mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'update/littlefs_demo_example_v5.1' into 'release/v5.1'
LittleFS demo example added (v5.1) See merge request espressif/esp-idf!28452
This commit is contained in:
commit
2374a0c04e
@ -97,6 +97,7 @@ typedef enum {
|
|||||||
ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD = 0x80, //!< ESPHTTPD partition
|
ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD = 0x80, //!< ESPHTTPD partition
|
||||||
ESP_PARTITION_SUBTYPE_DATA_FAT = 0x81, //!< FAT partition
|
ESP_PARTITION_SUBTYPE_DATA_FAT = 0x81, //!< FAT partition
|
||||||
ESP_PARTITION_SUBTYPE_DATA_SPIFFS = 0x82, //!< SPIFFS partition
|
ESP_PARTITION_SUBTYPE_DATA_SPIFFS = 0x82, //!< SPIFFS partition
|
||||||
|
ESP_PARTITION_SUBTYPE_DATA_LITTLEFS = 0x83, //!< LITTLEFS partition
|
||||||
|
|
||||||
#if __has_include("extra_partition_subtypes.inc")
|
#if __has_include("extra_partition_subtypes.inc")
|
||||||
#include "extra_partition_subtypes.inc"
|
#include "extra_partition_subtypes.inc"
|
||||||
|
@ -71,6 +71,7 @@ SUBTYPES = {
|
|||||||
'esphttpd': 0x80,
|
'esphttpd': 0x80,
|
||||||
'fat': 0x81,
|
'fat': 0x81,
|
||||||
'spiffs': 0x82,
|
'spiffs': 0x82,
|
||||||
|
'littlefs': 0x83,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
examples/storage/littlefs/CMakeLists.txt
Normal file
6
examples/storage/littlefs/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(littlefs_example)
|
76
examples/storage/littlefs/README.md
Normal file
76
examples/storage/littlefs/README.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||||
|
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
|
# About LittleFS
|
||||||
|
|
||||||
|
[LittleFS](https://github.com/littlefs-project/littlefs) is a file system designed for small devices like microcontrollers and embedded systems. It helps these devices manage and store data efficiently.
|
||||||
|
- LittleFS is specifically built to be lightweight and requires less storage space and processing power. It takes up very little memory, which is important for small devices with limited resources.
|
||||||
|
- It has features that ensure data integrity and reliability, so the files stored on the device are less likely to get corrupted or lost.
|
||||||
|
In a nutshell, LittleFS is a specialized file system that helps small devices effectively handle and store data, allowing them to perform tasks efficiently with minimal resources.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
The littlefs is provided under the BSD-3-Clause license. Please refer [littlefs license](https://github.com/littlefs-project/littlefs#license) for more details.
|
||||||
|
|
||||||
|
|
||||||
|
# LittleFS example
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
`littlefs` component is managed in ESP-IDF using IDF component manager. This example uses a littlefs port for [ESP-IDF littlefs](https://components.espressif.com/components/joltwallet/littlefs) for which upstream repository is [esp_littlefs](https://github.com/joltwallet/esp_littlefs).
|
||||||
|
|
||||||
|
LittleFS partition generator is invoked from CMake build system. We use `littlefs_create_partition_image` in main/CMakeLists.txt to generate the partition image and flash it to the device at build time.
|
||||||
|
|
||||||
|
*Note: Currently Windows does not support `LittleFS partition generation` feature.*
|
||||||
|
|
||||||
|
This example demonstrates how to use LittleFS with ESP32. Example does the following steps:
|
||||||
|
|
||||||
|
1. Use an "all-in-one" `esp_vfs_littlefs_register` function to:
|
||||||
|
- initialize LittleFS,
|
||||||
|
- mount LittleFS filesystem using LittleFS library (and format, if the filesystem can not be mounted),
|
||||||
|
- register LittleFS filesystem in VFS, enabling C standard library and POSIX functions to be used.
|
||||||
|
2. Create a file using `fopen` and write to it using `fprintf`.
|
||||||
|
3. Rename the file. Before renaming, check if destination file already exists using `stat` function, and remove it using `unlink` function.
|
||||||
|
4. Open renamed file for reading, read back the line, and print it to the terminal.
|
||||||
|
|
||||||
|
LittleFS partition size is set in partitions_demo_esp_littlefs.csv file. See [Partition Tables](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/partition-tables.html) documentation for more information.
|
||||||
|
|
||||||
|
## How to use example
|
||||||
|
|
||||||
|
### Hardware required
|
||||||
|
|
||||||
|
This example does not require any special hardware, and can be run on any common development board.
|
||||||
|
|
||||||
|
### Build and flash
|
||||||
|
|
||||||
|
Replace PORT with serial port name:
|
||||||
|
|
||||||
|
```
|
||||||
|
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 an example console output. In this case `format_if_mount_failed` parameter was set to `true` in the source code. LittleFS was unformatted, so the initial mount has failed. LittleFS was then formatted, and mounted again.
|
||||||
|
|
||||||
|
```
|
||||||
|
I (264) esp_littlefs: Initializing LittleFS
|
||||||
|
I (274) esp_littlefs: Partition size: total: 983040, used: 12288
|
||||||
|
I (274) esp_littlefs: Opening file
|
||||||
|
I (344) esp_littlefs: File written
|
||||||
|
I (344) esp_littlefs: Renaming file
|
||||||
|
I (354) esp_littlefs: Reading file
|
||||||
|
I (354) esp_littlefs: Read from file: 'Hello World!'
|
||||||
|
I (354) esp_littlefs: Reading from flashed filesystem example.txt
|
||||||
|
I (364) esp_littlefs: Read from file: 'Example text to compile into a LittleFS disk image to be flashed to the ESP device.'
|
||||||
|
I (374) esp_littlefs: LittleFS unmounted
|
||||||
|
I (374) main_task: Returned from app_main()
|
||||||
|
```
|
||||||
|
|
||||||
|
To erase the contents of LittleFS partition, run `idf.py erase-flash` command. Then upload the example again as described above.
|
||||||
|
|
||||||
|
[Here](https://github.com/joltwallet/esp_littlefs#performance) you can find performance results for LittleFS, SPIFFS and FATFS for your reference.
|
1
examples/storage/littlefs/flash_data/example.txt
Normal file
1
examples/storage/littlefs/flash_data/example.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Example text to compile into a LittleFS disk image to be flashed to the ESP device.
|
11
examples/storage/littlefs/main/CMakeLists.txt
Normal file
11
examples/storage/littlefs/main/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
idf_component_register(SRCS "esp_littlefs_example.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Note: you must have a partition named the first argument (here it's "littlefs")
|
||||||
|
# in your partition table csv file.
|
||||||
|
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||||
|
littlefs_create_partition_image(storage ../flash_data FLASH_IN_PROJECT)
|
||||||
|
else()
|
||||||
|
fail_at_build_time(littlefs "Windows does not support LittleFS partition generation")
|
||||||
|
endif()
|
116
examples/storage/littlefs/main/esp_littlefs_example.c
Normal file
116
examples/storage/littlefs/main/esp_littlefs_example.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Brian Pugh
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_littlefs.h"
|
||||||
|
|
||||||
|
static const char *TAG = "esp_littlefs";
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Initializing LittleFS");
|
||||||
|
|
||||||
|
esp_vfs_littlefs_conf_t conf = {
|
||||||
|
.base_path = "/littlefs",
|
||||||
|
.partition_label = "storage",
|
||||||
|
.format_if_mount_failed = true,
|
||||||
|
.dont_mount = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use settings defined above to initialize and mount LittleFS filesystem.
|
||||||
|
// Note: esp_vfs_littlefs_register is an all-in-one convenience function.
|
||||||
|
esp_err_t ret = esp_vfs_littlefs_register(&conf);
|
||||||
|
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
if (ret == ESP_FAIL) {
|
||||||
|
ESP_LOGE(TAG, "Failed to mount or format filesystem");
|
||||||
|
} else if (ret == ESP_ERR_NOT_FOUND) {
|
||||||
|
ESP_LOGE(TAG, "Failed to find LittleFS partition");
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Failed to initialize LittleFS (%s)", esp_err_to_name(ret));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t total = 0, used = 0;
|
||||||
|
ret = esp_littlefs_info(conf.partition_label, &total, &used);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to get LittleFS partition information (%s)", esp_err_to_name(ret));
|
||||||
|
esp_littlefs_format(conf.partition_label);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use POSIX and C standard library functions to work with files.
|
||||||
|
// First create a file.
|
||||||
|
ESP_LOGI(TAG, "Opening file");
|
||||||
|
FILE *f = fopen("/littlefs/hello.txt", "w");
|
||||||
|
if (f == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Failed to open file for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(f, "Hello World!\n");
|
||||||
|
fclose(f);
|
||||||
|
ESP_LOGI(TAG, "File written");
|
||||||
|
|
||||||
|
// Check if destination file exists before renaming
|
||||||
|
struct stat st;
|
||||||
|
if (stat("/littlefs/foo.txt", &st) == 0) {
|
||||||
|
// Delete it if it exists
|
||||||
|
unlink("/littlefs/foo.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename original file
|
||||||
|
ESP_LOGI(TAG, "Renaming file");
|
||||||
|
if (rename("/littlefs/hello.txt", "/littlefs/foo.txt") != 0) {
|
||||||
|
ESP_LOGE(TAG, "Rename failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open renamed file for reading
|
||||||
|
ESP_LOGI(TAG, "Reading file");
|
||||||
|
f = fopen("/littlefs/foo.txt", "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);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Reading from flashed filesystem example.txt");
|
||||||
|
f = fopen("/littlefs/example.txt", "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Failed to open file for reading");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fgets(line, sizeof(line), f);
|
||||||
|
fclose(f);
|
||||||
|
// strip newline
|
||||||
|
pos = strchr(line, '\n');
|
||||||
|
if (pos) {
|
||||||
|
*pos = '\0';
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Read from file: '%s'", line);
|
||||||
|
|
||||||
|
// All done, unmount partition and disable LittleFS
|
||||||
|
esp_vfs_littlefs_unregister(conf.partition_label);
|
||||||
|
ESP_LOGI(TAG, "LittleFS unmounted");
|
||||||
|
}
|
3
examples/storage/littlefs/main/idf_component.yml
Normal file
3
examples/storage/littlefs/main/idf_component.yml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
## IDF Component Manager Manifest File
|
||||||
|
dependencies:
|
||||||
|
joltwallet/littlefs: "~=1.13.0"
|
@ -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, littlefs, , 0xF0000,
|
|
2
examples/storage/littlefs/sdkconfig.defaults
Normal file
2
examples/storage/littlefs/sdkconfig.defaults
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_demo_esp_littlefs.csv"
|
@ -20,3 +20,6 @@ construct
|
|||||||
|
|
||||||
# gdb extensions dependencies
|
# gdb extensions dependencies
|
||||||
freertos_gdb
|
freertos_gdb
|
||||||
|
|
||||||
|
# littlefs-python has to be this specific version due to minimal Python version in IDF v5.0 and v5.1
|
||||||
|
littlefs-python == 0.9.3; python_version < "3.8"
|
||||||
|
Loading…
Reference in New Issue
Block a user