Wear Levelling APIs¶
Overview¶
Most of the flash devices and specially SPI flash devices that are used in ESP32 have sector based organization and have limited amount of erase/modification cycles per memory sector. To avoid situation when one sector reach the limit of erases when other sectors was used not often, we have made a component that avoid this situation. The wear levelling component share the amount of erases between all sectors in the memory without user interaction. The wear_levelling component contains APIs related to reading, writing, erasing, memory mapping data in the external SPI flash through the partition component. It also has higher-level APIs which work with FAT filesystem defined in the FAT filesystem.
The wear levelling component, together with FAT FS component, works with FAT FS sector size 4096 bytes which is standard size of the flash devices. In this mode the component has best performance, but needs additional memoty in the RAM. To save internal memory the component has two additional modes to work with sector size 512 bytes: Performance and Safety modes. In Performance mode by erase sector operation data will be stored to the RAM, sector will be erased and then data will be stored back to the flash. If by this operation power off situation will occur, the complete 4096 bytes will be lost. To prevent this the Safety mode was implemented. In safety mode the data will be first stored to the flash and after sector will be erased, will be stored back. If power off situation will occur, after power on, the data will be recovered. By default defined the sector size 512 bytes and Performance mode. To change these values please use the configuration menu.
The wear levelling component does not cache data in RAM. Write and erase functions modify flash directly, and flash contents is consistent when the function returns.
Wear Levelling access APIs¶
This is the set of APIs for working with data in flash:
wl_mount
mount wear levelling module for defined partitionwl_unmount
used to unmount levelling modulewl_erase_range
used to erase range of addresses in flashwl_write
used to write data to the partitionwl_read
used to read data from the partitionwl_size
return size of avalible memory in byteswl_sector_size
returns size of one sector
Generally, try to avoid using the raw wear levelling functions in favor of filesystem-specific functions.
Memory Size¶
The memory size calculated in the wear Levelling module based on parameters of partition. The module use few sectors of flash for internal data.
Application Example¶
An example which combines wear levelling driver with FATFS library is provided in examples/storage/wear_levelling
directory. This example initializes the wear levelling driver, mounts FATFS partition, and writes and reads data from it using POSIX and C library APIs. See README.md file in the example directory for more information.
High level API Reference¶
Header Files¶
Functions¶
-
esp_err_t
esp_vfs_fat_spiflash_mount
(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.
- Return
- 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 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
- Parameters
base_path
: path where FATFS partition should be mounted (e.g. “/spiflash”)partition_label
: label of the partition which should be usedmount_config
: pointer to structure with extra parameters for mounting FATFSwl_handle
: wear levelling driver handle
-
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.
-
bool
-
esp_err_t
esp_vfs_fat_spiflash_unmount
(const char *base_path, wl_handle_t wl_handle)¶ Unmount FAT filesystem and release resources acquired using esp_vfs_fat_spiflash_mount.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_STATE if esp_vfs_fat_spiflash_mount hasn’t been called
- Parameters
base_path
: path where partition should be registered (e.g. “/spiflash”)wl_handle
: wear levelling driver handle returned by esp_vfs_fat_spiflash_mount
Mid level API Reference¶
Header File¶
Functions¶
-
esp_err_t
wl_mount
(const esp_partition_t *partition, wl_handle_t *out_handle)¶ Mount WL for defined partition.
- Return
- 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;
- Parameters
partition
: that will be used for accessout_handle
: handle of the WL instance
-
esp_err_t
wl_unmount
(wl_handle_t handle)¶ Unmount WL for defined partition.
- Return
- ESP_OK, if the operation completed successfully;
- or one of error codes from lower-level flash driver.
- Parameters
handle
: WL partition handle
-
esp_err_t
wl_erase_range
(wl_handle_t handle, size_t start_addr, size_t size)¶ Erase part of the WL storage.
- Return
- 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.
- Parameters
handle
: WL handle that are related to the partitionstart_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_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.
- Note
- Prior to writing to WL storage, make sure it has been erased with wl_erase_range call.
- Return
- 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.
- Parameters
handle
: WL handle that are related to the partitiondest_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_err_t
wl_read
(wl_handle_t handle, size_t src_addr, void *dest, size_t size)¶ Read data from the WL storage.
- Return
- 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.
- Parameters
handle
: WL module instance that was initialized beforedest
: 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.
-
size_t
wl_size
(wl_handle_t handle)¶ Get size of the WL storage.
- Return
- usable size, in bytes
- Parameters
handle
: WL module handle that was initialized before
-
size_t
wl_sector_size
(wl_handle_t handle)¶ Get sector size of the WL instance.
- Return
- sector size, in bytes
- Parameters
handle
: WL module handle that was initialized before