FAT 文件系统

[English]

ESP-IDF 使用 FatFs 库来实现 FAT 文件系统。FatFs 库位于 fatfs 组件中,您可以直接使用,也可以借助 C 标准库和 POSIX API 通过 VFS(虚拟文件系统)使用 FatFs 库的大多数功能。

此外,我们对 FatFs 库进行了扩展,新增了支持可插拔磁盘 I/O 调度层,从而允许在运行时将 FatFs 驱动映射到物理磁盘。

FatFs 与 VFS 配合使用

头文件 fatfs/vfs/esp_vfs_fat.h 定义了连接 FatFs 和 VFS 的函数。

函数 esp_vfs_fat_register() 分配一个 FATFS 结构,并在 VFS 中注册特定路径前缀。如果文件路径以此前缀开头,则对此文件的后续操作将转至 FatFs API。 函数 esp_vfs_fat_unregister_path() 删除在 VFS 中的注册,并释放 FATFS 结构。

多数应用程序在使用 esp_vfs_fat_ 函数时,采用如下步骤:

  1. 调用 esp_vfs_fat_register(),指定:
    • 挂载文件系统的路径前缀(例如,"/sdcard""/spiflash"

    • FatFs 驱动编号

    • 一个用于接收指向 FATFS 结构指针的变量

  2. 调用 ff_diskio_register() 为步骤 1 中的驱动编号注册磁盘 I/O 驱动;

  3. 调用 FatFs 函数 f_mount,随后调用 f_fdiskf_mkfs,并使用与传递到 esp_vfs_fat_register() 相同的驱动编号挂载文件系统。请参考 FatFs 文档,查看更多信息;

  4. 调用 C 标准库和 POSIX API 对路径中带有步骤 1 中所述前缀的文件(例如,"/sdcard/hello.txt")执行打开、读取、写入、擦除、复制等操作。文件系统默认使用 8.3 文件名 格式 (SFN)。若您需要使用长文件名 (LFN),启用 CONFIG_FATFS_LONG_FILENAMES 选项。请参考 here,查看更多信息;

  5. 您可以选择启用 CONFIG_FATFS_USE_FASTSEEK 选项,使用 POSIX lseek 来快速执行。快速查找不适用于编辑模式下的文件,所以,使用快速查找时,应在只读模式下打开(或者关闭然后重新打开)文件;

  6. 您也可以选择直接调用 FatFs 库函数,但需要使用没有 VFS 前缀的路径(例如,"/hello.txt");

  7. 关闭所有打开的文件;

  8. 调用 FatFs 函数 f_mount 并使用 NULL FATFS* 参数,为与上述编号相同的驱动卸载文件系统;

  9. 调用 FatFs 函数 ff_diskio_register() 并使用 NULL ff_diskio_impl_t* 参数和相同的驱动编号,来释放注册的磁盘 I/O 驱动。

  10. 调用 esp_vfs_fat_unregister_path() 并使用文件系统挂载的路径将 FatFs 从 VFS 中移除,并释放步骤 1 中分配的 FATFS 结构。

便捷函数 esp_vfs_fat_sdmmc_mountesp_vfs_fat_sdspi_mount, 和 esp_vfs_fat_sdmmc_unmount 对上述步骤进行了封装,并加入了对 SD 卡初始化的处理。我们将在下一章节详细介绍这两个函数。

esp_err_t esp_vfs_fat_register(const char *base_path, const char *fat_drive, size_t max_files, FATFS **out_fs)

Register FATFS with VFS component.

This function registers given FAT drive in VFS, at the specified base path. If only one drive is used, fat_drive argument can be an empty string. Refer to FATFS library documentation on how to specify FAT drive. This function also allocates FATFS structure which should be used for f_mount call.

备注

This function doesn’t mount the drive into FATFS, it just connects POSIX and C standard library IO function with FATFS. You need to mount desired drive into FATFS separately.

参数
  • base_path – path prefix where FATFS should be registered

  • fat_drive – FATFS drive specification; if only one drive is used, can be an empty string

  • max_files – maximum number of files which can be open at the same time

  • out_fs[out] pointer to FATFS structure which can be used for FATFS f_mount call is returned via this argument.

返回

  • ESP_OK on success

  • ESP_ERR_INVALID_STATE if esp_vfs_fat_register was already called

  • ESP_ERR_NO_MEM if not enough memory or too many VFSes already registered

esp_err_t esp_vfs_fat_unregister_path(const char *base_path)

Un-register FATFS from VFS.

备注

FATFS structure returned by esp_vfs_fat_register is destroyed after this call. Make sure to call f_mount function to unmount it before calling esp_vfs_fat_unregister_ctx. Difference between this function and the one above is that this one will release the correct drive, while the one above will release the last registered one

参数

base_path – path prefix where FATFS is registered. This is the same used when esp_vfs_fat_register was called

返回

  • ESP_OK on success

  • ESP_ERR_INVALID_STATE if FATFS is not registered in VFS

FatFs 与 VFS 和 SD 卡配合使用

头文件 fatfs/vfs/esp_vfs_fat.h 定义了两个便捷函数 esp_vfs_fat_sdmmc_mount()esp_vfs_fat_sdmmc_unmount()。这两个函数分别执行上一章节的步骤 1-3 和步骤 7-9,并初始化 SD 卡,但仅提供有限的错误处理功能。我们鼓励开发人员查看源代码并将更多高级功能集成到产品应用中。

便捷函数 esp_vfs_fat_sdmmc_unmount() 用于卸载文件系统并释放从 esp_vfs_fat_sdmmc_mount() 函数获取的资源。

esp_err_t esp_vfs_fat_sdmmc_mount(const char *base_path, const sdmmc_host_t *host_config, const void *slot_config, const esp_vfs_fat_mount_config_t *mount_config, sdmmc_card_t **out_card)

Convenience function to get FAT filesystem on SD card registered in VFS.

This is an all-in-one function which does the following:

  • initializes SDMMC driver or SPI driver with configuration in host_config

  • initializes SD card with configuration in slot_config

  • mounts FAT partition on SD card using FATFS library, with configuration in mount_config

  • registers FATFS library with VFS, with prefix given by base_prefix variable

This function is intended to make example code more compact. For real world applications, developers should implement the logic of probing SD card, locating and mounting partition, and registering FATFS in VFS, with proper error checking and handling of exceptional conditions.

备注

Use this API to mount a card through SDSPI is deprecated. Please call esp_vfs_fat_sdspi_mount() instead for that case.

参数
  • base_path – path where partition should be registered (e.g. “/sdcard”)

  • host_config – Pointer to structure describing SDMMC host. When using SDMMC peripheral, this structure can be initialized using SDMMC_HOST_DEFAULT() macro. When using SPI peripheral, this structure can be initialized using SDSPI_HOST_DEFAULT() macro.

  • slot_config – Pointer to structure with slot configuration. For SDMMC peripheral, pass a pointer to sdmmc_slot_config_t structure initialized using SDMMC_SLOT_CONFIG_DEFAULT. (Deprecated) For SPI peripheral, pass a pointer to sdspi_slot_config_t structure initialized using SDSPI_SLOT_CONFIG_DEFAULT().

  • mount_config – pointer to structure with extra parameters for mounting FATFS

  • out_card[out] if not NULL, pointer to the card information structure will be returned via this argument

返回

  • ESP_OK on success

  • ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called

  • ESP_ERR_NO_MEM if memory can not be allocated

  • ESP_FAIL if partition can not be mounted

  • other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers

esp_err_t esp_vfs_fat_sdspi_mount(const char *base_path, const sdmmc_host_t *host_config_input, const sdspi_device_config_t *slot_config, const esp_vfs_fat_mount_config_t *mount_config, sdmmc_card_t **out_card)

Convenience function to get FAT filesystem on SD card registered in VFS.

This is an all-in-one function which does the following:

  • initializes an SPI Master device based on the SPI Master driver with configuration in slot_config, and attach it to an initialized SPI bus.

  • initializes SD card with configuration in host_config_input

  • mounts FAT partition on SD card using FATFS library, with configuration in mount_config

  • registers FATFS library with VFS, with prefix given by base_prefix variable

This function is intended to make example code more compact. For real world applications, developers should implement the logic of probing SD card, locating and mounting partition, and registering FATFS in VFS, with proper error checking and handling of exceptional conditions.

备注

This function try to attach the new SD SPI device to the bus specified in host_config. Make sure the SPI bus specified in host_config->slot have been initialized by spi_bus_initialize() before.

参数
  • base_path – path where partition should be registered (e.g. “/sdcard”)

  • host_config_input – Pointer to structure describing SDMMC host. This structure can be initialized using SDSPI_HOST_DEFAULT() macro.

  • slot_config – Pointer to structure with slot configuration. For SPI peripheral, pass a pointer to sdspi_device_config_t structure initialized using SDSPI_DEVICE_CONFIG_DEFAULT().

  • mount_config – pointer to structure with extra parameters for mounting FATFS

  • out_card[out] If not NULL, pointer to the card information structure will be returned via this argument. It is suggested to hold this handle and use it to unmount the card later if needed. Otherwise it’s not suggested to use more than one card at the same time and unmount one of them in your application.

返回

  • ESP_OK on success

  • ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called

  • ESP_ERR_NO_MEM if memory can not be allocated

  • ESP_FAIL if partition can not be mounted

  • other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers

struct esp_vfs_fat_mount_config_t

Configuration arguments for esp_vfs_fat_sdmmc_mount and esp_vfs_fat_spiflash_mount functions.

Public Members

bool format_if_mount_failed

If FAT partition can not be mounted, and this parameter is true, create partition table and format the filesystem.

int max_files

Max number of open files.

size_t allocation_unit_size

If format_if_mount_failed is set, and mount fails, format the card with given allocation unit size. Must be a power of 2, between sector size and 128 * sector size. For SD cards, sector size is always 512 bytes. For wear_levelling, sector size is determined by CONFIG_WL_SECTOR_SIZE option.

Using larger allocation unit size will result in higher read/write performance and higher overhead when storing small files.

Setting this field to 0 will result in allocation unit set to the sector size.

esp_err_t esp_vfs_fat_sdcard_unmount(const char *base_path, sdmmc_card_t *card)

Unmount an SD card from the FAT filesystem and release resources acquired using esp_vfs_fat_sdmmc_mount() or esp_vfs_fat_sdspi_mount()

返回

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG if the card argument is unregistered

  • ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount hasn’t been called

FatFs 与 VFS 配合使用(只读模式下)

头文件 fatfs/vfs/esp_vfs_fat.h 也定义了两个便捷函数 esp_vfs_fat_rawflash_mount()esp_vfs_fat_rawflash_unmount()。上述两个函数分别对 FAT 只读分区执行步骤 1-3 和步骤 7-9。有些数据分区仅在工厂配置时写入一次,之后在整个硬件生命周期内都不会再有任何改动。利用上述两个函数处理这种数据分区非常方便。

esp_err_t esp_vfs_fat_rawflash_mount(const char *base_path, const char *partition_label, const esp_vfs_fat_mount_config_t *mount_config)

Convenience function to initialize read-only FAT filesystem and register it in VFS.

This is an all-in-one function which does the following:

  • finds the partition with defined partition_label. Partition label should be configured in the partition table.

  • mounts FAT partition using FATFS library

  • registers FATFS library with VFS, with prefix given by base_prefix variable

备注

Wear levelling is not used when FAT is mounted in read-only mode using this function.

参数
  • base_path – path where FATFS partition should be mounted (e.g. “/spiflash”)

  • partition_label – label of the partition which should be used

  • mount_config – pointer to structure with extra parameters for mounting FATFS

返回

  • ESP_OK on success

  • ESP_ERR_NOT_FOUND if the partition table does not contain FATFS partition with given label

  • ESP_ERR_INVALID_STATE if esp_vfs_fat_rawflash_mount was already called for the same partition

  • ESP_ERR_NO_MEM if memory can not be allocated

  • ESP_FAIL if partition can not be mounted

  • other error codes from SPI flash driver, or FATFS drivers

esp_err_t esp_vfs_fat_rawflash_unmount(const char *base_path, const char *partition_label)

Unmount FAT filesystem and release resources acquired using esp_vfs_fat_rawflash_mount.

参数
  • base_path – path where partition should be registered (e.g. “/spiflash”)

  • partition_label – label of partition to be unmounted

返回

  • ESP_OK on success

  • ESP_ERR_INVALID_STATE if esp_vfs_fat_spiflash_mount hasn’t been called

FatFs 磁盘 I/O 层

我们对 FatFs API 函数进行了扩展,实现了运行期间注册磁盘 I/O 驱动。

上述 API 为 SD/MMC 卡提供了磁盘 I/O 函数实现方式,可使用 ff_diskio_register_sdmmc() 函数注册指定的 FatFs 驱动编号。

void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t *discio_impl)

Register or unregister diskio driver for given drive number.

When FATFS library calls one of disk_xxx functions for driver number pdrv, corresponding function in discio_impl for given pdrv will be called.

参数
  • pdrv – drive number

  • discio_impl – pointer to ff_diskio_impl_t structure with diskio functions or NULL to unregister and free previously registered drive

struct ff_diskio_impl_t

Structure of pointers to disk IO driver functions.

See FatFs documentation for details about these functions

Public Members

DSTATUS (*init)(unsigned char pdrv)

disk initialization function

DSTATUS (*status)(unsigned char pdrv)

disk status check function

DRESULT (*read)(unsigned char pdrv, unsigned char *buff, uint32_t sector, unsigned count)

sector read function

DRESULT (*write)(unsigned char pdrv, const unsigned char *buff, uint32_t sector, unsigned count)

sector write function

DRESULT (*ioctl)(unsigned char pdrv, unsigned char cmd, void *buff)

function to get info about disk and do some misc operations

void ff_diskio_register_sdmmc(unsigned char pdrv, sdmmc_card_t *card)

Register SD/MMC diskio driver

参数
  • pdrv – drive number

  • card – pointer to sdmmc_card_t structure describing a card; card should be initialized before calling f_mount.

esp_err_t ff_diskio_register_wl_partition(unsigned char pdrv, wl_handle_t flash_handle)

Register spi flash partition

参数
  • pdrv – drive number

  • flash_handle – handle of the wear levelling partition.

esp_err_t ff_diskio_register_raw_partition(unsigned char pdrv, const esp_partition_t *part_handle)

Register spi flash partition

参数
  • pdrv – drive number

  • part_handle – pointer to raw flash partition.