Hi Everybody,
I have a project in mind where I have to write sensor data into file in ESP32 flash memory (yes, I am aware of 10000 writes limit). As I understood SPIFFS is deprecated and LittleFS would be the way to go.
I decided to do a little speed test first. I uploaded the Arduino IDE ESP32 LITTLEFS_test.ino sketch onto the regular ESP32 Dev Module and added a couple of lines of code into loop to measure the append time of text "qwerty" to the file data.txt on ESP32 file system. I uploaded the file via ESP32 Sketch Data Upload tool with LittleFS, that seems to format the flash for using LittleFS.
To my great surprise the append function run time was 20-30ms in the beginning and when the data.txt file grew to a few hundred bytes it became 50-70ms. And there is very odd behavior - every 15th time the append operation takes 250-350ms. That does not depend on the append function call period. Extra long append time occurs every 15th time would the call period be 1, 2 or 3 seconds.
When I run the same script modified to use SPIFFS the append function run time is steady 5ms.
Would someone more knowledgeable on the subject explain me please what I am doing wrong. Or is the long append time problem with LITTLEFS and I should proceed with SPIFFS? Thank you in advance.
I add hereby also the shortened version of the LITTLEFS_test.ino sketch I used.
Compile environment:
Arduino IDE 1.8.19 on Win10 64bit
ESP32 systems version 2.0.2
The ESP32 board info:
Board: "ESP32 Dev Module"
Upload Speed: "921600"
CPU Frequency: "240MHz (WiFi/BT"
Flash Frequency: "80MHz"
Flash Mode: "QIO"
Flash Size: "4MB (32Mb)"
Partition Scheme: "No OTA (2MB APP 2MB SPIFFS)"
Core Debug Level: "None"
PSRAM: "Disabled"
Arduino Runs On: Core1
Events Run On: Core1
Port: "COM9"
#include "FS.h"
#include "LittleFS.h"
#define FORMAT_LITTLEFS_IF_FAILED true
unsigned long lastAppendMillis = 0; // append function call period, ms
unsigned long beginAppendMillis = 0; // append function start time, ms
unsigned long appendMillis = 0; // append function end time, ms
void setup(){
Serial.begin(115200);
if(!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
Serial.println("LittleFS Mount Failed");
return;
}
Serial.println("File system info:");
Serial.print(" Total space: ");
Serial.print(LittleFS.totalBytes());
Serial.println("byte");
Serial.print(" Total space used: ");
Serial.print(LittleFS.usedBytes());
Serial.println("byte");
Serial.println();
listDir(LittleFS, "/", 3);
}
void loop(){
if (millis() - lastAppendMillis > 1000) {
lastAppendMillis = millis();
Serial.println("###########################");
Serial.println("Append qwerty");
beginAppendMillis = millis();
appendFile(LittleFS, "/data.txt", "qwerty\r\n");
appendMillis = millis() - beginAppendMillis;
Serial.print("appendMillis = ");
Serial.print(appendMillis);
Serial.println(" ms");
}
}
// LittleFS functions
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 : ");
Serial.println(file.name());
if(levels){
listDir(fs, file.path(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print("\tSIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
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();
}