mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
feat(storage/fatfs): add minimal FatFS example
This commit is contained in:
parent
84ba1a323c
commit
b9a54fb1f3
@ -34,6 +34,14 @@ examples/storage/ext_flash_fatfs:
|
|||||||
temporary: true
|
temporary: true
|
||||||
reason: lack of runners
|
reason: lack of runners
|
||||||
|
|
||||||
|
examples/storage/fatfs_basic:
|
||||||
|
depends_components:
|
||||||
|
- fatfs
|
||||||
|
- vfs
|
||||||
|
disable_test:
|
||||||
|
- if: IDF_TARGET != "esp32"
|
||||||
|
reason: only one target needed
|
||||||
|
|
||||||
examples/storage/nvs_rw_blob:
|
examples/storage/nvs_rw_blob:
|
||||||
depends_components:
|
depends_components:
|
||||||
- nvs_flash
|
- nvs_flash
|
||||||
|
@ -7,6 +7,7 @@ This directory contains a range of examples ESP-IDF projects. These are intended
|
|||||||
|
|
||||||
The examples are grouped into sub-directories by category. Each category directory contains one or more example projects:
|
The examples are grouped into sub-directories by category. Each category directory contains one or more example projects:
|
||||||
|
|
||||||
|
* `fatfs_basic` minimal example of FatFS usage on SPI FLASH
|
||||||
* `custom_flash_driver` example demonstrates how to implement your own flash chip driver by overriding the default driver.
|
* `custom_flash_driver` example demonstrates how to implement your own flash chip driver by overriding the default driver.
|
||||||
* `emmc` example demonstrates how to use an eMMC chip with an ESP device.
|
* `emmc` example demonstrates how to use an eMMC chip with an ESP device.
|
||||||
* `ext_flash_fatfs` example demonstrates how to use FATFS partition with external SPI FLASH chip.
|
* `ext_flash_fatfs` example demonstrates how to use FATFS partition with external SPI FLASH chip.
|
||||||
|
6
examples/storage/fatfs_basic/CMakeLists.txt
Normal file
6
examples/storage/fatfs_basic/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# 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.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(fatfsgen)
|
43
examples/storage/fatfs_basic/README.md
Normal file
43
examples/storage/fatfs_basic/README.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||||
|
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
|
# FATFS minimal example
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
This example demonstrates the minimal setup required to store persistent data on SPI Flash using the FAT filesystem.
|
||||||
|
Beware that the minimal required size of the flash is 4 MB.
|
||||||
|
|
||||||
|
## How to use example
|
||||||
|
|
||||||
|
### Build and flash
|
||||||
|
|
||||||
|
To run the example, type the following command:
|
||||||
|
|
||||||
|
```CMake
|
||||||
|
# CMake
|
||||||
|
idf.py -p PORT flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||||
|
|
||||||
|
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||||
|
|
||||||
|
## Example output
|
||||||
|
|
||||||
|
Here is the example's console output:
|
||||||
|
|
||||||
|
```
|
||||||
|
...
|
||||||
|
I (339) example: Mounting FAT filesystem
|
||||||
|
I (339) example: Filesystem mounted
|
||||||
|
I (339) example: Opening file
|
||||||
|
I (729) example: File written
|
||||||
|
I (729) example: Reading file
|
||||||
|
I (739) example: Read from file: 'This is written by the device'
|
||||||
|
I (739) example: Unmounting FAT filesystem
|
||||||
|
I (849) example: Done
|
||||||
|
```
|
||||||
|
|
||||||
|
The logic of the example is contained in a [single source file](./main/fat_example_main.c),
|
||||||
|
and it should be relatively simple to match points in its execution with the log outputs above.
|
2
examples/storage/fatfs_basic/main/CMakeLists.txt
Normal file
2
examples/storage/fatfs_basic/main/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
idf_component_register(SRCS "fat_example_main.c"
|
||||||
|
INCLUDE_DIRS ".")
|
87
examples/storage/fatfs_basic/main/fat_example_main.c
Normal file
87
examples/storage/fatfs_basic/main/fat_example_main.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_vfs.h"
|
||||||
|
#include "esp_vfs_fat.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
static const char *TAG = "example";
|
||||||
|
|
||||||
|
// Mount path for the partition
|
||||||
|
const char *base_path = "/spiflash";
|
||||||
|
|
||||||
|
// Handle of the wear levelling library instance
|
||||||
|
static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Mounting FAT filesystem");
|
||||||
|
// To mount device we need name of device partition, define base_path
|
||||||
|
// and allow format partition in case if it is new one and was not formatted before
|
||||||
|
const esp_vfs_fat_mount_config_t mount_config = {
|
||||||
|
.max_files = 4, // Number of files that can be open at a time
|
||||||
|
.format_if_mount_failed = true, // If true, try to format the partition if mount fails
|
||||||
|
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE, // Size of allocation unit, cluster size.
|
||||||
|
.use_one_fat = false, // Use only one FAT table (reduce memory usage), but decrease reliability of file system in case of power failure.
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(base_path, "storage", &mount_config, &s_wl_handle);
|
||||||
|
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Filesystem mounted");
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Opening file");
|
||||||
|
|
||||||
|
const char *filename = "/spiflash/example.txt";
|
||||||
|
|
||||||
|
FILE *f = fopen(filename, "wb");
|
||||||
|
if (f == NULL) {
|
||||||
|
perror("fopen");
|
||||||
|
ESP_LOGE(TAG, "Failed to open file for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f, "This is written by the device");
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "File written");
|
||||||
|
|
||||||
|
// Open file for reading
|
||||||
|
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);
|
||||||
|
|
||||||
|
// strip newline
|
||||||
|
char *pos = strchr(line, '\n');
|
||||||
|
if (pos) {
|
||||||
|
*pos = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Read from file: '%s'", line);
|
||||||
|
|
||||||
|
// Unmount FATFS
|
||||||
|
ESP_LOGI(TAG, "Unmounting FAT filesystem");
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_vfs_fat_spiflash_unmount_rw_wl(base_path, s_wl_handle));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Done");
|
||||||
|
}
|
6
examples/storage/fatfs_basic/partitions_example.csv
Normal file
6
examples/storage/fatfs_basic/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,
|
|
17
examples/storage/fatfs_basic/pytest_fat_example.py
Normal file
17
examples/storage/fatfs_basic/pytest_fat_example.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_examples_fatfs_basic(dut: Dut) -> None:
|
||||||
|
dut.expect('example: Mounting FAT filesystem', 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: \'This is written by the device\'', timeout=90)
|
||||||
|
dut.expect('example: Unmounting FAT filesystem', timeout=90)
|
||||||
|
dut.expect('example: Done', timeout=90)
|
4
examples/storage/fatfs_basic/sdkconfig.defaults
Normal file
4
examples/storage/fatfs_basic/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
|
Loading…
x
Reference in New Issue
Block a user