Llevamos varias entradas de la serie dedicadas a el ESP8266 y el ESP32 funcionando como servidor. Pero ahora toca empezar a adentrarnos en su verdadero potencial viendo el sistema de archivos SPIFFS.
En entradas anteriores hemos visto cómo configurar un servidor básico, como servir contenido dinámico, como distinguir tipos de peticiones y parámetros, y como servir ficheros desde memoria Flash para reducir el consumo de RAM.
Ya habíamos dicho que lo anterior tiene sentido cuando estamos sirviendo contenido dinámico o “peudo-dinámico”, como cuando hacemos un API. Pero para servir contenido exclusivamente estático tenemos el sistema de archivos SPIFFS.
En realidad, deberíamos hablar de sistemas de archivos, en plural ya que, además de SPIFFS está LittleFS. Sin embargo, este último ha aparecido es mucho más reciente, y muchas librerías aún no son compatibles. Por lo que de momento nos centraremos en el SPIFFS, y hablaremos del LittleFS en su propia entrada.
¿Qué es el SPIFFS?
Es SPIFFS (SPI Flash File System) un sistema de archivos diseñado para funcionar en memorias flash conectadas por SPI en dispositivos embebidos y con escasa cantidad de RAM, como el ESP8266 y el ESP32.
Por este motivo tiene ciertas “simplificaciones” respecto a un sistema de ficheros como el que estamos habituado. Por ejemplo, SPIFFS no soporta directorios, aunque en la práctica consigue que a menudo de veces no notemos la diferencia.
Así crear un fichero miDir/miFile.txt creará un fichero llamado así, en lugar de un fichero miFile.txt dentro del directorio miDir. Al listar los ficheros de un directorio, básicamente, el sistema SPIFFS “filtra” los ficheros cuya ruta empieza por el directorio deseado.
Otra limitación importante es que la longitud máxima de una ruta es de 31 caracteres, incluyendo directorio, subdirectorios, caracteres ’/’, nombre de archivo, y extensión. Esto es una ruta muy corta, por lo que tenedlo en cuenta a la hora de nombrar vuestros ficheros.
Cómo configurar Arduino IDE para funcionar con ESP8266 SPIFFS
Podemos modificar el IDE de Arduino para dar soporte al sistema SPIFFS del ESP8266 de forma sencilla mediante la instalación del plugin ESP8266 FS para Arduino.
En primer lugar, descargamos la última versión disponible del plugin desde la siguiente ruta este enlace para el ESP8266 o desde este enlace para el ESP32.
A continuación, descomprimimos el contenido (esp8266fs.jar) en la siguiente carpeta del IDE de Arduino
- Linux/Mac: ~/Arduino/tools/
- Windows: C:\Users\YOURUSERNAME\Documents\Arduino\tools\
Por lo que la instalación del plugin quedaría algo así,
Usando el plugin ESP8266 FS
Iniciamos el entorno de Arduino, y veremos que tenemos una nueva opción disponible.
Para usarlo, como de costumbre, en primer lugar debemos asegurarnos de que tenemos la placa y el puerto correctamente elegidos.
Por otro lado, en las placas con ESP8266 tenemos una opción con varias combinaciones entre espacio dedicado a memoria y a SPIFFS. Para que el SPIFFS funcione, lógicamente, deberemos elegir una combinación que disponga más espacio de archivos que el que vamos a usar (en particular, si usáis cero, no podéis usarlo).
Para usar el plugin deberemos crear una carpeta llamada ‘data’ dentro de la carpeta donde este el Sketch con el programa del ESP8266. Veréis que esta carpeta es habitual en la mayoría de proyectos del ESP8266.
Finalmente, al usar el comando ‘ESP8266 Sketch Data Upload’ el contenido de la carpeta ‘data’ se subirá a la memoria SPIFFS, borrando todo lo que hubiera anteriormente.
Detalles de la librería FS.h
Para trabajar con ficheros SPIFFS el ESP8266 dispone de la librería ‘FS.h’ que podemos incluir en nuestros programas. Esta librería contiene objetos y funciones interesantes para la gestión de ficheros en SPIFFS. Conviene echarle un ojo a su código, pero aquí tenéis un pequeño resumen.
Structura FSInfo64
El objeto directory representa un directorio del SPIFFS, y dispone de las siguientes propiedades.
struct FSInfo64 {
uint64_t totalBytes;
uint64_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
Clase Directory
El objeto Directory representa un directorio del SPIFFS, y dispone de las propiedades de FSInfo64 y las siguientes funciones.
// iterates over files in directory
bool next();
bool rewind();
// actions over current item
File openFile(const char* mode);
String fileName();
size_t fileSize();
bool isFile() const;
bool isDirectory() const;
Clase File
El objeto File representa un fichero del SPIFFS, y dispone de las propiedades de FSInfo64 y las siguientes funciones.
// Print methods:
size_t write(uint8_t);
size_t write(const uint8_t *buf, size_t size);
// Stream methods
int available();
int read();
int peek();
void flush();
size_t readBytes(char *buffer, size_t length)
size_t read(uint8_t* buf, size_t size);
bool seek(uint32_t pos, SeekMode mode);
size_t position();
// file information
size_t size() const;
const char* name();
const char* fullName(); // Includes path
bool isFile();
bool isDirectory();
// close file
void close();
Funciones de FS.h
Por su parte, la librería FS.h proporciona las siguientes funciones para manejar ficheros y directorios.
bool setConfig(const FSConfig &cfg);
bool begin(); // mount file system
void end(); // unmount file system
bool format(); // format file system
// return FSinfo structure with file system info
bool info(FSInfo& info); information
bool info64(FSInfo64& info);
// return true if a path exists
bool exists(const char* path);
bool exists(const String& path);
// open a file
// mode is a string specifying access mode. It can be one of “r”, “w”, “a”, “r+”, “w+”, “a+”
File open(const char* path, const char* mode); // open a file
File open(const String& path, const char* mode);
// delete file
bool remove(const char* path);
bool remove(const String& path);
// rename file
bool rename(const char* pathFrom, const char* pathTo);
bool rename(const String& pathFrom, const String& pathTo);
// open a directory
Dir openDir(const char* path);
Dir openDir(const String& path);
// Create a directory
bool mkdir(const char* path);
bool mkdir(const String& path);
// Delete a directory
bool rmdir(const char* path);
bool rmdir(const String& path);
Hasta aquí la entrada a presentar el sistema de ficheros SPIFFS en un SoC como el ESP8266. En la próxima entrada aprenderemos a usar el SPIFFS para servir páginas estáticas, lo que (por fin) nos abrirá las puertas del ESP8266 como servidor. ¡Hasta pronto!