Continuiamo ad esplorare i dispositivi rp2040 dei microcontrollori molto interessanti. Tutte le schede prototipo vengono fornite con SPI Flash integrato. Raspberry Pi ha selezionato il filesystem LittleFS per gestire questo storage, un buon compromesso tra funzionalità e prestazioni.
Ecco la mia selezione di schede rp2040 Official Pi Pico - Official Pi Pico W - Waveshare rp2040-zero - WeAct Studio rp2040
File System LittleFS
LittleFS si concentra su prestazioni più elevate e supporto di directory e ha un file system con un ragionevole sovraccarico per file (unità di allocazione file minima 4K).
Aggiungere file dall’IDE a LittleFS
Questa operazione senza un’estensione per l’IDE Arduino non è così semplice, perciò andremo a spiegare questa modalità.
Innanzitutto, devi scaricare il plug-in per Arduino IDE qui .
Quindi devi trovare la tua cartella Shetckbook: devi andare su File -> Preferenze
; in quella schermata, puoi trovare nella parte superiore della finestra la Sketchbook location
.
Ora devi creare (se non esiste) la cartella tools/PicoLittleFS/tool
e aggiungere lì il file jar picolittlefs.jar
.
Ora riavvia l’IDE e nel menu Tools
puoi trovare una nuova riga di menu Pico LittleFS Data Upload
.
Creare la cartella data
Su Arduino IDE, fai Ctrl+K per aprire un browser di file nella directory dello sketch.
Crea una directory data
in cui inserire i dati che desideri caricare.
Imposta la dimensione del LittleFS su Tools --> Flash size
questa è la dimensione del tuo filesystem nel microcontrollore.
Carica il tuo sketch, quindi fai clic su Pico LittleFS Data Upload
.
Ora vai allo sketch di esempio per verificare se tutto è a posto.
Comandi
Ci sono alcuni comandi standard che puoi usare con questo filesystem
LittreFS.begin()
Questo metodo monta il file system LittreFS e deve essere chiamato prima di utilizzare qualsiasi altra API FS. Restituisce true se il file system è stato montato correttamente; falso altrimenti.
LittreFS.format()
Formatta il file system. Restituisce true se la formattazione è riuscita.
LittreFS.open(path, mode)
Apre un file. Il percorso dovrebbe essere assoluto, iniziando con una barra (ad esempio,/dir/nomefile.txt). Mode è una stringa che specifica la modalità di accesso. Può essere uno tra “r”, “w” e “a”. Il significato di queste modalità è lo stesso della funzione fopen C.
Restituisce l’oggetto File. Per verificare se il file è stato aperto correttamente, utilizzare l’operatore booleano.
LittreFS.exists(path)
Restituisce true se esiste un file con un determinato percorso; falso altrimenti.
LittreFS.remove(path): Elimina il file dato il suo percorso assoluto. Restituisce true se il file è stato eliminato correttamente.
LittleFS.rename(pathFrom, pathTo)
Rinomina il file da pathFrom a pathTo. Restituisce true se il file è stato rinominato correttamente. I percorsi devono essere assoluti.
LittreFS.mkdir(path):
Crea una nuova cartella. Restituisce true se la creazione della directory è riuscita, false contrario.
LittreFS.rmdir(path):
Rimuove la directory. Restituisce true se la directory è stata rimossa correttamente; falso altrimenti.
LittreFS.info()
Compila tutte le informazioni sul filesystem e devi passare una struttura FSInfo. Restituisce vero se è tutto ok.
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
file.seek(offset, mode)
Questa funzione si comporta come la funzione C fseek. A seconda del valore di mode, sposta la posizione corrente in un file come segue:
- se la modalità è SeekSet, la posizione è impostata per compensare i byte dall’inizio.
- se la modalità è SeekCur, la posizione corrente viene spostata di byte di offset.
- se la modalità è SeekEnd, la posizione è impostata per sfalsare i byte dalla fine del file.
- Restituisce true 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.
file.getLastWrite()
time_t ora dell’ultima scrittura (usa l’ora interna per gestire la data).
file.getCreationTime()
tempo_t di creazione.
file.isDirectory()
Restituisce se è una directory
file.isFile()
Restituisce se è un file
file.openNextFile()
Imposta il puntatore al file successivo nella directory.
file.rewindDirectory()
Riavvia il puntatore al primo file della directory.
dir.isFile()
Restituisce true se il file corrente a cui punta l’iteratore interno è un file.
dir.isDirectory()
Restituisce true se il file corrente a cui punta l’iteratore interno è una directory.
dir.openFile()
Questo metodo accetta l’argomento mode, che ha lo stesso significato di LittleFS.open()
function.
dir.fileName()
Restituisce il nome del file attualmente puntato.
dir.filetime()
Restituisce l’ultima ora di scrittura del file attualmente puntato.
dir.fileCreationTime()
Restituisce l’ora di creazione del file attualmente puntato.
dir.fileSize()
Restituisce la dimensione del file attualmente puntato.
dir.rewind()
Reimposta il puntatore interno all’inizio della directory.
dir.next()
Posiziona il puntatore interno all’elemento successivo della directory.
Esempi pratici
Ecco uno sketch per ottenere informazioni e controllare tutti i file nel tuo LittleFS .
/*
* Raspberry Pi Pico (or generic rp2040)
* LittleFS get info, read dir and show all file uploaded
* add a data folder to use with Pico LittleFS Data Upload
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org
*
*/
#include "Arduino.h"
#include "LittleFS.h"
void printDirectory(File dir, int numTabs = 3);
void setup()
{
Serial.begin(115200);
while (!Serial) {delay(100);}
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 *info;
LittleFS.info(*info);
unsigned int totalBytes = info->totalBytes;
unsigned int usedBytes = info->usedBytes;
unsigned int freeBytes = totalBytes-usedBytes;
unsigned int maxPath = info->maxPathLength;
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.print("Max path lenght: ");
Serial.print(maxPath);
Serial.println("");
Serial.println();
// Open dir folder
File dir = LittleFS.open("/", "r");
// 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.print(entry.size(), DEC);
Serial.print("\t");
Serial.println("byte");
}
entry.close();
}
}
Il risultato è:
Inizializing FS...
done.
File sistem info.
Total space: 537140992byte
Total space used: 239byte
Total space free: 537140753byte
Max path lenght: 13107322
file1.txt 62 byte
folderTest/
file2.txt 62 byte
file3.txt 62 byte
Ecco uno schizzo con comandi più utili, scrivere una stringa in un file, leggere tutto il contenuto del file, si posiziona sul nono byte del file e leggere da lì i dati.
/*
* Raspberry Pi Pico (or generic rp2040)
* 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);
while (!Serial) {delay(100);}
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 www.mischianti.org!!");
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 19 byte!");
testFile.seek(19, SeekSet);
Serial.println("Read file content!");
Serial.println(testFile.readString());
testFile.close();
}else{
Serial.println("Problem on read file!");
}
}
void loop()
{
}
Ecco il risultato dello sketch.
Inizializing FS...
done.
Write file content!
Read file content!
Here the test text www.mischianti.org!!
Position inside the file at 19 byte!
Read file content!
www.mischianti.org!!
Grazie
- Schede Raspberry Pi Pico e rp2040: pinout, specifiche e configurazione IDE Arduino
- Schede Raspberry Pi Pico e rp2040: filesystem LittleFS integrato
- Scheda Raspberry Pi Pico e rp2040: ethernet w5500 e requests HTTP e HTTPS (SSL)
- Schede Raspberry Pi Pico e rp2040: WiFiNINA con coprocessore WiFi ESP32
- Schede Raspberry Pi Pico e rp2040: come utilizzare una scheda SD
- Dallas ds18b20
- Collegamento dell’EByte E70 ai dispositivi Raspberry Pi Pico (rp2040) ed un semplice sketch di esempio