ESP32 (22) – SPIFFS

luca 30/09/2017 0

In alcuni tutorial precedenti vi ho mostrato come includere elementi “esterni” al programma (immagini, certificati…) grazie alla funzionalità embedding binary data del framework. Oggi vi mostrerò invece come poter utilizzare una porzione della memoria flash per memorizzare dati, in maniera simile ad un disco fisso o una memory card.

Partizioni e file system

Avete già imparato dal mio quarto tutorial sul chip esp32 che la memoria flash collegata al chip viene suddivisa in partizioni, per poter ospitare diversi elementi e che è possibile – tramite menuconfig – configurare le diverse partizioni utilizzando dei template standard (es. “single factory app, no OTA”) o in maniera completamente custom.

L’elenco delle partizioni, la loro posizione all’interno della memoria flash e la loro dimensione sono definiti nella partition table, anch’essa memorizzata nella flash all’indirizzo 0x8000.

Possiamo definire un layout personalizzato della memoria flash creando un file csv con questo formato:

spiffs-001

Ogni riga corrisponde ad una partizione; per ogni partizione va indicato il tipo, il sottotipo, l’offset (ovvero l’indirizzo di partenza della partizione) e la dimensione. Il file csv sopra mostrato corrisponde a questo layout:

spiffs-002

Per verificare che le partizioni siano contigue, è sufficiente sommare all’offset la dimensione della partizione per trovare l’offset della successiva… ad esempio 0x9000 + 0x6000 = 0xf000.

Una partizione è semplicemente un’area di memoria: per poter memorizzarvi dei dati è necessario “organizzarli”; ad esempio abbiamo già visto l’utilizzo del componente NVS che si occupa di gestire dati nella forma “chiave-valore” nella partizione ad esso dedicato. I diversi supporti di memorizzazione (chiavette USB, dischi fissi…) organizzano i dati grazie ad un filesystem. Negli anni sono stati sviluppati moltissimi filesystem in base alle tipologie di supporti e ad esigenze specifiche… se avete un PC Windows quasi sicuramente il vostro disco fisso utilizzerà il filesystem NTFS, mentre le memory card normalmente utilizzano il filesystem FAT. Viste le caratteristiche peculiari delle memorie flash, Peter Andersson ha sviluppato un filesystem ottimizzato per tali supporti di memorizzazione, SPIFFS.

Componente

Per poter utilizzare il filesystem SPIFFS in un nostro programma, è necessario aggiungere alla cartella del progetto il componente sviluppato da Boris Lovosevic (loboris) che fa da wrapper tra la libreria SPIFFS di Peter Andersson (pellepl) e il Virtual File System (VFS) del framework esp-idf.

Scarichiamo quindi lo zip contenente il repository Github di loboris:

spiffs-01

Copiamo la cartella spiffs dallo zip all’interno della cartella components del nostro progetto:

spiffs-02

All’interno dello zip è anche presente lo strumento (mkspiffs) per poter “trasformare” una cartella del proprio PC in un file che rappresenta una partizione SPIFFS, pronto per essere caricato nella flash. Possiamo copiare la cartella mkspiffs ad esempio nella nostra home:

spiffs-04

Il componente spiffs richiede alcune variabili di configurazioni, che definiscono la geometria della partizione, ovvero come è “costruita”.

I parametri vanno aggiunti al file Kconfig.projbuild del progetto (qui vi ho spiegato la struttura di tale file) e sono i seguenti:

  • SPIFFS_BASE_ADDR, indirizzo della memoria flash dal quale inizia la partizione SPIFFS
  • SPIFFS_SIZE, dimensione in bytes della partizione
  • SPIFFS_LOG_BLOCK_SIZE, dimensione in bytes di ogni blocco di memoria
  • SPIFFS_LOG_PAGE_SIZE, dimensione in bytes di ogni pagina di memoria

Se volete approfondire la struttura interna in blocchi e pagine della partizione SPIFFS, potete leggere questo documento.

Indirizzo base e dimensioni devono essere quelle che avete configurato nel file csv che definisce il layout della memoria flash, mentre valori “buoni” per dimensione blocco e pagina sono 8192 e 256.

Nel creare il file csv, abbiamo visto che è possibile specificare la dimensione indicando ad esempio 1M per 1MB (1 Mega Bytes). Tale dimensione equivale a 1.048.576 bytes (1024 * 1024 bytes) e non come si potrebbe pensare a 1.000.000 bytes.

Prepariamo e carichiamo l’immagine

Se è necessario caricare nella partizione SPIFFS del contenuto prima che venga eseguito il programma (ad esempio immagini, files audio… che saranno poi utilizzati dal programma durante la sua esecuzione) è possibile utilizzare il tool mkspiffs per preparare un file immagine con il contenuto di una cartella del proprio computer.

Per prima cosa dobbiamo compilare mkspiffs:

cd mkspiffs/src
make

spiffs-05

Creiamo ora sul nostro PC una nuova cartella e inseriamo i files che dovranno essere memorizzati nella partizione SPIFFS. Possiamo anche creare sottocartelle… ad esempio ho creato la cartella spiffs_image nella mia home con questo contenuto:

spiffs-06

Lanciamo il seguente comando per creare il file .img che rappresenta una partizione SPIFFS con il contenuto della cartella sopra:

./mkspiffs.exe -c /home/luca/spiffs_image/ -b 8192 -p 256 
 -s 1048576 /home/luca/spiffs_image.img

Il parametro -b rappresenta il valore di LOG_BLOCK_SIZE, -p il valore di LOG_PAGE_SIZE e -s la dimensione della partizione. Il comando mkspiffs visualizza il contenuto dell’immagine creata:

spiffs-07

Ora possiamo utilizzare esptool per memorizzare il contenuto del file creato all’interno della flash:

python $IDF_PATH/components/esptool_py/esptool/esptool.py --chip esp32 
--port COM15 --baud 115200 write_flash --flash_size detect 0x180000 /home/luca/spiffs_image.img

Sostituite la porta COM con quella a cui è collegata la vostra scheda di sviluppo. Fate particolare attenzione all’indirizzo (sopra 0x180000) da cui esptool inizia a scrivere i dati: deve corrispondere a quello specificato nel file csv che definisce il layout delle diverse partizioni.

Utilizziamo spiffs in un programma

Per prima cosa includiamo nel nostro programma gli headers del wrapper SPIFFS e del componente VFS:

// VFS and SPIFFS includes
#include "esp_vfs.h"
#include "spiffs_vfs.h"

All’inizio del programma, dobbiamo registrare il filesystem SPIFFS:

vfs_spiffs_register();

Questo metodo indica al componente VFS le caratteristiche proprie della partizione SPIFFS e quali funzioni chiamare per le diverse operazioni sul filesystem. Il metodo esegue anche il mount della partizione (formattandola se necessario) in modo che sia visibile a partire dal percorso /spiffs.

Possiamo verificare che la partizione sia stata montata con:

if(spiffs_is_mounted) {...}

A questo punto, grazie al componente VFS, è possibile operare sui files e cartelle contenute nella partizione usando le funzioni standard C. Ad esempio possiamo aprire in lettura il file “readme.txt” presente nella root della partizione con:

FILE *file;
file = fopen("/spiffs/readme.txt", "r");

e leggerne il contenuto con:

int filechar;
while((filechar = fgetc(file)) != EOF)
[...]

Nel mio repository Github trovate un programma che consente di navigare all’interno di una partizione SPIFFS con comandi unix-like (cd, ls) e di visualizzare il contenuto di files (cat):

Conclusioni

La possibilità di utilizzare parte della memoria flash per memorizzare files ci consente di realizzare progetti che richiedano elementi esterni (pagine html, immagini, suoni…) senza bisogno di supporti di memorizzazione esterni al chip esp32.

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi