mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'feature/fatfs_bdl_v6.0' into 'release/v6.0'
feat(fatfs): Add BDL support to FatFS component (v6.0) See merge request espressif/esp-idf!52557
This commit is contained in:
@@ -9,6 +9,17 @@ examples/storage/fatfs:
|
||||
- if: IDF_TARGET != "esp32"
|
||||
reason: only one target needed
|
||||
|
||||
examples/storage/fatfs/bdl_wl:
|
||||
depends_components:
|
||||
- *common_components
|
||||
- esp_blockdev
|
||||
- fatfs
|
||||
- vfs
|
||||
- wear_leveling
|
||||
disable_test:
|
||||
- if: IDF_TARGET != "esp32"
|
||||
reason: only one target needed
|
||||
|
||||
examples/storage/fatfs/ext_flash:
|
||||
depends_components:
|
||||
- *common_components
|
||||
|
||||
7
examples/storage/fatfs/bdl_wl/CMakeLists.txt
Normal file
7
examples/storage/fatfs/bdl_wl/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(fatfs_bdl_wl)
|
||||
55
examples/storage/fatfs/bdl_wl/README.md
Normal file
55
examples/storage/fatfs/bdl_wl/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# FatFS over BDL (Block Device Layer) - Wear-Levelling Stack
|
||||
|
||||
This example demonstrates mounting a FAT filesystem using the Block Device Layer (BDL) interface
|
||||
instead of the legacy `wl_handle_t`-based API.
|
||||
|
||||
## BDL Stack
|
||||
|
||||
The BDL stack constructed in this example:
|
||||
|
||||
```
|
||||
FatFS (VFS + POSIX API)
|
||||
|
|
||||
diskio_bdl (generic BDL diskio adapter)
|
||||
|
|
||||
WL BDL (wear-levelling, via wl_get_blockdev())
|
||||
|
|
||||
Partition BDL (flash partition, via esp_partition_get_blockdev())
|
||||
|
|
||||
SPI Flash (physical storage)
|
||||
```
|
||||
|
||||
The key advantage of BDL is that **the same `diskio_bdl` adapter works with any BDL device**.
|
||||
You can swap the bottom of the stack (e.g., use `sdmmc_get_blockdev()` for an SD card) without
|
||||
changing the FatFS integration code.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Build and flash
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type `Ctrl-]`.)
|
||||
|
||||
## Example output
|
||||
|
||||
```
|
||||
I (321) example: Creating partition BDL for 'storage' partition
|
||||
I (331) example: Partition BDL: disk_size=1048576, erase_size=4096
|
||||
I (331) example: Creating WL BDL on top of partition BDL
|
||||
I (341) example: WL BDL: disk_size=...., erase_size=4096
|
||||
I (341) example: Mounting FAT filesystem via BDL
|
||||
I (741) example: Filesystem mounted
|
||||
I (741) example: Opening file
|
||||
I (841) example: File written
|
||||
I (841) example: Reading file
|
||||
I (841) example: Read from file: 'Hello from FatFS over BDL!'
|
||||
I (841) example: Unmounting FAT filesystem
|
||||
I (941) example: Releasing BDL devices
|
||||
I (941) example: Done
|
||||
```
|
||||
3
examples/storage/fatfs/bdl_wl/main/CMakeLists.txt
Normal file
3
examples/storage/fatfs/bdl_wl/main/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "fatfs_bdl_wl_main.c"
|
||||
PRIV_REQUIRES vfs fatfs esp_blockdev esp_partition wear_levelling
|
||||
INCLUDE_DIRS ".")
|
||||
133
examples/storage/fatfs/bdl_wl/main/fatfs_bdl_wl_main.c
Normal file
133
examples/storage/fatfs/bdl_wl/main/fatfs_bdl_wl_main.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* FatFS over BDL (Block Device Layer) - Wear-Levelling stack example
|
||||
*
|
||||
* Demonstrates building a BDL stack and mounting FatFS on top of it:
|
||||
*
|
||||
* +-----------+
|
||||
* | FatFS | <- file system (VFS + FatFS)
|
||||
* +-----------+
|
||||
* | diskio_bdl| <- FatFS diskio driver for BDL devices
|
||||
* +-----------+
|
||||
* | WL BDL | <- wear-levelling BDL layer (wl_get_blockdev)
|
||||
* +-----------+
|
||||
* | Part BDL | <- partition BDL layer (esp_partition_get_blockdev)
|
||||
* +-----------+
|
||||
* | SPI Flash | <- physical storage
|
||||
* +-----------+
|
||||
*
|
||||
* The BDL approach decouples FatFS from any specific storage driver.
|
||||
* The same diskio_bdl adapter works with any BDL-compatible bottom device:
|
||||
* - partition BDL (flash partition)
|
||||
* - sdmmc BDL (SD/eMMC card)
|
||||
* - memory BDL (RAM disk for testing)
|
||||
* - or any custom BDL implementation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_vfs.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_blockdev.h"
|
||||
#include "wear_levelling.h"
|
||||
|
||||
static const char *TAG = "example";
|
||||
|
||||
const char *base_path = "/spiflash";
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Step 1: Build the BDL stack */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
ESP_LOGI(TAG, "Creating partition BDL for 'storage' partition");
|
||||
|
||||
esp_blockdev_handle_t part_bdl = NULL;
|
||||
ESP_ERROR_CHECK(esp_partition_get_blockdev(
|
||||
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT,
|
||||
"storage", &part_bdl));
|
||||
|
||||
ESP_LOGI(TAG, " Partition BDL: disk_size=%llu, erase_size=%u",
|
||||
(unsigned long long)part_bdl->geometry.disk_size,
|
||||
(unsigned)part_bdl->geometry.erase_size);
|
||||
|
||||
ESP_LOGI(TAG, "Creating WL BDL on top of partition BDL");
|
||||
|
||||
esp_blockdev_handle_t wl_bdl = NULL;
|
||||
ESP_ERROR_CHECK(wl_get_blockdev(part_bdl, &wl_bdl));
|
||||
|
||||
ESP_LOGI(TAG, " WL BDL: disk_size=%llu, erase_size=%u",
|
||||
(unsigned long long)wl_bdl->geometry.disk_size,
|
||||
(unsigned)wl_bdl->geometry.erase_size);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Step 2: Mount FatFS on the BDL device */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
ESP_LOGI(TAG, "Mounting FAT filesystem via BDL");
|
||||
|
||||
const esp_vfs_fat_mount_config_t mount_config = {
|
||||
.max_files = 4,
|
||||
.format_if_mount_failed = true,
|
||||
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE,
|
||||
.use_one_fat = false,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_vfs_fat_bdl_mount(base_path, wl_bdl, &mount_config));
|
||||
|
||||
ESP_LOGI(TAG, "Filesystem mounted");
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Step 3: Use POSIX file operations */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
const char *filename = "/spiflash/example.txt";
|
||||
|
||||
ESP_LOGI(TAG, "Opening file");
|
||||
FILE *f = fopen(filename, "wb");
|
||||
if (f == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to open file for writing");
|
||||
return;
|
||||
}
|
||||
fprintf(f, "Hello from FatFS over BDL!\n");
|
||||
fclose(f);
|
||||
ESP_LOGI(TAG, "File written");
|
||||
|
||||
ESP_LOGI(TAG, "Reading file");
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to open file for reading");
|
||||
return;
|
||||
}
|
||||
char line[128];
|
||||
fgets(line, sizeof(line), f);
|
||||
fclose(f);
|
||||
|
||||
char *pos = strchr(line, '\n');
|
||||
if (pos) {
|
||||
*pos = '\0';
|
||||
}
|
||||
ESP_LOGI(TAG, "Read from file: '%s'", line);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Step 4: Unmount and tear down the BDL stack */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
ESP_LOGI(TAG, "Unmounting FAT filesystem");
|
||||
ESP_ERROR_CHECK(esp_vfs_fat_bdl_unmount(base_path, wl_bdl));
|
||||
|
||||
ESP_LOGI(TAG, "Releasing BDL devices");
|
||||
wl_bdl->ops->release(wl_bdl);
|
||||
part_bdl->ops->release(part_bdl);
|
||||
|
||||
ESP_LOGI(TAG, "Done");
|
||||
}
|
||||
6
examples/storage/fatfs/bdl_wl/partitions_example.csv
Normal file
6
examples/storage/fatfs/bdl_wl/partitions_example.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1M,
|
||||
storage, data, fat, , 1M,
|
||||
|
18
examples/storage/fatfs/bdl_wl/pytest_fatfs_bdl_wl_example.py
Normal file
18
examples/storage/fatfs/bdl_wl/pytest_fatfs_bdl_wl_example.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_examples_fatfs_bdl_wl(dut: Dut) -> None:
|
||||
dut.expect('example: Mounting FAT filesystem via BDL', timeout=90)
|
||||
dut.expect('example: Filesystem mounted', timeout=90)
|
||||
dut.expect('example: Opening file', timeout=90)
|
||||
dut.expect('example: File written', timeout=90)
|
||||
dut.expect('example: Reading file', timeout=90)
|
||||
dut.expect("example: Read from file: 'Hello from FatFS over BDL!'", timeout=90)
|
||||
dut.expect('example: Unmounting FAT filesystem', timeout=90)
|
||||
dut.expect('example: Done', timeout=90)
|
||||
4
examples/storage/fatfs/bdl_wl/sdkconfig.defaults
Normal file
4
examples/storage/fatfs/bdl_wl/sdkconfig.defaults
Normal file
@@ -0,0 +1,4 @@
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
Reference in New Issue
Block a user