update little fs lib to last version

This commit is contained in:
Dmitry Borisenko
2020-10-19 00:46:38 +03:00
parent 92371f01da
commit b43fd9e389
20 changed files with 1243 additions and 445 deletions

View File

@@ -3,15 +3,15 @@
"chipID": "",
"apssid": "IoTmanager",
"appass": "",
"routerssid": "home",
"routerpass": "kisa3333",
"routerssid": "rise",
"routerpass": "hostel3333",
"timezone": 2,
"ntp": "pool.ntp.org",
"mqttServer": "91.204.228.124",
"mqttPort": 1883,
"mqttPrefix": "/iotTeam",
"mqttUser": "test",
"mqttPass": "test",
"mqttPrefix": "/iotTest",
"mqttUser": "rise",
"mqttPass": "23ri22se32",
"scen": "1",
"pushingboxid": "v7C133E426B0C69E",
"weblogin": "admin",

View File

@@ -3,7 +3,9 @@
//
// Firmware
//
#define FIRMWARE_NAME "esp8266-iotm"
#define FIRMWARE_VERSION 258
#define FLASH_4MB true

View File

@@ -1,24 +1,30 @@
# LITTLEFS
# LittleFS_esp32
## LittleFS library for arduino-esp32
#### Warning: Tested only with git arduino-esp32 #b92c58d core, which is for ESP-IDF 3.3! </br> With other versions/releases of the core including release 1.0.4, especially against different IDF this will NOT not work.
- A LittleFS wrapper for Arduino ESP32 of [Mbed LittleFS](https://github.com/ARMmbed/littlefs)
- A LittleFS wrapper for Arduino ESP32 of [ARMmbed LittleFS](https://github.com/ARMmbed/littlefs)
- Based on [ESP-IDF port of joltwallet/esp_littlefs](https://github.com/joltwallet/esp_littlefs) , thank you Brian!
- Functionality is the same and SPIFFS partition scheme and data folder meaning are kept
- You can use either LITTLEFS or SPIFFS but not both simultaneously on given Arduino project
- A PR to embed it to esp32 core is made too. See the [PR status here](https://github.com/espressif/arduino-esp32/pull/4096)
- As a reference, see [LillteFS library for ESP8266 core](https://github.com/esp8266/Arduino/tree/master/libraries/LittleFS)
- [PR at esp32 core development](https://github.com/espressif/arduino-esp32/pull/4096)
- [PR at esp-idf development](https://github.com/espressif/esp-idf/pull/5469)
- The functionality is similar to SPIFFS
### Installation
- Copy <b>LITTLEFS</b> folder to Arduino IDE embedded libraries place
- For Win, the default place of arduino-esp32 core libraries is somewhere like:
```C:\Users\<username>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries ```
- Alternatively, you can put it to your usual libraries place
- Use **Arduino Library Manager**
- Or download / use **git** to have latest repository of **LITTLEFS** added to Arduino IDE **/libraries** folder
(File > Preferences > Sketchbook location).
- See ``` #define CONFIG_LITTLEFS_FOR_IDF_3_2 ``` in **esp_littlefs.c**.
When defined, code builds with any IDF 3.2 - 4.x.
On IDF newer than 3.2, it **can** be commented to enable file timestamp feature.
See LITTLEFS_time example.
- The other ``` #define CONFIG_LITTLEFS_xxxxx ``` are set to optimal default values.
Read [here](https://github.com/joltwallet/esp_littlefs/blob/master/Kconfig) and [here](https://github.com/ARMmbed/littlefs/blob/master/README.md) if you want to modify.
### Usage
- In your existing code, replace SPIFFS like this
- Use LITTLEFS same way as SPIFFS
- A quick startup based on your existing code you can re-define SPIFFS
```
#define USE_LittleFS
@@ -30,30 +36,59 @@
#include <SPIFFS.h>
#endif
```
### Differences with SPIFFS (and in this implementation)
- Note, this may not work if your sketch uses other libraries that use SPIFFS themselves.
- LittleFS has folders, you my need to tweak your code to iterate files in folders
- Root: /someting = something, so attention to /
- Lower level littlefs library cannot mount on NULL as partition_label name, while SPIFFS can
- Lower level littlefs library does not need maxOpenFiles parameter
- Speed (LITTLEFS_Test.ino) 1048576 bytes written in 16238 ms / 1048576 bytes read in 918 ms
- Speed (SPIFFS_Test.ino) 1048576 bytes written in 65971 ms / 1048576 bytes read in 680 ms
### Differences with SPIFFS
- LittleFS has folders, you need to iterate files in folders. See **To Do** below.
- At root a "/folder" = "folder"
- Requires a label for mount point, NULL will not work
- maxOpenFiles parameter is unused, kept for compatibility
- LITTLEFS.mkdir(path) and LITTLEFS.rmdir(path) work as expected for folders
- Speed comparison based on **LittleFS_test.ino** sketch (for a file 1048576 bytes):
|Filesystem|Read time [ms]|Write time [ms]|
|----|----|----|
|FAT|276|14493|
|LITTLEFS|446*|16387|
|SPIFFS|767|65622|
*The read speed improved by changing ```#define CONFIG_LITTLEFS_CACHE_SIZE``` from 128 to 512
### Arduino ESP32 LittleFS filesystem upload tool
- Download the tool archive from [here](https://github.com/lorol/arduino-esp32littlefs-plugin/raw/master/src/bin/esp32littlefs.jar)
- In your Arduino sketchbook directory, create tools directory if it doesn't exist yet.
- Unpack the tool into tools directory (the path will look like ```<home_dir>/Arduino/tools/ESP32LittleFS/tool/esp32littlefs.jar```).
- You need the [mklittlefs tool](https://github.com/earlephilhower/mklittlefs) Download the [release](https://github.com/earlephilhower/mklittlefs/releases) and copy it to
packages\esp32\tools\mkspiffs\<mklittlefs rev. x.x.x>\ or on checkout (dev) environment to: packages\esp32\hardware\esp32\<release>\tools\mklittlefs\
- Use (replace if exists) [arduino-esp32fs-plugin](https://github.com/me-no-dev/arduino-esp32fs-plugin/pull/23 ) with [this variant](https://github.com/lorol/arduino-esp32fs-plugin), which supports SPIFFS, LittleFS and FatFS
- Requires [mklittlefs executable](https://github.com/earlephilhower/mklittlefs) which is available [in releases section here](https://github.com/lorol/arduino-esp32fs-plugin ) or download the zipped binary [here](https://github.com/earlephilhower/mklittlefs/releases) or from **esp-quick-toolchain** releases [here](https://github.com/earlephilhower/esp-quick-toolchain/releases)
- Copy it to **/tools** folder of esp32 platform where **espota** and **esptool** (.py or.exe) tools are located
- Restart Arduino IDE.
### PlatformIO
- See [LITTLEFS_PlatformIO example here](https://github.com/lorol/LITTLEFS/tree/master/examples/LITTLEFS_PlatformIO)
( based on notes below from [BlueAndi](https://github.com/BlueAndi) )
- Add to _platformio.ini_:
`extra_scripts = replace_fs.py`
- Add _replace_fs.py_ to project root directory (where platformio.ini is located):
```python
Import("env")
print("Replace MKSPIFFSTOOL with mklittlefs.exe")
env.Replace (MKSPIFFSTOOL = "mklittlefs.exe")
```
- Add _mklittlefs.exe_ to project root directory as well.
## Credits and license
- This work is based on [Mbed LittleFS](https://github.com/ARMmbed/littlefs) , [ESP-IDF port of joltwallet/esp_littlefs](https://github.com/joltwallet/esp_littlefs) , [Espressif Arduino core for the ESP32, the ESP-IDF - SPIFFS Library](https://github.com/espressif/arduino-esp32/tree/master/libraries/SPIFFS)
- This work is based on [ARMmbed LittleFS](https://github.com/ARMmbed/littlefs) , [ESP-IDF port of joltwallet/esp_littlefs](https://github.com/joltwallet/esp_littlefs) , [Espressif Arduino core for the ESP32, the ESP-IDF - SPIFFS Library](https://github.com/espressif/arduino-esp32/tree/master/libraries/SPIFFS)
- Licensed under GPL v2 ([text](LICENSE))
## To Do
- Supporting different IDF versions
- [x] Submit to be added to Arduino Library Manager
- [ ] Decide on more compatibility (or not) with SPIFFS' lack of folders, similar to esp8266' way:
- [recursive folders auto creation](https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.cpp#L60) when a new file is created at non-existing path
- [recursive folders auto deletion](https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.h#L149) on "last file" deletion (SPIFFS cannot have "folder w/o file")
- review other differences: opendir(), rmdir(), unlink()
- [ ] Follow-up / eventually retire this library if LittleFS gets implemented through IDF / esp32 Arduino core.

View File

@@ -0,0 +1,4 @@
.pio
.vscode
mklittlefs.exe
mklittlefs

View File

@@ -0,0 +1,68 @@
# How to run on PlatformIO IDE
- Download and extract to this project root a **mklittlefs** executable for your OS [from a zipped binary here](https://github.com/earlephilhower/mklittlefs/releases)
- Open **LITTLEFS_PlatformIO** folder
- Run PlatformIO project task: **Upload Filesystem Image**
- Run PlatformIO project task: **Upload and Monitor**
- You will see a Serial output like:
```
--- Miniterm on COM5 115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (Snfigsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10044
load:0x40080400,len:5872
entry 0x400806ac
Listing directory: /
FILE: /file1.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33
DIR : /testfolder LAST WRITE: 2020-10-06 15:10:33
Creating Dir: /mydir
Dir created
Writing file: /mydir/hello2.txt
- file written
Listing directory: /
FILE: /file1.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33
DIR : /mydir LAST WRITE: 1970-01-01 00:00:00
Listing directory: /mydir
FILE: /mydir/hello2.txt SIZE: 6 LAST WRITE: 1970-01-01 00:00:00
DIR : /testfolder LAST WRITE: 2020-10-06 15:10:33
Listing directory: /testfolder
FILE: /testfolder/test2.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33
Deleting file: /mydir/hello2.txt
- file deleted
Removing Dir: /mydir
Dir removed
Listing directory: /
FILE: /file1.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33
DIR : /testfolder LAST WRITE: 2020-10-06 15:10:33
Listing directory: /testfolder
FILE: /testfolder/test2.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33
Writing file: /hello.txt
- file written
Appending to file: /hello.txt
- message appended
Reading file: /hello.txt
- read from file:
Hello World!
Renaming file /hello.txt to /foo.txt
- file renamed
Reading file: /foo.txt
- read from file:
Hello World!
Deleting file: /foo.txt
- file deleted
Testing file I/O with /test.txt
- writing................................................................
- 1048576 bytes written in 12006 ms
- reading................................................................
- 1048576 bytes read in 547 ms
Deleting file: /test.txt
- file deleted
Test complete
```
- If you have a module with more than 4MB flash, you can uncomment **partitions_custom.csv** in **platformio.ini** and modify the csv file accordingly

View File

@@ -0,0 +1 @@
aaa

View File

@@ -0,0 +1 @@
bbb

View File

@@ -0,0 +1,2 @@
Import("env")
env.Replace( MKSPIFFSTOOL=env.get("PROJECT_DIR") + '/mklittlefs' )

View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
ota_0, app, ota_0, 0x10000, 0x1A0000,
ota_1, app, ota_1, , 0x1A0000,
otadata, data, ota, 0x350000, 0x2000,
nvs, data, nvs, , 0x6000,
data, data, spiffs, , 0xA8000,
1 # Name Type SubType Offset Size Flags
2 ota_0 app ota_0 0x10000 0x1A0000
3 ota_1 app ota_1 0x1A0000
4 otadata data ota 0x350000 0x2000
5 nvs data nvs 0x6000
6 data data spiffs 0xA8000

View File

@@ -0,0 +1,35 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = esp32
[env]
framework = arduino
[env:esp32]
platform = espressif32
;platform = https://github.com/platformio/platform-espressif32.git
;board_build.mcu = esp32
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
build_flags =
${env.build_flags}
-D=${PIOENV}
;-D CONFIG_LITTLEFS_FOR_IDF_3_2
lib_deps = https://github.com/lorol/LITTLEFS.git
board = esp32dev
;board_build.partitions = partitions_custom.csv
monitor_filters = esp32_exception_decoder
monitor_speed = 115200
extra_scripts = ./littlefsbuilder.py

View File

@@ -0,0 +1,293 @@
#include <Arduino.h>
#include "FS.h"
#include <LITTLEFS.h>
#ifndef CONFIG_LITTLEFS_FOR_IDF_3_2
#include <time.h>
#endif
/* You only need to format LITTLEFS the first time you run a
test or else use the LITTLEFS plugin to create a partition
https://github.com/lorol/arduino-esp32littlefs-plugin */
#define FORMAT_LITTLEFS_IF_FAILED true
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\r\n", dirname);
File root = fs.open(dirname);
if(!root){
Serial.println("- failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println(" - not a directory");
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
#ifdef CONFIG_LITTLEFS_FOR_IDF_3_2
Serial.println(file.name());
#else
Serial.print(file.name());
time_t t= file.getLastWrite();
struct tm * tmstruct = localtime(&t);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
#endif
if(levels){
listDir(fs, file.name(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
#ifdef CONFIG_LITTLEFS_FOR_IDF_3_2
Serial.println(file.size());
#else
Serial.print(file.size());
time_t t= file.getLastWrite();
struct tm * tmstruct = localtime(&t);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
#endif
}
file = root.openNextFile();
}
}
void createDir(fs::FS &fs, const char * path){
Serial.printf("Creating Dir: %s\n", path);
if(fs.mkdir(path)){
Serial.println("Dir created");
} else {
Serial.println("mkdir failed");
}
}
void removeDir(fs::FS &fs, const char * path){
Serial.printf("Removing Dir: %s\n", path);
if(fs.rmdir(path)){
Serial.println("Dir removed");
} else {
Serial.println("rmdir failed");
}
}
void readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\r\n", path);
File file = fs.open(path);
if(!file || file.isDirectory()){
Serial.println("- failed to open file for reading");
return;
}
Serial.println("- read from file:");
while(file.available()){
Serial.write(file.read());
}
file.close();
}
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\r\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- write failed");
}
file.close();
}
void appendFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Appending to file: %s\r\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("- failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("- message appended");
} else {
Serial.println("- append failed");
}
file.close();
}
void renameFile(fs::FS &fs, const char * path1, const char * path2){
Serial.printf("Renaming file %s to %s\r\n", path1, path2);
if (fs.rename(path1, path2)) {
Serial.println("- file renamed");
} else {
Serial.println("- rename failed");
}
}
void deleteFile(fs::FS &fs, const char * path){
Serial.printf("Deleting file: %s\r\n", path);
if(fs.remove(path)){
Serial.println("- file deleted");
} else {
Serial.println("- delete failed");
}
}
// SPIFFS-like write and delete file
// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.cpp#L60
void writeFile2(fs::FS &fs, const char * path, const char * message){
if(!fs.exists(path)){
if (strchr(path, '/')) {
Serial.printf("Create missing folders of: %s\r\n", path);
char *pathStr = strdup(path);
if (pathStr) {
char *ptr = strchr(pathStr, '/');
while (ptr) {
*ptr = 0;
fs.mkdir(pathStr);
*ptr = '/';
ptr = strchr(ptr+1, '/');
}
}
free(pathStr);
}
}
Serial.printf("Writing file to: %s\r\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- write failed");
}
file.close();
}
// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.h#L149
void deleteFile2(fs::FS &fs, const char * path){
Serial.printf("Deleting file and empty folders on path: %s\r\n", path);
if(fs.remove(path)){
Serial.println("- file deleted");
} else {
Serial.println("- delete failed");
}
char *pathStr = strdup(path);
if (pathStr) {
char *ptr = strrchr(pathStr, '/');
if (ptr) {
Serial.printf("Removing all empty folders on path: %s\r\n", path);
}
while (ptr) {
*ptr = 0;
fs.rmdir(pathStr);
ptr = strrchr(pathStr, '/');
}
free(pathStr);
}
}
void testFileIO(fs::FS &fs, const char * path){
Serial.printf("Testing file I/O with %s\r\n", path);
static uint8_t buf[512];
size_t len = 0;
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("- failed to open file for writing");
return;
}
size_t i;
Serial.print("- writing" );
uint32_t start = millis();
for(i=0; i<2048; i++){
if ((i & 0x001F) == 0x001F){
Serial.print(".");
}
file.write(buf, 512);
}
Serial.println("");
uint32_t end = millis() - start;
Serial.printf(" - %u bytes written in %u ms\r\n", 2048 * 512, end);
file.close();
file = fs.open(path);
start = millis();
end = start;
i = 0;
if(file && !file.isDirectory()){
len = file.size();
size_t flen = len;
start = millis();
Serial.print("- reading" );
while(len){
size_t toRead = len;
if(toRead > 512){
toRead = 512;
}
file.read(buf, toRead);
if ((i++ & 0x001F) == 0x001F){
Serial.print(".");
}
len -= toRead;
}
Serial.println("");
end = millis() - start;
Serial.printf("- %u bytes read in %u ms\r\n", flen, end);
file.close();
} else {
Serial.println("- failed to open file for reading");
}
}
void setup(){
Serial.begin(115200);
if(!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
Serial.println("LITTLEFS Mount Failed");
return;
}
listDir(LITTLEFS, "/", 0);
createDir(LITTLEFS, "/mydir");
writeFile(LITTLEFS, "/mydir/hello2.txt", "Hello2");
//writeFile(LITTLEFS, "/mydir/newdir2/newdir3/hello3.txt", "Hello3");
writeFile2(LITTLEFS, "/mydir/newdir2/newdir3/hello3.txt", "Hello3");
listDir(LITTLEFS, "/", 3);
deleteFile(LITTLEFS, "/mydir/hello2.txt");
//deleteFile(LITTLEFS, "/mydir/newdir2/newdir3/hello3.txt");
deleteFile2(LITTLEFS, "/mydir/newdir2/newdir3/hello3.txt");
removeDir(LITTLEFS, "/mydir");
listDir(LITTLEFS, "/", 3);
writeFile(LITTLEFS, "/hello.txt", "Hello ");
appendFile(LITTLEFS, "/hello.txt", "World!\r\n");
readFile(LITTLEFS, "/hello.txt");
renameFile(LITTLEFS, "/hello.txt", "/foo.txt");
readFile(LITTLEFS, "/foo.txt");
deleteFile(LITTLEFS, "/foo.txt");
testFileIO(LITTLEFS, "/test.txt");
deleteFile(LITTLEFS, "/test.txt");
Serial.println( "Test complete" );
}
void loop(){
}

View File

@@ -0,0 +1,219 @@
#include "FS.h"
//#include "SPIFFS.h"
#include "LITTLEFS.h"
#include <time.h>
#include <WiFi.h>
#define SPIFFS LITTLEFS
/* This examples uses "quick re-define" of SPIFFS to run
an existing sketch with LITTLEFS instead of SPIFFS
To get time/date stamps by file.getLastWrite(), you need an
esp32 core on IDF 3.3 and comment a line in file esp_littlefs.c:
//#define CONFIG_LITTLEFS_FOR_IDF_3_2
You only need to format LITTLEFS the first time you run a
test or else use the LITTLEFS plugin to create a partition
https://github.com/lorol/arduino-esp32littlefs-plugin */
#define FORMAT_LITTLEFS_IF_FAILED true
const char* ssid = "yourssid";
const char* password = "yourpass";
long timezone = 1;
byte daysavetime = 1;
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if(!root){
Serial.println("Failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.print (file.name());
time_t t= file.getLastWrite();
struct tm * tmstruct = localtime(&t);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
if(levels){
listDir(fs, file.name(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.print(file.size());
time_t t= file.getLastWrite();
struct tm * tmstruct = localtime(&t);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
}
file = root.openNextFile();
}
}
void createDir(fs::FS &fs, const char * path){
Serial.printf("Creating Dir: %s\n", path);
if(fs.mkdir(path)){
Serial.println("Dir created");
} else {
Serial.println("mkdir failed");
}
}
void removeDir(fs::FS &fs, const char * path){
Serial.printf("Removing Dir: %s\n", path);
if(fs.rmdir(path)){
Serial.println("Dir removed");
} else {
Serial.println("rmdir failed");
}
}
void readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if(!file){
Serial.println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while(file.available()){
Serial.write(file.read());
}
file.close();
}
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("Failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}
void appendFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("Failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
void renameFile(fs::FS &fs, const char * path1, const char * path2){
Serial.printf("Renaming file %s to %s\n", path1, path2);
if (fs.rename(path1, path2)) {
Serial.println("File renamed");
} else {
Serial.println("Rename failed");
}
}
void deleteFile(fs::FS &fs, const char * path){
Serial.printf("Deleting file: %s\n", path);
if(fs.remove(path)){
Serial.println("File deleted");
} else {
Serial.println("Delete failed");
}
}
void setup(){
Serial.begin(115200);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("Contacting Time Server");
configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
struct tm tmstruct ;
delay(2000);
tmstruct.tm_year = 0;
getLocalTime(&tmstruct, 5000);
Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct.tm_year)+1900,( tmstruct.tm_mon)+1, tmstruct.tm_mday,tmstruct.tm_hour , tmstruct.tm_min, tmstruct.tm_sec);
Serial.println("");
if(!SPIFFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
Serial.println("LITTLEFS Mount Failed");
return;
}
Serial.println("----list 1----");
listDir(SPIFFS, "/", 1);
Serial.println("----remove old dir----");
removeDir(SPIFFS, "/mydir");
Serial.println("----create a new dir----");
createDir(SPIFFS, "/mydir");
Serial.println("----remove the new dir----");
removeDir(SPIFFS, "/mydir");
Serial.println("----create the new again----");
createDir(SPIFFS, "/mydir");
Serial.println("----create and work with file----");
writeFile(SPIFFS, "/mydir/hello.txt", "Hello ");
appendFile(SPIFFS, "/mydir/hello.txt", "World!\n");
Serial.println("----list 2----");
listDir(SPIFFS, "/", 1);
Serial.println("----attempt to remove dir w/ file----");
removeDir(SPIFFS, "/mydir");
Serial.println("----remove dir after deleting file----");
deleteFile(SPIFFS, "/mydir/hello.txt");
removeDir(SPIFFS, "/mydir");
Serial.println("----list 3----");
listDir(SPIFFS, "/", 1);
Serial.println( "Test complete" );
}
void loop(){
}

View File

@@ -2,9 +2,10 @@
#include "FS.h"
#include <LITTLEFS.h>
/* You only need to format SPIFFS the first time you run a
/* You only need to format LITTLEFS the first time you run a
test or else use the LITTLEFS plugin to create a partition
https://github.com/me-no-dev/arduino-esp32fs-plugin */
https://github.com/lorol/arduino-esp32littlefs-plugin */
#define FORMAT_LITTLEFS_IF_FAILED true
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
@@ -38,6 +39,24 @@ void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
}
}
void createDir(fs::FS &fs, const char * path){
Serial.printf("Creating Dir: %s\n", path);
if(fs.mkdir(path)){
Serial.println("Dir created");
} else {
Serial.println("mkdir failed");
}
}
void removeDir(fs::FS &fs, const char * path){
Serial.printf("Removing Dir: %s\n", path);
if(fs.rmdir(path)){
Serial.println("Dir removed");
} else {
Serial.println("rmdir failed");
}
}
void readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\r\n", path);
@@ -104,6 +123,66 @@ void deleteFile(fs::FS &fs, const char * path){
}
}
// SPIFFS-like write and delete file
// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.cpp#L60
void writeFile2(fs::FS &fs, const char * path, const char * message){
if(!fs.exists(path)){
if (strchr(path, '/')) {
Serial.printf("Create missing folders of: %s\r\n", path);
char *pathStr = strdup(path);
if (pathStr) {
char *ptr = strchr(pathStr, '/');
while (ptr) {
*ptr = 0;
fs.mkdir(pathStr);
*ptr = '/';
ptr = strchr(ptr+1, '/');
}
}
free(pathStr);
}
}
Serial.printf("Writing file to: %s\r\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- write failed");
}
file.close();
}
// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.h#L149
void deleteFile2(fs::FS &fs, const char * path){
Serial.printf("Deleting file and empty folders on path: %s\r\n", path);
if(fs.remove(path)){
Serial.println("- file deleted");
} else {
Serial.println("- delete failed");
}
char *pathStr = strdup(path);
if (pathStr) {
char *ptr = strrchr(pathStr, '/');
if (ptr) {
Serial.printf("Removing all empty folders on path: %s\r\n", path);
}
while (ptr) {
*ptr = 0;
fs.rmdir(pathStr);
ptr = strrchr(pathStr, '/');
}
free(pathStr);
}
}
void testFileIO(fs::FS &fs, const char * path){
Serial.printf("Testing file I/O with %s\r\n", path);
@@ -164,8 +243,18 @@ void setup(){
Serial.println("LITTLEFS Mount Failed");
return;
}
Serial.println( "SPIFFS-like write file to new path and delete it w/folders" );
writeFile2(LITTLEFS, "/new1/new2/new3/hello3.txt", "Hello3");
listDir(LITTLEFS, "/", 3);
deleteFile2(LITTLEFS, "/new1/new2/new3/hello3.txt");
listDir(LITTLEFS, "/", 0);
listDir(LITTLEFS, "/", 3);
createDir(LITTLEFS, "/mydir");
writeFile(LITTLEFS, "/mydir/hello2.txt", "Hello2");
listDir(LITTLEFS, "/", 1);
deleteFile(LITTLEFS, "/mydir/hello2.txt");
removeDir(LITTLEFS, "/mydir");
listDir(LITTLEFS, "/", 1);
writeFile(LITTLEFS, "/hello.txt", "Hello ");
appendFile(LITTLEFS, "/hello.txt", "World!\r\n");
readFile(LITTLEFS, "/hello.txt");
@@ -174,6 +263,7 @@ void setup(){
deleteFile(LITTLEFS, "/foo.txt");
testFileIO(LITTLEFS, "/test.txt");
deleteFile(LITTLEFS, "/test.txt");
Serial.println( "Test complete" );
}

View File

@@ -1,10 +1,10 @@
{
"name":"LITTLEFS",
"description":"LITTLEFS File System Library for ESP32",
"name":"LittleFS_esp32",
"description":"LittleFS for esp32",
"keywords":"littlefs, spiffs",
"authors":
{
"name": "LL",
"name": "lorol",
"maintainer": true
},
"repository":

View File

@@ -1,9 +1,9 @@
name=LITTLEFS
name=LittleFS_esp32
version=1.0
author=LL
maintainer=LL
sentence=ESP32 LITTLEFS File System
paragraph=
author=lorol
maintainer=lorol
sentence=LittleFS for esp32
paragraph=LittleFS for esp32
category=Data Storage
url=
url=https://github.com/lorol/LITTLEFS
architectures=esp32

View File

@@ -2,27 +2,40 @@
* @file esp_littlefs.c
* @brief Maps LittleFS <-> ESP_VFS
* @author Brian Pugh
*
* @note Modified and used by lorol for Arduino esp32 core
*
* Copyright 2020 Brian Pugh
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//#define LOG_LOCAL_LEVEL 4
#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */
#include "esp_littlefs.h"
#include "esp_log.h"
#include "esp_spi_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include <unistd.h>
#include <dirent.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/param.h>
#include <unistd.h>
#include "esp_log.h"
#include "esp_spi_flash.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "littlefs_api.h"
#if __has_include("esp32/rom/spi_flash.h")
#include "esp32/rom/spi_flash.h"
#else
#include "rom/spi_flash.h"
#endif
#include "esp_system.h"
#include "esp_littlefs.h"
#include "littlefs_api.h"
static const char TAG[] = "esp_littlefs";
@@ -39,10 +52,18 @@ static const char TAG[] = "esp_littlefs";
#define CONFIG_LITTLEFS_READ_SIZE 128
#define CONFIG_LITTLEFS_WRITE_SIZE 128
#define CONFIG_LITTLEFS_LOOKAHEAD_SIZE 128
#define CONFIG_LITTLEFS_CACHE_SIZE 128
#define CONFIG_LITTLEFS_CACHE_SIZE 512
#define CONFIG_LITTLEFS_BLOCK_CYCLES 512
//#define CONFIG_SECURE_FLASH_ENC_ENABLED 1 /* For encrypted, in part.csv: flash_test, data, spiffs, , 512K, encrypted */
#ifdef CONFIG_LITTLEFS_FOR_IDF_3_2
#define CONFIG_LITTLEFS_USE_MTIME 0
#else
#define CONFIG_LITTLEFS_USE_MTIME 1
#define CONFIG_LITTLEFS_MTIME_USE_SECONDS 1
#endif
/**
* @brief littlefs DIR structure
@@ -115,6 +136,7 @@ void esp_littlefs_free_fds(esp_littlefs_t *efs) {
efs->cache_size = efs->fd_count = 0;
}
/********************
* Public Functions *
********************/
@@ -143,7 +165,8 @@ esp_err_t esp_littlefs_info(const char *partition_label, size_t *total_bytes, si
return ESP_OK;
}
esp_err_t esp_vfs_littlefs_register(const esp_vfs_littlefs_conf_t *conf) {
esp_err_t esp_vfs_littlefs_register(const esp_vfs_littlefs_conf_t * conf)
{
assert(conf->base_path);
const esp_vfs_t vfs = {
.flags = ESP_VFS_FLAG_CONTEXT_PTR,
@@ -170,9 +193,13 @@ esp_err_t esp_vfs_littlefs_register(const esp_vfs_littlefs_conf_t *conf) {
.mkdir_p = &vfs_littlefs_mkdir,
.rmdir_p = &vfs_littlefs_rmdir,
.fsync_p = &vfs_littlefs_fsync,
#ifndef CONFIG_LITTLEFS_FOR_IDF_3_2
#if CONFIG_LITTLEFS_USE_MTIME
.utime_p = &vfs_littlefs_utime,
#else
.utime_p = NULL,
#endif // CONFIG_LITTLEFS_USE_MTIME
#endif //CONFIG_LITTLEFS_FOR_IDF_3_2
};
esp_err_t err = esp_littlefs_init(conf);
@@ -195,18 +222,19 @@ esp_err_t esp_vfs_littlefs_register(const esp_vfs_littlefs_conf_t *conf) {
return err;
}
ESP_LOGD(TAG, "Successfully registered LittleFS to \"%s\"", conf->base_path);
ESP_LOGV(TAG, "Successfully registered LittleFS to \"%s\"", conf->base_path);
return ESP_OK;
}
esp_err_t esp_vfs_littlefs_unregister(const char *partition_label) {
esp_err_t esp_vfs_littlefs_unregister(const char* partition_label)
{
assert(partition_label);
int index;
if (esp_littlefs_by_label(partition_label, &index) != ESP_OK) {
ESP_LOGE(TAG, "Partition was never registered.");
return ESP_ERR_INVALID_STATE;
}
ESP_LOGD(TAG, "Unregistering \"%s\"", partition_label);
ESP_LOGV(TAG, "Unregistering \"%s\"", partition_label);
esp_err_t err = esp_vfs_unregister(_efs[index]->base_path);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to unregister \"%s\"", partition_label);
@@ -226,14 +254,14 @@ esp_err_t esp_littlefs_format(const char *partition_label) {
esp_err_t err;
esp_littlefs_t *efs = NULL;
ESP_LOGI(TAG, "Formatting \"%s\"", partition_label);
ESP_LOGV(TAG, "Formatting \"%s\"", partition_label);
/* Get a context */
err = esp_littlefs_by_label(partition_label, &index);
if( err != ESP_OK ){
/* Create a tmp context */
ESP_LOGD(TAG, "Temporarily creating EFS context.");
ESP_LOGV(TAG, "Temporarily creating EFS context.");
efs_free = true;
const esp_vfs_littlefs_conf_t conf = {
/* base_name not necessary for initializing */
@@ -259,7 +287,7 @@ esp_err_t esp_littlefs_format(const char *partition_label) {
/* Unmount if mounted */
if(efs->cache_size > 0){
int res;
ESP_LOGD(TAG, "Partition was mounted. Unmounting...");
ESP_LOGV(TAG, "Partition was mounted. Unmounting...");
was_mounted = true;
res = lfs_unmount(efs->fs);
if(res != LFS_ERR_OK){
@@ -272,7 +300,7 @@ esp_err_t esp_littlefs_format(const char *partition_label) {
/* Erase and Format */
{
int res;
ESP_LOGD(TAG, "Formatting filesystem");
ESP_LOGV(TAG, "Formatting filesystem");
esp_littlefs_erase_partition(partition_label);
res = lfs_format(efs->fs, &efs->cfg);
if( res != LFS_ERR_OK ) {
@@ -285,7 +313,7 @@ esp_err_t esp_littlefs_format(const char *partition_label) {
if( was_mounted ) {
int res;
/* Remount the partition */
ESP_LOGD(TAG, "Remounting formatted partition");
ESP_LOGV(TAG, "Remounting formatted partition");
res = lfs_mount(efs->fs, &efs->cfg);
if( res != LFS_ERR_OK ) {
ESP_LOGE(TAG, "Failed to re-mount filesystem");
@@ -294,7 +322,7 @@ esp_err_t esp_littlefs_format(const char *partition_label) {
efs->cache_size = CONFIG_LITTLEFS_FD_CACHE_MIN_SIZE; // Initial size of cache; will resize ondemand
efs->cache = calloc(sizeof(*efs->cache), efs->cache_size);
}
ESP_LOGD(TAG, "Format Success!");
ESP_LOGV(TAG, "Format Success!");
err = ESP_OK;
@@ -310,38 +338,22 @@ exit:
*/
const char * esp_littlefs_errno(enum lfs_error lfs_errno) {
switch(lfs_errno){
case LFS_ERR_OK:
return "LFS_ERR_OK";
case LFS_ERR_IO:
return "LFS_ERR_IO";
case LFS_ERR_CORRUPT:
return "LFS_ERR_CORRUPT";
case LFS_ERR_NOENT:
return "LFS_ERR_NOENT";
case LFS_ERR_EXIST:
return "LFS_ERR_EXIST";
case LFS_ERR_NOTDIR:
return "LFS_ERR_NOTDIR";
case LFS_ERR_ISDIR:
return "LFS_ERR_ISDIR";
case LFS_ERR_NOTEMPTY:
return "LFS_ERR_NOTEMPTY";
case LFS_ERR_BADF:
return "LFS_ERR_BADF";
case LFS_ERR_FBIG:
return "LFS_ERR_FBIG";
case LFS_ERR_INVAL:
return "LFS_ERR_INVAL";
case LFS_ERR_NOSPC:
return "LFS_ERR_NOSPC";
case LFS_ERR_NOMEM:
return "LFS_ERR_NOMEM";
case LFS_ERR_NOATTR:
return "LFS_ERR_NOATTR";
case LFS_ERR_NAMETOOLONG:
return "LFS_ERR_NAMETOOLONG";
default:
return "LFS_ERR_UNDEFINED";
case LFS_ERR_OK: return "LFS_ERR_OK";
case LFS_ERR_IO: return "LFS_ERR_IO";
case LFS_ERR_CORRUPT: return "LFS_ERR_CORRUPT";
case LFS_ERR_NOENT: return "LFS_ERR_NOENT";
case LFS_ERR_EXIST: return "LFS_ERR_EXIST";
case LFS_ERR_NOTDIR: return "LFS_ERR_NOTDIR";
case LFS_ERR_ISDIR: return "LFS_ERR_ISDIR";
case LFS_ERR_NOTEMPTY: return "LFS_ERR_NOTEMPTY";
case LFS_ERR_BADF: return "LFS_ERR_BADF";
case LFS_ERR_FBIG: return "LFS_ERR_FBIG";
case LFS_ERR_INVAL: return "LFS_ERR_INVAL";
case LFS_ERR_NOSPC: return "LFS_ERR_NOSPC";
case LFS_ERR_NOMEM: return "LFS_ERR_NOMEM";
case LFS_ERR_NOATTR: return "LFS_ERR_NOATTR";
case LFS_ERR_NAMETOOLONG: return "LFS_ERR_NAMETOOLONG";
default: return "LFS_ERR_UNDEFINED";
}
return "";
}
@@ -360,7 +372,8 @@ const char *esp_littlefs_errno(enum lfs_error lfs_errno) {
* @param efs Pointer to pointer to struct. Done this way so we can also zero
* out the pointer.
*/
static void esp_littlefs_free(esp_littlefs_t **efs) {
static void esp_littlefs_free(esp_littlefs_t ** efs)
{
esp_littlefs_t * e = *efs;
if (e == NULL) return;
*efs = NULL;
@@ -395,20 +408,20 @@ static esp_err_t esp_littlefs_by_label(const char *label, int *index) {
if(!label || !index) return ESP_ERR_INVALID_ARG;
ESP_LOGD(TAG, "Searching for existing filesystem for partition \"%s\"", label);
ESP_LOGV(TAG, "Searching for existing filesystem for partition \"%s\"", label);
for (i = 0; i < CONFIG_LITTLEFS_MAX_PARTITIONS; i++) {
p = _efs[i];
if (p) {
if (strncmp(label, p->partition->label, 17) == 0) {
*index = i;
ESP_LOGD(TAG, "Found existing filesystem \"%s\" at index %d", label, *index);
ESP_LOGV(TAG, "Found existing filesystem \"%s\" at index %d", label, *index);
return ESP_OK;
}
}
}
ESP_LOGD(TAG, "Existing filesystem \%s\" not found", label);
ESP_LOGV(TAG, "Existing filesystem \%s\" not found", label);
return ESP_ERR_NOT_FOUND;
}
@@ -435,7 +448,7 @@ static esp_err_t esp_littlefs_get_empty(int *index) {
* @return ESP_OK on success
*/
static esp_err_t esp_littlefs_erase_partition(const char *partition_label) {
ESP_LOGD(TAG, "Erasing partition...");
ESP_LOGV(TAG, "Erasing partition...");
const esp_partition_t* partition = esp_partition_find_first(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY,
@@ -460,13 +473,13 @@ static esp_err_t esp_littlefs_erase_partition(const char *partition_label) {
*/
static int esp_littlefs_flags_conv(int m) {
int lfs_flags = 0;
if (m == O_APPEND) lfs_flags |= LFS_O_APPEND;
if (m == O_RDONLY) lfs_flags |= LFS_O_RDONLY;
if (m & O_WRONLY) lfs_flags |= LFS_O_WRONLY;
if (m & O_RDWR) lfs_flags |= LFS_O_RDWR;
if (m & O_EXCL) lfs_flags |= LFS_O_EXCL;
if (m & O_CREAT) lfs_flags |= LFS_O_CREAT;
if (m & O_TRUNC) lfs_flags |= LFS_O_TRUNC;
if (m == O_APPEND) {ESP_LOGV(TAG, "O_APPEND"); lfs_flags |= LFS_O_APPEND;}
if (m == O_RDONLY) {ESP_LOGV(TAG, "O_RDONLY"); lfs_flags |= LFS_O_RDONLY;}
if (m & O_WRONLY) {ESP_LOGV(TAG, "O_WRONLY"); lfs_flags |= LFS_O_WRONLY;}
if (m & O_RDWR) {ESP_LOGV(TAG, "O_RDWR"); lfs_flags |= LFS_O_RDWR;}
if (m & O_EXCL) {ESP_LOGV(TAG, "O_EXCL"); lfs_flags |= LFS_O_EXCL;}
if (m & O_CREAT) {ESP_LOGV(TAG, "O_CREAT"); lfs_flags |= LFS_O_CREAT;}
if (m & O_TRUNC) {ESP_LOGV(TAG, "O_TRUNC"); lfs_flags |= LFS_O_TRUNC;}
return lfs_flags;
}
@@ -475,7 +488,8 @@ static int esp_littlefs_flags_conv(int m) {
* @param[in] conf Filesystem Configuration
* @return ESP_OK on success
*/
static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t *conf) {
static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t* conf)
{
int index = -1;
esp_err_t err = ESP_FAIL;
const esp_partition_t* partition = NULL;
@@ -533,14 +547,6 @@ static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t *conf) {
goto exit;
}
if (partition->encrypted) {
// TODO: allow encryption; should probably be fine,
// just not allowing until tested.
ESP_LOGE(TAG, "littlefs can not run on encrypted partition");
err = ESP_ERR_INVALID_STATE;
goto exit;
}
/* Allocate Context */
efs = calloc(1, sizeof(esp_littlefs_t));
if (efs == NULL) {
@@ -562,8 +568,7 @@ static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t *conf) {
// block device configuration
efs->cfg.read_size = CONFIG_LITTLEFS_READ_SIZE;
efs->cfg.prog_size = CONFIG_LITTLEFS_WRITE_SIZE;
efs->cfg.block_size = CONFIG_LITTLEFS_BLOCK_SIZE;
;
efs->cfg.block_size = CONFIG_LITTLEFS_BLOCK_SIZE;;
efs->cfg.block_count = efs->partition->size / efs->cfg.block_size;
efs->cfg.cache_size = CONFIG_LITTLEFS_CACHE_SIZE;
efs->cfg.lookahead_size = CONFIG_LITTLEFS_LOOKAHEAD_SIZE;
@@ -615,7 +620,8 @@ exit:
if(err != ESP_OK){
if( index >= 0 ) {
esp_littlefs_free(&_efs[index]);
} else {
}
else{
esp_littlefs_free(&efs);
}
}
@@ -629,12 +635,12 @@ exit:
*/
static inline int sem_take(esp_littlefs_t *efs) {
int res;
#if LOG_LOCAL_LEVEL >= 4
ESP_LOGD(TAG, "------------------------ Sem Taking [%s]", pcTaskGetTaskName(NULL));
#if LOG_LOCAL_LEVEL >= 5
ESP_LOGV(TAG, "------------------------ Sem Taking [%s]", pcTaskGetTaskName(NULL));
#endif
res = xSemaphoreTakeRecursive(efs->lock, portMAX_DELAY);
#if LOG_LOCAL_LEVEL >= 4
ESP_LOGD(TAG, "--------------------->>> Sem Taken [%s]", pcTaskGetTaskName(NULL));
#if LOG_LOCAL_LEVEL >= 5
ESP_LOGV(TAG, "--------------------->>> Sem Taken [%s]", pcTaskGetTaskName(NULL));
#endif
return res;
}
@@ -644,12 +650,13 @@ static inline int sem_take(esp_littlefs_t *efs) {
* @parameter efs file system context
*/
static inline int sem_give(esp_littlefs_t *efs) {
#if LOG_LOCAL_LEVEL >= 4
ESP_LOGD(TAG, "---------------------<<< Sem Give [%s]", pcTaskGetTaskName(NULL));
#if LOG_LOCAL_LEVEL >= 5
ESP_LOGV(TAG, "---------------------<<< Sem Give [%s]", pcTaskGetTaskName(NULL));
#endif
return xSemaphoreGiveRecursive(efs->lock);
}
/* We are using a double allocation system here, which an array and a linked list.
The array contains the pointer to the file descriptor (the index in the array is what's returned to the user).
The linked list is used for file descriptors.
@@ -674,10 +681,10 @@ static inline int sem_give(esp_littlefs_t *efs) {
*/
static int esp_littlefs_allocate_fd(esp_littlefs_t *efs, vfs_littlefs_file_t ** file
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
,
const size_t path_len
, const size_t path_len
#endif
) {
)
{
int i = -1;
assert( efs->fd_count < UINT16_MAX );
@@ -698,6 +705,7 @@ static int esp_littlefs_allocate_fd(esp_littlefs_t *efs, vfs_littlefs_file_t **f
efs->cache_size = new_size;
}
/* Allocate file descriptor here now */
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
*file = calloc(1, sizeof(**file) + path_len);
@@ -773,7 +781,7 @@ static int esp_littlefs_free_fd(esp_littlefs_t *efs, int fd) {
efs->cache[fd] = NULL;
efs->fd_count--;
ESP_LOGD(TAG, "Clearing FD");
ESP_LOGV(TAG, "Clearing FD");
free(file);
#if 0
@@ -797,7 +805,7 @@ static int esp_littlefs_free_fd(esp_littlefs_t *efs, int fd) {
if(n_free >= (efs->cache_size - new_size)){
new_size += CONFIG_LITTLEFS_FD_CACHE_HYST;
ESP_LOGD(TAG, "Reallocating cache %i -> %i", efs->cache_size, new_size);
ESP_LOGV(TAG, "Reallocating cache %i -> %i", efs->cache_size, new_size);
vfs_littlefs_file_t ** new_cache;
new_cache = realloc(efs->cache, new_size * sizeof(*efs->cache));
/* No harm on realloc failure, continue using the oversized cache */
@@ -849,12 +857,12 @@ static int esp_littlefs_get_fd_by_name(esp_littlefs_t *efs, const char *path) {
&& strcmp(path, efs->cache[i]->path) == 0 // May as well check incase of hash collision. Usually short-circuited.
#endif
) {
ESP_LOGD(TAG, "Found \"%s\" at FD %d.", path, i);
ESP_LOGV(TAG, "Found \"%s\" at FD %d.", path, i);
return i;
}
}
}
ESP_LOGD(TAG, "Unable to get a find FD for \"%s\"", path);
ESP_LOGV(TAG, "Unable to get a find FD for \"%s\"", path);
return -1;
}
@@ -870,7 +878,7 @@ static int vfs_littlefs_open(void *ctx, const char *path, int flags, int mode) {
#endif
assert(path);
ESP_LOGD(TAG, "Opening %s", path);
ESP_LOGV(TAG, "Opening %s", path);
/* Convert flags to lfs flags */
lfs_flags = esp_littlefs_flags_conv(flags);
@@ -879,22 +887,23 @@ static int vfs_littlefs_open(void *ctx, const char *path, int flags, int mode) {
sem_take(efs);
fd = esp_littlefs_allocate_fd(efs, &file
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
,
path_len
, path_len
#endif
);
if(fd < 0) {
errno = -fd;
sem_give(efs);
ESP_LOGE(TAG, "Error obtaining FD");
ESP_LOGV(TAG, "Error obtaining FD");
return LFS_ERR_INVAL;
}
/* Open File */
res = lfs_file_open(efs->fs, &file->file, path, lfs_flags);
if( res < 0 ) {
errno = -res;
esp_littlefs_free_fd(efs, fd);
sem_give(efs);
ESP_LOGE(TAG, "Failed to open file. Error %s (%d)",
ESP_LOGV(TAG, "Failed to open file. Error %s (%d)",
esp_littlefs_errno(res), res);
return LFS_ERR_INVAL;
}
@@ -905,14 +914,14 @@ static int vfs_littlefs_open(void *ctx, const char *path, int flags, int mode) {
#endif
#if CONFIG_LITTLEFS_USE_MTIME
if (!(lfs_flags & LFS_O_RDONLY)) {
if (lfs_flags != LFS_O_RDONLY) {
/* If this is being opened as not read-only */
vfs_littlefs_update_mtime(efs, path);
}
#endif
sem_give(efs);
ESP_LOGD(TAG, "Done opening %s", path);
ESP_LOGV(TAG, "Done opening %s", path);
return fd;
}
@@ -932,11 +941,12 @@ static ssize_t vfs_littlefs_write(void *ctx, int fd, const void *data, size_t si
sem_give(efs);
if(res < 0){
errno = -res;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to write FD %d; path \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to write FD %d; path \"%s\". Error %s (%d)",
fd, file->path, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to write FD %d. Error %s (%d)",
ESP_LOGV(TAG, "Failed to write FD %d. Error %s (%d)",
fd, esp_littlefs_errno(res), res);
#endif
return res;
@@ -950,6 +960,7 @@ static ssize_t vfs_littlefs_read(void *ctx, int fd, void *dst, size_t size) {
ssize_t res;
vfs_littlefs_file_t *file = NULL;
sem_take(efs);
if((uint32_t)fd > efs->cache_size) {
sem_give(efs);
@@ -961,11 +972,12 @@ static ssize_t vfs_littlefs_read(void *ctx, int fd, void *dst, size_t size) {
sem_give(efs);
if(res < 0){
errno = -res;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to read file \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to read file \"%s\". Error %s (%d)",
file->path, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to read FD %d. Error %s (%d)",
ESP_LOGV(TAG, "Failed to read FD %d. Error %s (%d)",
fd, esp_littlefs_errno(res), res);
#endif
return res;
@@ -989,12 +1001,13 @@ static int vfs_littlefs_close(void *ctx, int fd) {
file = efs->cache[fd];
res = lfs_file_close(efs->fs, &file->file);
if(res < 0){
errno = -res;
sem_give(efs);
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to close file \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to close file \"%s\". Error %s (%d)",
file->path, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to close Fd %d. Error %s (%d)",
ESP_LOGV(TAG, "Failed to close Fd %d. Error %s (%d)",
fd, esp_littlefs_errno(res), res);
#endif
return res;
@@ -1011,15 +1024,9 @@ static off_t vfs_littlefs_lseek(void *ctx, int fd, off_t offset, int mode) {
int whence;
switch (mode) {
case SEEK_SET:
whence = LFS_SEEK_SET;
break;
case SEEK_CUR:
whence = LFS_SEEK_CUR;
break;
case SEEK_END:
whence = LFS_SEEK_END;
break;
case SEEK_SET: whence = LFS_SEEK_SET; break;
case SEEK_CUR: whence = LFS_SEEK_CUR; break;
case SEEK_END: whence = LFS_SEEK_END; break;
default:
ESP_LOGE(TAG, "Invalid mode");
return -1;
@@ -1036,11 +1043,12 @@ static off_t vfs_littlefs_lseek(void *ctx, int fd, off_t offset, int mode) {
sem_give(efs);
if(res < 0){
errno = -res;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to seek file \"%s\" to offset %08x. Error %s (%d)",
ESP_LOGV(TAG, "Failed to seek file \"%s\" to offset %08x. Error %s (%d)",
file->path, (unsigned int)offset, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to seek FD %d to offset %08x. Error (%d)",
ESP_LOGV(TAG, "Failed to seek FD %d to offset %08x. Error (%d)",
fd, (unsigned int)offset, res);
#endif
return res;
@@ -1049,11 +1057,13 @@ static off_t vfs_littlefs_lseek(void *ctx, int fd, off_t offset, int mode) {
return res;
}
static int vfs_littlefs_fsync(void *ctx, int fd) {
static int vfs_littlefs_fsync(void* ctx, int fd)
{
esp_littlefs_t * efs = (esp_littlefs_t *)ctx;
ssize_t res;
vfs_littlefs_file_t *file = NULL;
sem_take(efs);
if((uint32_t)fd > efs->cache_size) {
sem_give(efs);
@@ -1065,11 +1075,12 @@ static int vfs_littlefs_fsync(void *ctx, int fd) {
sem_give(efs);
if(res < 0){
errno = -res;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to sync file \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to sync file \"%s\". Error %s (%d)",
file->path, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to sync file %d. Error %d", fd, res);
ESP_LOGV(TAG, "Failed to sync file %d. Error %d", fd, res);
#endif
return res;
}
@@ -1077,6 +1088,7 @@ static int vfs_littlefs_fsync(void *ctx, int fd) {
return res;
}
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
static int vfs_littlefs_fstat(void* ctx, int fd, struct stat * st) {
esp_littlefs_t * efs = (esp_littlefs_t *)ctx;
@@ -1096,8 +1108,9 @@ static int vfs_littlefs_fstat(void *ctx, int fd, struct stat *st) {
file = efs->cache[fd];
res = lfs_stat(efs->fs, file->path, &info);
if (res < 0) {
errno = -res;
sem_give(efs);
ESP_LOGE(TAG, "Failed to stat file \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to stat file \"%s\". Error %s (%d)",
file->path, esp_littlefs_errno(res), res);
return res;
}
@@ -1126,10 +1139,11 @@ static int vfs_littlefs_stat(void *ctx, const char *path, struct stat *st) {
sem_take(efs);
res = lfs_stat(efs->fs, path, &info);
if (res < 0) {
errno = -res;
sem_give(efs);
/* Not strictly an error, since stat can be used to check
* if a file exists */
ESP_LOGI(TAG, "Failed to stat path \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to stat path \"%s\". Error %s (%d)",
path, esp_littlefs_errno(res), res);
return res;
}
@@ -1152,8 +1166,9 @@ static int vfs_littlefs_unlink(void *ctx, const char *path) {
sem_take(efs);
res = lfs_stat(efs->fs, path, &info);
if (res < 0) {
errno = -res;
sem_give(efs);
ESP_LOGE(TAG, fail_str_1 " Error %s (%d)",
ESP_LOGV(TAG, fail_str_1 " Error %s (%d)",
path, esp_littlefs_errno(res), res);
return res;
}
@@ -1164,16 +1179,17 @@ static int vfs_littlefs_unlink(void *ctx, const char *path) {
return -1;
}
if (info.type == LFS_TYPE_DIR) {
sem_give(efs);
ESP_LOGE(TAG, "Cannot unlink a directory.");
return LFS_ERR_ISDIR;
}
//if (info.type == LFS_TYPE_DIR) {
// sem_give(efs);
// ESP_LOGV(TAG, "Cannot unlink a directory.");
// return LFS_ERR_ISDIR;
//}
res = lfs_remove(efs->fs, path);
if (res < 0) {
errno = -res;
sem_give(efs);
ESP_LOGE(TAG, fail_str_1 " Error %s (%d)",
ESP_LOGV(TAG, fail_str_1 " Error %s (%d)",
path, esp_littlefs_errno(res), res);
return res;
}
@@ -1194,7 +1210,8 @@ static int vfs_littlefs_rename(void *ctx, const char *src, const char *dst) {
sem_give(efs);
ESP_LOGE(TAG, "Cannot rename; src \"%s\" is open.", src);
return -1;
} else if (esp_littlefs_get_fd_by_name(efs, dst) >= 0) {
}
else if(esp_littlefs_get_fd_by_name(efs, dst) >= 0){
sem_give(efs);
ESP_LOGE(TAG, "Cannot rename; dst \"%s\" is open.", dst);
return -1;
@@ -1203,7 +1220,8 @@ static int vfs_littlefs_rename(void *ctx, const char *src, const char *dst) {
res = lfs_rename(efs->fs, src, dst);
sem_give(efs);
if (res < 0) {
ESP_LOGE(TAG, "Failed to rename \"%s\" -> \"%s\". Error %s (%d)",
errno = -res;
ESP_LOGV(TAG, "Failed to rename \"%s\" -> \"%s\". Error %s (%d)",
src, dst, esp_littlefs_errno(res), res);
return res;
}
@@ -1232,11 +1250,12 @@ static DIR *vfs_littlefs_opendir(void *ctx, const char *name) {
res = lfs_dir_open(efs->fs, &dir->d, dir->path);
sem_give(efs);
if (res < 0) {
errno = -res;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to opendir \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to opendir \"%s\". Error %s (%d)",
dir->path, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to opendir \"%s\". Error %d", dir->path, res);
ESP_LOGV(TAG, "Failed to opendir \"%s\". Error %d", dir->path, res);
#endif
goto exit;
}
@@ -1258,11 +1277,12 @@ static int vfs_littlefs_closedir(void *ctx, DIR *pdir) {
res = lfs_dir_close(efs->fs, &dir->d);
sem_give(efs);
if (res < 0) {
errno = -res;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to closedir \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to closedir \"%s\". Error %s (%d)",
dir->path, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to closedir \"%s\". Error %d", dir->path, res);
ESP_LOGV(TAG, "Failed to closedir \"%s\". Error %d", dir->path, res);
#endif
return res;
}
@@ -1296,27 +1316,30 @@ static int vfs_littlefs_readdir_r(void *ctx, DIR *pdir,
}while( res>0 && (strcmp(info.name, ".") == 0 || strcmp(info.name, "..") == 0));
sem_give(efs);
if (res < 0) {
errno = -res;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGE(TAG, "Failed to readdir \"%s\". Error %s (%d)",
ESP_LOGV(TAG, "Failed to readdir \"%s\". Error %s (%d)",
dir->path, esp_littlefs_errno(res), res);
#else
ESP_LOGE(TAG, "Failed to readdir \"%s\". Error %d", dir->path, res);
ESP_LOGV(TAG, "Failed to readdir \"%s\". Error %d", dir->path, res);
#endif
return -1;
}
if(info.type == LFS_TYPE_REG) {
ESP_LOGD(TAG, "readdir a file of size %d named \"%s\"",
ESP_LOGV(TAG, "readdir a file of size %d named \"%s\"",
info.size, info.name);
} else {
ESP_LOGD(TAG, "readdir a dir named \"%s\"", info.name);
}
else {
ESP_LOGV(TAG, "readdir a dir named \"%s\"", info.name);
}
if(res == 0) {
/* End of Objs */
ESP_LOGD(TAG, "Reached the end of the directory.");
ESP_LOGV(TAG, "Reached the end of the directory.");
*out_dirent = NULL;
} else {
}
else {
entry->d_ino = 0;
entry->d_type = info.type == LFS_TYPE_REG ? DT_REG : DT_DIR;
strncpy(entry->d_name, info.name, sizeof(entry->d_name));
@@ -1345,7 +1368,8 @@ static void vfs_littlefs_seekdir(void *ctx, DIR *pdir, long offset) {
res = lfs_dir_rewind(efs->fs, &dir->d);
sem_give(efs);
if (res < 0) {
ESP_LOGE(TAG, "Failed to rewind dir \"%s\". Error %s (%d)",
errno = -res;
ESP_LOGV(TAG, "Failed to rewind dir \"%s\". Error %s (%d)",
dir->path, esp_littlefs_errno(res), res);
return;
}
@@ -1366,13 +1390,14 @@ static int vfs_littlefs_mkdir(void *ctx, const char *name, mode_t mode) {
/* Note: mode is currently unused */
esp_littlefs_t * efs = (esp_littlefs_t *)ctx;
int res;
ESP_LOGD(TAG, "mkdir \"%s\"", name);
ESP_LOGV(TAG, "mkdir \"%s\"", name);
sem_take(efs);
res = lfs_mkdir(efs->fs, name);
sem_give(efs);
if (res < 0) {
ESP_LOGE(TAG, "Failed to mkdir \"%s\". Error %s (%d)",
errno = -res;
ESP_LOGV(TAG, "Failed to mkdir \"%s\". Error %s (%d)",
name, esp_littlefs_errno(res), res);
return res;
}
@@ -1388,14 +1413,15 @@ static int vfs_littlefs_rmdir(void *ctx, const char *name) {
sem_take(efs);
res = lfs_stat(efs->fs, name, &info);
if (res < 0) {
errno = -res;
sem_give(efs);
ESP_LOGE(TAG, "\"%s\" doesn't exist.", name);
ESP_LOGV(TAG, "\"%s\" doesn't exist.", name);
return -1;
}
if (info.type != LFS_TYPE_DIR) {
sem_give(efs);
ESP_LOGE(TAG, "\"%s\" is not a directory.", name);
ESP_LOGV(TAG, "\"%s\" is not a directory.", name);
return -1;
}
@@ -1403,7 +1429,8 @@ static int vfs_littlefs_rmdir(void *ctx, const char *name) {
res = lfs_remove(efs->fs, name);
sem_give(efs);
if ( res < 0) {
ESP_LOGE(TAG, "Failed to unlink path \"%s\". Error %s (%d)",
errno = -res;
ESP_LOGV(TAG, "Failed to unlink path \"%s\". Error %s (%d)",
name, esp_littlefs_errno(res), res);
return -1;
}
@@ -1415,12 +1442,14 @@ static int vfs_littlefs_rmdir(void *ctx, const char *name) {
/**
* Sets the mtime attr to t.
*/
static int vfs_littlefs_update_mtime_value(esp_littlefs_t *efs, const char *path, time_t t) {
static int vfs_littlefs_update_mtime_value(esp_littlefs_t *efs, const char *path, time_t t)
{
int res;
res = lfs_setattr(efs->fs, path, LITTLEFS_ATTR_MTIME,
&t, sizeof(t));
if( res < 0 ) {
ESP_LOGE(TAG, "Failed to update mtime (%d)", res);
errno = -res;
ESP_LOGV(TAG, "Failed to update mtime (%d)", res);
}
return res;
@@ -1429,11 +1458,14 @@ static int vfs_littlefs_update_mtime_value(esp_littlefs_t *efs, const char *path
/**
* Sets the mtime attr to an appropriate value
*/
static void vfs_littlefs_update_mtime(esp_littlefs_t *efs, const char *path) {
static void vfs_littlefs_update_mtime(esp_littlefs_t *efs, const char *path)
{
vfs_littlefs_utime(efs, path, NULL);
}
static int vfs_littlefs_utime(void *ctx, const char *path, const struct utimbuf *times) {
static int vfs_littlefs_utime(void *ctx, const char *path, const struct utimbuf *times)
{
esp_littlefs_t * efs = (esp_littlefs_t *)ctx;
time_t t;
@@ -1448,10 +1480,8 @@ static int vfs_littlefs_utime(void *ctx, const char *path, const struct utimbuf
#elif CONFIG_LITTLEFS_MTIME_USE_NONCE
assert( sizeof(time_t) == 4 );
t = vfs_littlefs_get_mtime(efs, path);
if (0 == t)
t = esp_random();
else
t += 1;
if( 0 == t ) t = esp_random();
else t += 1;
if( 0 == t ) t = 1;
#else
@@ -1463,17 +1493,19 @@ static int vfs_littlefs_utime(void *ctx, const char *path, const struct utimbuf
return ret;
}
static time_t vfs_littlefs_get_mtime(esp_littlefs_t *efs, const char *path) {
static time_t vfs_littlefs_get_mtime(esp_littlefs_t *efs, const char *path)
{
time_t t = 0;
int size;
size = lfs_getattr(efs->fs, path, LITTLEFS_ATTR_MTIME,
&t, sizeof(t));
if( size < 0 ) {
errno = -size;
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
ESP_LOGI(TAG, "Failed to get mtime attribute %s (%d)",
ESP_LOGV(TAG, "Failed to get mtime attribute %s (%d)",
esp_littlefs_errno(size), size);
#else
ESP_LOGI(TAG, "Failed to get mtime attribute %d", size);
ESP_LOGV(TAG, "Failed to get mtime attribute %d", size);
#endif
}
return t;

View File

@@ -13,22 +13,27 @@
#include <sys/reent.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/termios.h>
//#include <sys/termios.h>
#include <sys/poll.h>
#include <dirent.h>
#include <string.h>
#include "sdkconfig.h"
#include "lfs.h"
#include "lfs.h" //#include "littlefs/lfs.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
LITTLEFS_ATTR_MTIME, /**< Last Modified - time (seconds) */
LITTLEFS_ATTR_MAX
};
/**
* @brief Last Modified Time
*
* Use 't' for LITTLEFS_ATTR_MTIME to match example:
* https://github.com/ARMmbed/littlefs/issues/23#issuecomment-482293539
* And to match other external tools such as:
* https://github.com/earlephilhower/mklittlefs
*/
#define LITTLEFS_ATTR_MTIME ((uint8_t) 't')
/**
*Configuration structure for esp_vfs_littlefs_register.

View File

@@ -2,6 +2,11 @@
* @file littlefs_api.c
* @brief Maps the HAL of esp_partition <-> littlefs
* @author Brian Pugh
*
* Copyright 2020 Brian Pugh
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define ESP_LOCAL_LOG_LEVEL ESP_LOG_INFO