WeMos D1 mini (esp8266): FileSystem integrato LittleFS – Parte 5
LittleFS File System
SPIFFS è il filesystem originale ed è ideale per applicazioni con limitazioni di spazio e RAM che utilizzano molti piccoli file e si preoccupano del livellamento statico e dinamico del FS determinato dall’utilizzo e non necessitano di un vero supporto alle directory. Anche l’overhead del filesystem sul flash è minimo.
Ma con l’introduzione del nuovo LittleFS, SPIFFS diventa deprecato.
LittleFS è stato recentemente aggiunto e si concentra su prestazioni più elevate e supporto alle directory , ma ha una maggiore consumo di risorse e occupazione per file (minimo 4K rispetto all’unità di allocazione minima di 256 byte di SPIFFS).
L’implementazione del LittleFS per ESP8266 supporta nomi di file con un massimo di 31 caratteri + zero di terminazione (ovvero char filename[32]
) e tante sottodirectory quanto lo consente lo spazio.
A differenza di SPIFFS, i descrittori di file effettivi vengono allocati come richiesto dall’applicazione, quindi in condizioni di memoria insufficiente potrebbe non essere possibile aprire nuovi file. Al contrario, ciò significa anche che i descrittori di file utilizzati occuperanno effettivamente spazio sull’heap.
Poiché esistono directory, il metodo openDir
si comporta in modo diverso rispetto a SPIFFS. Mentre SPIFFS restituirà i file con le relative “sottodirectory” quando si attraversa con Dir::next()
(perché in realtà non sono sottodirectory ma semplicemente file con la “/” nei loro nomi), LittleFS restituirà il solo file nella sottodirectory specifica. Questo imita il comportamento POSIX per l’attraversamento delle directory a cui è abituata la maggior parte dei programmatori C.
Il WeMos D1 mini ha 4 Mb di flash e ne puoi utilizzare fino a 3 per i tuoi files.
In questa memoria flash l’ESP memorizza il programma. Insieme al programma è possibile memorizzare i nostri file. Il limite di questa memoria è che ha solo 10000 (diecimila) cicli di scrittura.
Aggiungere file dall’IDE Arduino su LittleFS
Questa operazione senza estensione per l’IDE di Arduino non è così semplice, ma qui andremo a vedere il modo più semplice.
Per prima cosa devi scaricare il plug-in per l’Arduino IDE qui.
Quindi devi trovare la tua cartella dei Shetckbook, se non sai dove è dislocata puoi andare su File --> Preferences
, in quella schermata puoi trovare nella parte superiore della finestra lo Sketchbook location
.
Ora devi creare (se non esiste) la cartella
aggiungere lì il file jar tools/ESP8266LittleFS/tool
eesp8266littlefs.jar
.
Ora riavvia l’IDE e nel menu Tools
troverai una nuova riga ESP8266 LittleFS Data Upload
.
Sull’Arduino IDE fai Ctrl+K
per aprire un Esplora risorse nella directory dello sketch.
Crea una directory denominata data
dove andrai ad inserire i dati che desideri caricare.
Imposta la dimensione dello LittleFS Tools --> Flash size
e imposta la dimensione del filesystem.
Carica il tuo sketch e fai clic su ESP8266 LittleFS Data Upload
.
Ora vai allo sketch di esempio per verificare se tutto è OK.
Comandi
Ci sono alcuni comandi standard che puoi usare con questo filesystem
LittleFS.begin ()
Questo metodo monta il file system LittleFS e deve essere chiamato prima di utilizzare qualsiasi altra API FS. Restituisce vero se il file system è stato montato correttamente, altrimenti falso.
LittleFS.format ()
Formatta il file system. Restituisce vero se la formattazione ha avuto esito positivo.
LittleFS.open (percorso, modalità)
Apre un file. il percorso dovrebbe essere un percorso assoluto che inizia con una barra (ad es. /dir/filename.txt). modalità
è una stringa che specifica la modalità di accesso. Può essere uno di “r”, “w”, “a”, “r +”, “w +”, “a +”. Il significato di queste modalità è lo stesso della funzione C fopen.
Restituisce l’oggetto File. Per verificare se il file è stato aperto correttamente, utilizzare l’operatore booleano.
LittleFS.exists (percorso)
Restituisce vero se esiste un file con un determinato percorso
, altrimenti falso.
LittleFS.openDir (percorso)
Apre una directory dato il suo percorso
assoluto. Restituisce un oggetto Dir.
LittleFS.remove (percorso)
elimina un file dato il suo percorso
assoluto. Restituisce vero se il file è stato eliminato correttamente.
LittleFS.rename (pathFrom, pathTo)
Rinomina il file da pathFrom
a pathTo
. I percorsi devono essere assoluti. Restituisce vero se il file è stato rinominato correttamente.
LittleFS.info (fs_info)
Riempie la struttura di FSInfo
con informazioni sul file system. Restituisce vero ha esito positivo, altrimenti falso.
file.seek (offset, mode)
Questa funzione si comporta come la funzione fseek C. A seconda del valore della modalità, sposta la posizione corrente in un file come segue:
- se mode è SeekSet, la posizione è impostata per compensare i byte dall’inizio.
- se mode è SeekCur, la posizione corrente viene spostata di byte offset.
- se mode è SeekEnd, position è impostato per compensare i byte dalla fine del file.
- Restituisce vero se la posizione è stata impostata correttamente.
file.position ()
Restituisce la posizione corrente all’interno del file, in byte.
file.size ()
Restituisce la dimensione del file, in byte.
file.name ()
Restituisce il nome del file, come const char *.
file.close ()
Chiude il file.
dir.next ()
Restituisce true se ci sono file nella directory su cui si sta ciclando. Deve essere chiamato prima delle funzioni fileName()
, fileSize()
e openFile()
.
dir.fileName ()
Restituisce il nome del file corrente a cui punta l’iteratore interno.
dir.fileSize ()
Restituisce la dimensione del file corrente a cui punta l’iteratore interno.
dir.fileTime ()
Restituisce il tempo di scrittura time_t del file a cui punta l’iteratore interno.
dir.fileCreationTime ()
Restituisce l’ora di creazione time_t del file corrente a cui punta l’iteratore interno.
dir.isFile ()
Restituisce true se il file corrente indicato dall’iteratore è un file.
dir.isDirectory ()
Restituisce true se il file corrente indicato dall’iteratore interno è una directory.
dir.openFile (mode)
Questo metodo accetta l’argomento mode che ha lo stesso significato della funzione LittleFS.open()
.
dir.rewind ()
Reimposta il puntatore interno all’inizio della directory.
Esempi pratici
Ecco uno sketch per ottenere informazioni e controllare tutti i file nel tuo LittleFS.
/*
* WeMos D1 mini (esp8266)
* LittleFS get info, read dir and show all file uploaded
* add a data folder to use with esp8266 data uploader
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org/
*
*/
#include "Arduino.h"
#include "LittleFS.h"
void setup()
{
Serial.begin(112500);
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
FSInfo fs_info;
LittleFS.info(fs_info);
Serial.println("File sistem info.");
Serial.print("Total space: ");
Serial.print(fs_info.totalBytes);
Serial.println("byte");
Serial.print("Total space used: ");
Serial.print(fs_info.usedBytes);
Serial.println("byte");
Serial.print("Block size: ");
Serial.print(fs_info.blockSize);
Serial.println("byte");
Serial.print("Page size: ");
Serial.print(fs_info.totalBytes);
Serial.println("byte");
Serial.print("Max open files: ");
Serial.println(fs_info.maxOpenFiles);
Serial.print("Max path length: ");
Serial.println(fs_info.maxPathLength);
Serial.println();
// Open dir folder
Dir dir = LittleFS.openDir("/");
// Cycle all the content
while (dir.next()) {
// get filename
Serial.print(dir.fileName());
Serial.print(" - ");
// If element have a size display It else write 0
if(dir.fileSize()) {
File f = dir.openFile("r");
Serial.println(f.size());
f.close();
}else{
Serial.println("0");
}
}
}
void loop()
{
}
Ecco il risultato della richiesta
Inizializing FS...
done.
File sistem info.
Total space: 2072576byte
Total space used: 73728byte
Block size: 8192byte
Page size: 2072576byte
Max open files: 5
Max path length: 32
logo.jpg - 46136
provaTXT.txt - 4416
Qui uno sketch con comandi più pratici, scrivi una stringa in un file, leggi tutto il contenuto del file, posizionati sul 9 byte del file e leggi da lì i dati.
/*
* WeMos D1 mini (esp8266)
* 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(112500);
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()
{
}
Ed ecco il risultato
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!!
Grazie
- WeMos D1 mini (esp8266): caratteristiche e configurazione dell’Arduino IDE
- WeMos D1 mini (esp8266): SPIFFS Filesystem integrato
- WeMos D1 mini (esp8266): debug sulla seriale secondaria
- WeMos D1 mini (esp8266), i tre tipi di modalità di sospensione per gestire il risparmio energetico
- WeMos D1 mini (esp8266): FileSystem integrato LittleFS
- esp12 esp07 (esp8266): flash, piedinatura, spec e config dell’IDE Arduino
- Firmware and OTA update
- Gestione del firmware
- Aggiornamenti OTA con Arduino IDE
- Aggiornamenti OTA con Web Browser
- Aggiornamenti OTA automatico da server HTTP
- Aggiornamenti firmware non standard
- esp32 e esp8266: file system FAT su memoria SPI flash esterna
- i2c esp8266: how to, rete 5V, 3.3V, velocità e pin personalizzati
- …
Ciao,
seguendo i tuoi articoli ho fatto un’applicazione su lolin wemos d1 (client in javascript che dialoga he scambia dati in json con web server) utilizzando anche libreria Little FS. Mi capita che dopo 8-9 mesi di corretto funzionamento H24 su un 10% dei wemos ad un certo punto l’applicazione non funziona più e perde le configurazioni scritte su file system. A quel punto devo flashare nuovamente il firmware e tutto riparte correttamente. Secondo te cosa potrebbe essere? se fosse solo un problema di memoria le impostazioni scritte su FS non dovrebbero essere impattate..
Grazie anticipatamente
Ciao Marco,
sarebbe utile che aprissi un topic sul forum con allegato il codice sorgente.
Ma da come mi hai scritto sembrerebbe che il file dovrebbero troppo grande o la memoria ridotta rispetto all’inizio e al momento di scrivere si corrompe il file.
Ciao Renzo