ESP32: integrated LittleFS FileSystem – 5
We continue to explore e32 devices, very powerful microcontrollers. The possibilities offered by the integrated Flash SPI are many, but the first problem is choosing an adequate filesystem; each has characteristics that make them unique and valuable in various aspects. After the SPIFFS, lighter and low resource filesystem (with many limitations), we will see the LittleFS as a good compromise between functionality and performance.
You can find It here ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S
LittleFS File System
SPIFFS is the original filesystem and is ideal for space and RAM-constrained applications that utilize many small files, care about static and dynamic wear-leveling and don’t need true directory support. Filesystem overhead on the flash is minimal as well.
LittleFS is recently added and focuses on higher performance and directory support but has higher filesystem and per-file overhead (4K minimum vs. SPIFFS’ 256-byte minimum file allocation unit).
The LittleFS implementation for the ESP8266 supports filenames of up to 31 characters + terminating zero (i.e. char filename[32]
) and as many subdirectories as space permits.
Unlike SPIFFS, the actual file descriptors are allocated as requested by the application, so you may not be able to open new files in low memory conditions. Conversely, this also means that only file descriptors used will take space on the heap.
Although not by default for esp32, it should be mentioned that it is speedy and takes up much fewer resources than FatFS, which will be set as the default of esp32.
Because there are directories, the open
method behaves differently than SPIFFS. Whereas SPIFFS will return files in “subdirectories” when you traverse a File::openNextFile()
(because they aren’t subdirs but files with “/”s in their names), LittleFS will only return files in the specified subdirectory. This mimics the POSIX behavior for directory traversal most C programmers are used to.
In this flash memory, ESP stores the program. Along with the program, you can store your files on it. The limitation of this memory is it has only 10000 (ten thousand) write cycles.
Add files from IDE to LittleFS
This operation without an extension for the Arduino IDE is not so simple, but here we will explain the most straightforward way.
First, you must download the plugin for Arduino IDE here.
Then you must find your Shetckbook folder, so you must go to file –> Preferences; in that screen, you can find at the top of the window the Sketchbook location
.
Now you must create (if not exist) the folder tools\ESP32FS\tool
and add the jar file esp32fs.jar
there.
Now restart the IDE and on Tools the
menu you can find new menu-line ESP32 Sketch Data Upload
.
This plugin was able to manage three types of the filesystem and can substitute the others (like SPIFFS); when you click on “ESP32 Sketch Data Upload,” a popup asks you what operation you can do
The partition table is the same as SPIFFS so that you can select the standard SPIFFS partition scheme.
Add mklittlefs file
If you have esp8266 core installed probably, you can already upload the file on the LittleFS partition.
If you can’t upload the data, you must add the mklittlefs.exe file to the relative folder.
You must download mklittlefs from GitHub. In my case, the version for Windows 10 64bit x86_64-w64-mingw32-mklittlefs-295fe9b.zip.
Then you must open the preferences folder
and the complete folder
<preferences folder>/packages/esp32/hardware/esp32/1.0.5/tools
where the 1.0.5 is the current version installed of esp32 core, then copy the file mklittlefs.exe in the same folder of espota
and esptool
.
Create data
folder
On Arduino IDE, do Ctrl+K to open a file browser on the sketch’s directory.
Create a directory data to put the data you want to upload.
Set the size of LittleFS on Tools --> Flash size
this is the size of your Microcontroller filesystem.
Upload your sketch, and then click on ESP32 Sketch Data Upload
.
Now go to the example sketch to check if all is OK.
Commands
There are some standard commands that you can use with this filesystem
LITTLEFS.begin()
This method mounts the LITTLEFS file system, and It must be called before any other FS APIs are used. Returns true if the file system was mounted successfully; false otherwise.
LITTLEFS.format()
Formats the file system. Returns true if the formatting was successful.
LITTLEFS.open(path, mode)
Opens a file. The path should be absolute, starting with a slash (e.g.,/dir/filename.txt). Mode is a string specifying access mode. It can be one of “r,” “w”, “a”. Meaning of these modes is the same as for fopen C function.
Returns File object. To check whether the file was opened successfully, use the boolean operator.
LITTLEFS.exists(path)
Returns true if a file with a given path exists; false otherwise.
LITTLEFS.remove(path): Deletes the file given its absolute path. Returns true if the file was deleted successfully.
LITTLEFS.rename(pathFrom, pathTo)
Renames file from pathFrom to pathTo. Returns true if the file was renamed successfully. Paths must be absolute.
LITTLEFS.mkdir(path):
Create a new folder. Returns true if the directory creation succeeded, false otherwise.
LITTLEFS.rmdir(path):
Remove directory. Returns true if the directory was successfully removed; false otherwise.
LITTLEFS.totalBytes()
Return the total bytes enabled on LITTLEFS. Returns bytes.
LITTLEFS.usedBytes()
Return the total used bytes enabled on LITTLEFS. Returns bytes.
file.seek(offset, mode)
This function behaves like fseek C function. Depending on the value of mode, it moves current position in a file as follows:
- if mode is SeekSet, position is set to offset bytes from the beginning.
- if mode is SeekCur, current position is moved by offset bytes.
- if mode is SeekEnd, position is set to offset bytes from the end of the file.
- Returns true if position was set successfully.
file.position()
Returns the current position inside the file, in bytes.
file.size()
Returns file size, in bytes.
file.name()
Returns file name, as const char*.
file.close()
Close the file.
file.getLastWrite()
Epoch time of last write (use internal time to manage date).
file.isDirectory()
Return if It’s directory
file.openNextFile()
Set next file pointer in the directory.
file.rewindDirectory()
Restart the pointer to the first file of the directory.
Library
From version 2.x.x of esp32 Arduino Core LittleFS was integrated inside the core, and It isn’t any more LITTLEFS but with canonical case format LittleFS.
You can find the library here.
To download.
Click the DOWNLOADS button in the top right corner rename the uncompressed folder LITTLEFS.
Place the LITTLEFS library folder in your /libraries/ folder.
You may need to create the libraries subfolder if it’s your first library.
Restart the IDE.
You can also download It from the library manager of Arduino
Pratical examples
Here is a sketch to get info and check all files in your LittleFS.
From version 2.x.x of esp32 Arduino Core LittleFS was integrated inside the core, and It isn’t any more LITTLEFS but with canonical case format LittleFS.
/*
* ESP32
* LITTLEFS get info, read dir and show all file uploaded
* add a data folder to use with ESP32 Sketch data uploader
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org
*
*/
#include "Arduino.h"
#include "FS.h"
#include "LITTLEFS.h"
void printDirectory(File dir, int numTabs = 3);
void setup()
{
Serial.begin(115200);
delay(500);
Serial.println(F("Inizializing FS..."));
if (LITTLEFS.begin()){
Serial.println(F("done."));
}else{
Serial.println(F("fail."));
}
// To format all space in LITTLEFS
// LITTLEFS.format()
// Get all information of your LITTLEFS
unsigned int totalBytes = LITTLEFS.totalBytes();
unsigned int usedBytes = LITTLEFS.usedBytes();
unsigned int freeBytes = LITTLEFS.freeBytes();
Serial.println("File sistem info.");
Serial.print("Total space: ");
Serial.print(totalBytes);
Serial.println("byte");
Serial.print("Total space used: ");
Serial.print(usedBytes);
Serial.println("byte");
Serial.print("Total space free: ");
Serial.print(freeBytes);
Serial.println("byte");
Serial.println();
// Open dir folder
File dir = LITTLEFS.open("/");
// Cycle all the content
printDirectory(dir);
}
void loop()
{
}
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
The result of the inquiry
Inizializing FS...
done.
File sistem info.
Total space: 1507328byte
Total space used: 53248byte
/bombo.png 44236
Here is a sketch with more valuable commands, write a string in a file, read all file content, position on the 9 bytes of the file, and read from there the data.
From version 2.x.x of esp32 Arduino Core LittleFS was integrated inside the core, and It isn’t any more LITTLEFS but with canonical case format LittleFS.
/*
* ESP32
* LITTLEFS write, read and seek file
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org/
*
*/
#include "Arduino.h"
#include "LITTLEFS.h"
void setup()
{
Serial.begin(115200);
delay(500);
Serial.println(F("Inizializing FS..."));
if (LITTLEFS.begin()){
Serial.println(F("done."));
}else{
Serial.println(F("fail."));
}
// To remove previous test
// LITTLEFS.remove(F("/testCreate.txt"));
File testFile = LITTLEFS.open(F("/testCreate.txt"), "w");
if (testFile){
Serial.println("Write file content!");
testFile.print("Here the test text!!");
testFile.close();
}else{
Serial.println("Problem on create file!");
}
testFile = LITTLEFS.open(F("/testCreate.txt"), "r");
if (testFile){
Serial.println("Read file content!");
/**
* File derivate from Stream so you can use all Stream method
* readBytes, findUntil, parseInt, println etc
*/
Serial.println(testFile.readString());
testFile.close();
}else{
Serial.println("Problem on read file!");
}
testFile = LITTLEFS.open(F("/testCreate.txt"), "r");
if (testFile){
/**
* mode is SeekSet, position is set to offset bytes from the beginning.
* mode is SeekCur, current position is moved by offset bytes.
* mode is SeekEnd, position is set to offset bytes from the end of the file.
* Returns true if position was set successfully.
*/
Serial.println("Position inside the file at 9 byte!");
testFile.seek(9, SeekSet);
Serial.println("Read file content!");
Serial.println(testFile.readString());
testFile.close();
}else{
Serial.println("Problem on read file!");
}
}
void loop()
{
}
Here is the result of the sketch.
Inizializing FS...
done.
Write file content!
Read file content!
Here the test text!!
Position inside the file at 9 byte!
Read file content!
test text!!
Thanks
- ESP32: pinout, specs and Arduino IDE configuration
- ESP32: integrated SPIFFS Filesystem
- ESP32: manage multiple Serial and logging
- ESP32 practical power saving
- ESP32 practical power saving: manage WiFi and CPU
- ESP32 practical power saving: modem and light sleep
- ESP32 practical power saving: deep sleep and hibernation
- ESP32 practical power saving: preserve data, timer and touch wake up
- ESP32 practical power saving: external and ULP wake up
- ESP32 practical power saving: UART and GPIO wake up
- ESP32: integrated LittleFS FileSystem
- ESP32: integrated FFat (Fat/exFAT) FileSystem
- ESP32-wroom-32
- ESP32-CAM
- ESP32: use ethernet w5500 with plain (HTTP) and SSL (HTTPS)
- ESP32: use ethernet enc28j60 with plain (HTTP) and SSL (HTTPS)
- How to use SD card with esp32
- esp32 and esp8266: FAT filesystem on external SPI flash memory
- Firmware and OTA update management
- Firmware management
- OTA update with Arduino IDE
- OTA update with Web Browser
- Self OTA uptate from HTTP server
- Non-standard Firmware update
- Integrating LAN8720 with ESP32 for Ethernet Connectivity with plain (HTTP) and SSL (HTTPS)
- Connecting the EByte E70 to ESP32 c3/s3 devices and a simple sketch example
- ESP32-C3: pinout, specs and Arduino IDE configuration
- Integrating W5500 with ESP32 Using Core 3: Native Ethernet Protocol Support with SSL and Other Features
- Integrating LAN8720 with ESP32 Using Core 3: Native Ethernet Protocol Support with SSL and Other Features
- Dallas ds18b20:
- Dallas ds18b20 with esp32 and esp8266: introduction and parasite mode
- Dallas ds18b20 with esp32 and esp8266: pull-up P-MOSFET gate and alarms
- Dallas ds18b20 with esp32 and esp8266: all OneWire topologies, long stubs and more devices
Hi,
Thank you! Really thorough and understandable overview.
Could you please explain also how to download a file from ESP32 LittleFS file system. Lets say I collect some sensor data (yes I know the 10000 write cycles limitation) into a text / csv file and want to download that file onto my PC.
Thank you beforehand,
Fred
Hi Fred,
in the past, I had the same problem, so I rewrite an FTP server that can be used for the major type of microcontroller.
FTP server on esp8266 and esp32
You can find It in the Arduino library manager also.
I think can be a good solution.
Bye Renzo
Fantastic! Renzo, thank you so much for your ultra quick reply.
I will download your library and give it a try.
Kind regards,
Fred