磨损均衡 API
概述
ESP32 所使用的 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 库在分区中存储文件,并使用 POSIX 和 C 库 API 从中写入和读取数据。
高级 API 参考
头文件
有关高级磨损均衡函数 esp_vfs_fat_spiflash_mount_rw_wl()
、 esp_vfs_fat_spiflash_unmount_rw_wl()
和结构体 esp_vfs_fat_mount_config_t
的详细内容,请参见 FAT 文件系统。
中层 API 参考
Header File
This header file can be included with:
#include "wear_levelling.h"
This header file is a part of the API provided by the
wear_levelling
component. To declare that your component depends onwear_levelling
, add the following to your CMakeLists.txt:REQUIRES wear_levelling
or
PRIV_REQUIRES wear_levelling
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 WL allocation is successful;
ESP_ERR_INVALID_ARG, if the arguments for WL configuration are not valid;
ESP_ERR_NO_MEM, if the WL allocation fails because of insufficient memory;
-
esp_err_t wl_unmount(wl_handle_t handle)
Unmount WL for defined partition.
- 参数
handle -- WL partition handle
- 返回
ESP_OK, if the operation is successful;
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 from 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 the result of function wl_sector_size(...)..
- 返回
ESP_OK, if the given 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 corresponding to the WL 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. The Pointer must be non-NULL and the 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 the actual flash size in use for the WL storage partition.
- 参数
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