磨损均衡 API
概述
ESP32-C3 所使用的 flash,特别是 SPI flash,多数具备扇区结构,且每个扇区仅允许有限次数的擦除/修改操作。为了避免过度使用某一扇区,乐鑫提供了磨损均衡组件,无需用户介入即可帮助用户均衡各个扇区之间的磨损。
磨损均衡组件包含了通过分区组件对外部 SPI flash 进行数据读取、写入、擦除和存储器映射相关的 API 函数。磨损均衡组件还具有软件上更高级别的 API 函数,与 FAT 文件系统 协同工作。
磨损均衡组件与 FAT 文件系统组件共用 FAT 文件系统的扇区,扇区大小为 4096 字节,是标准 flash 扇区的大小。在这种模式下,磨损均衡组件性能达到最佳,但需要在 RAM 中占用更多内存。
为了节省内存,磨损均衡组件还提供了另外两种模式,均使用 512 字节大小的扇区:
- 性能模式:先将数据保存在 RAM 中,擦除扇区,然后将数据存储回 flash。如果设备在扇区擦写过程中突然断电,则整个扇区(4096 字节)数据将全部丢失。 
- 安全模式:数据先保存在 flash 中空余扇区,擦除扇区后,数据即存储回去。如果设备断电,上电后可立即恢复数据。 
设备默认设置如下:
- 定义扇区大小为 512 字节 
- 默认使用性能模式 
您可以使用配置菜单更改设置。
磨损均衡组件不会将数据缓存在 RAM 中。写入和擦除函数直接修改 flash,函数返回后,flash 即完成修改。
磨损均衡访问 API
处理 flash 数据常用的 API 如下所示:
- wl_mount- 为指定分区挂载并初始化磨损均衡模块
- wl_unmount- 卸载分区并释放磨损均衡模块
- wl_erase_range- 擦除 flash 中指定的地址范围
- wl_write- 将数据写入分区
- wl_read- 从分区读取数据
- wl_size- 返回可用内存的大小(以字节为单位)
- wl_sector_size- 返回一个扇区的大小
请尽量避免直接使用原始磨损均衡函数,建议您使用文件系统特定的函数。
内存大小
内存大小是根据分区参数在磨损均衡模块中计算所得,由于模块使用 flash 部分扇区存储内部数据,因此计算所得内存大小有少许偏差。
另请参阅
应用示例
storage/wear_levelling 中提供了一款磨损均衡驱动与 FatFs 库结合使用的示例。该示例初始化磨损均衡驱动,挂载 FAT 文件系统分区,并使用 POSIX(可移植操作系统接口)和 C 库 API 从中写入和读取数据。如需了解更多信息,请参考 storage/wear_levelling/README.md。
高级 API 参考
头文件
函数
- 
esp_err_t esp_vfs_fat_spiflash_mount_rw_wl(const char *base_path, const char *partition_label, const esp_vfs_fat_mount_config_t *mount_config, wl_handle_t *wl_handle)
- Convenience function to initialize FAT filesystem in SPI flash 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. 
- initializes flash wear levelling library on top of the given partition 
- mounts FAT partition using FATFS library on top of flash wear levelling library 
- registers FATFS library with VFS, with prefix given by base_prefix variable 
 - This function is intended to make example code more compact. - 参数
- 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 
- wl_handle – [out] wear levelling driver handle 
 
- 返回
- 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_spiflash_mount_rw_wl 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 wear levelling library, SPI flash driver, or FATFS drivers 
 
 
- 
struct esp_vfs_fat_mount_config_t
- Configuration arguments for esp_vfs_fat_sdmmc_mount and esp_vfs_fat_spiflash_mount_rw_wl 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. 
 - 
bool disk_status_check_enable
- Enables real ff_disk_status function implementation for SD cards (ff_sdmmc_status). Possibly slows down IO performance. - Try to enable if you need to handle situations when SD cards are not unmounted properly before physical removal or you are experiencing issues with SD cards. - Doesn’t do anything for other memory storage media. 
 
- 
bool format_if_mount_failed
- 
esp_err_t esp_vfs_fat_spiflash_unmount_rw_wl(const char *base_path, wl_handle_t wl_handle)
- Unmount FAT filesystem and release resources acquired using esp_vfs_fat_spiflash_mount_rw_wl. - 参数
- base_path – path where partition should be registered (e.g. “/spiflash”) 
- wl_handle – wear levelling driver handle returned by esp_vfs_fat_spiflash_mount_rw_wl 
 
- 返回
- ESP_OK on success 
- ESP_ERR_INVALID_STATE if esp_vfs_fat_spiflash_mount_rw_wl hasn’t been called 
 
 
中层 API 参考
Header File
Functions
- 
esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle)
- Mount WL for defined partition. - 参数
- partition – that will be used for access 
- out_handle – handle of the WL instance 
 
- 返回
- ESP_OK, if the allocation was successfully; 
- ESP_ERR_INVALID_ARG, if WL allocation was unsuccessful; 
- ESP_ERR_NO_MEM, if there was no memory to allocate WL components; 
 
 
- 
esp_err_t wl_unmount(wl_handle_t handle)
- Unmount WL for defined partition. - 参数
- handle – WL partition handle 
- 返回
- ESP_OK, if the operation completed successfully; 
- or one of error codes from lower-level flash driver. 
 
 
- 
esp_err_t wl_erase_range(wl_handle_t handle, size_t start_addr, size_t size)
- Erase part of the WL storage. - 参数
- handle – WL handle that are related to the partition 
- start_addr – Address where erase operation should start. Must be aligned to the result of function wl_sector_size(…). 
- size – Size of the range which should be erased, in bytes. Must be divisible by result of function wl_sector_size(…).. 
 
- 返回
- ESP_OK, if the range was erased successfully; 
- ESP_ERR_INVALID_ARG, if iterator or dst are NULL; 
- ESP_ERR_INVALID_SIZE, if erase would go out of bounds of the partition; 
- or one of error codes from lower-level flash driver. 
 
 
- 
esp_err_t wl_write(wl_handle_t handle, size_t dest_addr, const void *src, size_t size)
- Write data to the WL storage. - Before writing data to flash, corresponding region of flash needs to be erased. This can be done using wl_erase_range function. - 备注 - Prior to writing to WL storage, make sure it has been erased with wl_erase_range call. - 参数
- handle – WL handle that are related to the partition 
- dest_addr – Address where the data should be written, relative to the beginning of the partition. 
- src – Pointer to the source buffer. Pointer must be non-NULL and buffer must be at least ‘size’ bytes long. 
- size – Size of data to be written, in bytes. 
 
- 返回
- ESP_OK, if data was written successfully; 
- ESP_ERR_INVALID_ARG, if dst_offset exceeds partition size; 
- ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition; 
- or one of error codes from lower-level flash driver. 
 
 
- 
esp_err_t wl_read(wl_handle_t handle, size_t src_addr, void *dest, size_t size)
- Read data from the WL storage. - 参数
- handle – WL module instance that was initialized before 
- dest – Pointer to the buffer where data should be stored. Pointer must be non-NULL and buffer must be at least ‘size’ bytes long. 
- src_addr – Address of the data to be read, relative to the beginning of the partition. 
- size – Size of data to be read, in bytes. 
 
- 返回
- ESP_OK, if data was read successfully; 
- ESP_ERR_INVALID_ARG, if src_offset exceeds partition size; 
- ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition; 
- or one of error codes from lower-level flash driver. 
 
 
- 
size_t wl_size(wl_handle_t handle)
- Get size of the WL storage. - 参数
- handle – WL module handle that was initialized before 
- 返回
- usable size, in bytes 
 
- 
size_t wl_sector_size(wl_handle_t handle)
- Get sector size of the WL instance. - 参数
- handle – WL module handle that was initialized before 
- 返回
- sector size, in bytes 
 
Macros
- 
WL_INVALID_HANDLE
Type Definitions
- 
typedef int32_t wl_handle_t
- wear levelling handle