【esp32-s3】6.2 文件系统——文件夹列表

1 前言

本章测试如何列出tf卡种的文件名称。

2 使用接口

opendir
readdir

需要注意的是函数调用
代码路径:components\vfs\vfs.c

DIR* opendir(const char* name)
    __attribute__((alias("esp_vfs_opendir")));
int readdir_r(DIR* pdir, struct dirent* entry, struct dirent** out_dirent)
    __attribute__((alias("esp_vfs_readdir_r")));
struct dirent* readdir(DIR* pdir)
    __attribute__((alias("esp_vfs_readdir")));

这里定义了接口函数readdir等,实际调用的是esp_vfs_readdir。

DIR* esp_vfs_opendir(const char* name)
{
    
    
    const vfs_entry_t* vfs = get_vfs_for_path(name);
    struct _reent* r = __getreent();
    if (vfs == NULL) {
    
    
        __errno_r(r) = ENOENT;
        return NULL;
    }
    const char* path_within_vfs = translate_path(vfs, name);
    DIR* ret;
    CHECK_AND_CALLP(ret, r, vfs, opendir, path_within_vfs);
    if (ret != NULL) {
    
    
        ret->dd_vfs_idx = vfs->offset;
    }
    return ret;
}

struct dirent* esp_vfs_readdir(DIR* pdir)
{
    
    
    const vfs_entry_t* vfs = get_vfs_for_index(pdir->dd_vfs_idx);
    struct _reent* r = __getreent();
    if (vfs == NULL) {
    
    
       __errno_r(r) = EBADF;
        return NULL;
    }
    struct dirent* ret;
    CHECK_AND_CALLP(ret, r, vfs, readdir, pdir);
    return ret;
}

可以看到,入参的是DIR,这个需要用opendir获取,输入文件名(路径)。

3 代码

/* SD card and FAT filesystem example.
   This example uses SPI peripheral to communicate with SD card.

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"

#include <dirent.h>
#include "esp_vfs.h"

static const char *TAG = "example";

#define MOUNT_POINT "/sdcard"


// Pin assignments can be set in menuconfig, see "SD SPI Example Configuration" menu.
// You can also change the pin assignments here by changing the following 4 lines.
#define PIN_NUM_MISO  37
#define PIN_NUM_MOSI  35
#define PIN_NUM_CLK   36
#define PIN_NUM_CS    34


#define DIR_NUM_MAX 10    

void func2_list()
{
    
    
    const char* dir_name = MOUNT_POINT;//"/t1";
    ESP_LOGI(TAG, "Opening dir %s", dir_name);

    DIR *dir_t1 = opendir(dir_name);

    int count = 0;
    const char* names[DIR_NUM_MAX];

    printf("DIR: %s\n",dir_name);
    while(1) {
    
    
        struct dirent* de = readdir(dir_t1);
        if (!de) {
    
    
            break;
        }

        printf("\t%s\n", de->d_name);
        names[count] = de->d_name;
        ++count;
    }
    closedir(dir_name);	
}

void func1_test(sdmmc_card_t *card)
{
    
    
    // Use POSIX and C standard library functions to work with files.

    // First create a file.
    const char *file_hello = MOUNT_POINT"/hello.txt";

    ESP_LOGI(TAG, "Opening file %s", file_hello);
    FILE *f = fopen(file_hello, "w");
    if (f == NULL) {
    
    
        ESP_LOGE(TAG, "Failed to open file for writing");
        return;
    }
    fprintf(f, "Hello %s!\n", card->cid.name);
    fclose(f);
    ESP_LOGI(TAG, "File written");

    const char *file_foo = MOUNT_POINT"/foo.txt";

    // Check if destination file exists before renaming
    struct stat st;
    if (stat(file_foo, &st) == 0) {
    
    
        // Delete it if it exists
        unlink(file_foo);
    }

    // Rename original file
    ESP_LOGI(TAG, "Renaming file %s to %s", file_hello, file_foo);
    if (rename(file_hello, file_foo) != 0) {
    
    
        ESP_LOGE(TAG, "Rename failed");
        return;
    }

    // Open renamed file for reading
    ESP_LOGI(TAG, "Reading file %s", file_foo);
    f = fopen(file_foo, "r");
    if (f == NULL) {
    
    
        ESP_LOGE(TAG, "Failed to open file for reading");
        return;
    }

    // Read a line from file
    char line[64];
    fgets(line, sizeof(line), f);
    fclose(f);

    // Strip newline
    char *pos = strchr(line, '\n');
    if (pos) {
    
    
        *pos = '\0';
    }
    ESP_LOGI(TAG, "Read from file: '%s'", line);
}


void app_main(void)
{
    
    
    //------------------ init_spi_sdcard ------------------
    // init_spi_sdcard();
    esp_err_t ret;

    // Options for mounting the filesystem.
    // If format_if_mount_failed is set to true, SD card will be partitioned and
    // formatted in case when mounting fails.
    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
    
    
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
        .format_if_mount_failed = true,
#else
        .format_if_mount_failed = false,
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
        .max_files = 5,
        .allocation_unit_size = 16 * 1024
    };
    sdmmc_card_t *card;
    const char mount_point[] = MOUNT_POINT;
    ESP_LOGI(TAG, "Initializing SD card");

    // Use settings defined above to initialize SD card and mount FAT filesystem.
    // Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
    // Please check its source code and implement error recovery when developing
    // production applications.
    ESP_LOGI(TAG, "Using SPI peripheral");

    sdmmc_host_t host = SDSPI_HOST_DEFAULT();
    host.max_freq_khz = 1000;
    printf("host.max_freq_khz = %d\n",host.max_freq_khz);
    spi_bus_config_t bus_cfg = {
    
    
        .mosi_io_num = PIN_NUM_MOSI,
        .miso_io_num = PIN_NUM_MISO,
        .sclk_io_num = PIN_NUM_CLK,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 4000,
    };
    ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
    if (ret != ESP_OK) {
    
    
        ESP_LOGE(TAG, "Failed to initialize bus.");
        return;
    }

    // This initializes the slot without card detect (CD) and write protect (WP) signals.
    // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
    sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
    slot_config.gpio_cs = PIN_NUM_CS;
    slot_config.host_id = host.slot;

    ESP_LOGI(TAG, "Mounting filesystem");
    ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
    printf("youkai : %d\n",ret);

    if (ret != ESP_OK) {
    
    
        if (ret == ESP_FAIL) {
    
    
            ESP_LOGE(TAG, "Failed to mount filesystem. "
                     "If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
        } else {
    
    
            ESP_LOGE(TAG, "Failed to initialize the card (%s). "
                     "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
        }
        return;
    }
    ESP_LOGI(TAG, "Filesystem mounted");

    // Card has been initialized, print its properties
    sdmmc_card_print_info(stdout, card);

    //------------------ init_spi_sdcard ------------------

    printf("------------- test file -------------\n");
    func1_test(card);
    printf("------------- test file -------------\n");

    printf("------------- test list -------------\n");
    func2_list();
    printf("------------- test list -------------\n");

    //------------------ deinit_spi_sdcard ------------------
    // All done, unmount partition and disable SPI peripheral
    esp_vfs_fat_sdcard_unmount(mount_point, card);
    ESP_LOGI(TAG, "Card unmounted");

    //deinitialize the bus after all devices are removed
    spi_bus_free(host.slot);
    //------------------ deinit_spi_sdcard ------------------
}

结果

在这里插入图片描述
如图,已经将文件名称列出来了。

猜你喜欢

转载自blog.csdn.net/qq_38091632/article/details/124521389