Sistema de ficheros¶
Esquema de la memoria flash¶
Aunque el sistema de archivos está almacenado en el mismo chip flash que el sketch, la programación de un nuevo boceto no modificará el contenido del sistema de archivos. Esto permite utilizar el sistema de archivos para almacenar datos del sketch, archivos de configuración o contenido para el servidor web.
El siguiente diagrama ilustra el esquema o plantilla utilizado por el entorno Arduino:
|--------------|----------|--------------------|---|---|---|---|---|
^ ^ ^ ^ ^
Sketch Actualiz. OTA Sistema de ficheros EEPROM Config. WiFi (SDK)
El tamaño del sistema de ficheros depende del tamaño del chip flash. Dependiendo de que tarjeta se ha seleccionado en el IDE, tendrás las siguientes opciones de tamaño flash:
Tarjeta | tañano chip flash, bytes | Tamaño sistem. fich, bytes |
---|---|---|
Generic module | 512k | 64k, 128k |
Generic module | 1M | 64k, 128k, 256k, 512k |
Generic module | 2M | 1M |
Generic module | 4M | 1M, 2M, 3M |
Adafruit HUZZAH | 4M | 1M, 2M, 3M |
ESPresso Lite 1.0 | 4M | 1M, 2M, 3M |
ESPresso Lite 2.0 | 4M | 1M, 2M, 3M |
NodeMCU 0.9 | 4M | 1M, 2M, 3M |
NodeMCU 1.0 | 4M | 1M, 2M, 3M |
Olimex MOD-WIFI-ESP8266(-DEV) | 2M | 1M |
SparkFun Thing | 512k | 64k |
SweetPea ESP-210 | 4M | 1M, 2M, 3M |
WeMos D1 & D1 mini | 4M | 1M, 2M, 3M |
ESPDuino | 4M | 1M, 2M, 3M |
WiFiduino | 4M | 1M, 2M, 3M |
Nota para utilizar funciones del sistema de ficheros en el sketch, añade la siguiente línea include al sketch:
#include "FS.h"
Limitaciones del sistema de ficheros¶
La implementación del sistema de archivos para ESP8266 tuvo que acomodarse a las restricciones del chip, entre las cuales está su RAM limitada. SPIFFS fue seleccionado porque está diseñado para sistemas pequeños, pero tiene como coste algunas simplificaciones y limitaciones.
Primero, por detrás, SPIFFS no soporta directorios, solo almacena una lista «plana» de ficheros. Pero en contra de un sistema de ficheros tradicional, el caracter «slash» '/'
está permitido en los nombres de ficheros, por lo que las funciones que se ocupan de listar directorios (por ejemplo, openDir("/website")
) básicamente solo filtra los nombres de archivo y conserva los que comienzan con el prefijo solicitado ( /website/
). En términos prácticos, eso hace poca diferencia sin embargo.
Segundo, existe una limitación a 32 caracteres en total en los nombres de ficheros. Un caracter '\0'
está reservado para la cadena C de terminación, lo que nos deja 31 caracteres para utilizar.
Combinado, significa que se recomienda mantener los nombres de archivo cortos y no usar directorios profundamente anidados, como la ruta completa de cada archivo (incluido directorios, caracteres '/'
, nombre base, punto y extensión) tiene que ser
31 caracteres como máximo. Por ejemplo, el nombre de archivo /website/images/bird_thumbnail.jpg
tiene 34 caracteres y causará problemas si se utiliza, por ejemplo en exists()
o en caso de que otro archivo comience con los mismos primeros 31 caracteres.
Peligro: Ese límite se alcanza fácilmente y si se ignora, los problemas podrían pasar desapercibidos porque no aparecerá ningún mensaje de error en la compilación ni en el tiempo de ejecución.
Para mas detalles sobre la implementación interna de SPIFFS, ver el fichero readme SPIFFS.
Subiendo ficheros al sistema de archivos¶
ESP8266FS es una herramienta que se integra en el IDE de Arduino. Añadiendo una nueva casilla al menú Herramientas para subir el contenido del directorio «data» del sketch al sistema de ficheros flash del ESP8266.
- Descarga la herramienta: https://github.com/esp8266/arduino-esp8266fs-plugin/releases/download/0.3.0/ESP8266FS-0.3.0.zip.
- En el directorio de sketchs de Arduino, crea el directorio
tools
si no existe todavía. - Descomprime la herramienta en el directorio
tools
(la ruta debe quedar<home_dir>/Arduino/tools/ESP8266FS/tool/esp8266fs.jar
). - Reinicia el IDE de Arduino.
- Abre el sketch (o crea uno nuevo y sálvalo)
- Ve al directorio del sketch (selecciona Programa > Mostrar carpeta de programa)
- Crea un directorio llamado
data
y algún fichero que quieras tener en el sistema de ficheros. - Asegúrate de tener tu tarjeta seleccionada, el puerto (COM, tty, etc) y cierra el Monitor Serie.
- Selecciona Herramientas > ESP8266 Sketch Data Upload. Debería comenzar la subida de los ficheros a sistema de ficheros flash del ESP8266. Cuando acabe, la barra de estado del IDE mostrará el mensaje
SPIFFS Image Uploaded
.
Objeto sistema de ficheros SPIFFS¶
begin¶
SPIFFS.begin()
Este método monta el sistema de ficheros SPIFFS. Debe ser llamado antes de usar cualquier otro API del sistema de ficheros. Devuelve true si el sistema de archivos se ha montado satisfactoriamente, false en caso contrario.
end¶
SPIFFS.end()
Este método desmonta el sistema de ficheros SPIFFS. Utiliza este método antes de realizar una actualización OTA del SPIFFS.
format¶
SPIFFS.format()
Formatea el sistema de ficheros. Se puede llamar antes o después de llamar begin
. Devuelve verdadero si el formateo tuvo éxito.
open¶
SPIFFS.open(path, mode)
Abre un fichero. path
debe ser un camino absoluto comenzando con un slash (p.ej. /dir/filename.txt
). mode
es una palabra que especifica el modo de acceso. Puede ser una de las siguientes: «r», «w», «a», «r+», «w+», «a+». El significado de estos modos es el mismo que para la función fopen
en C.
r Abre un fichero de texto para leerlo. La secuencia se coloca en el comienzo del archivo.
r+ Abre un fichero para lectura y escritura. La secuencia se coloca en el comienzo del archivo.
w Trunca en fichero con una longitud cero o crea un fichero de texto para escritura.
La secuencia se coloca en el comienzo del archivo.
w+ Abre para lectura y escritura. El fichero se crea si no existe, de lo contrario se trunca.
La secuencia se coloca en el comienzo del archivo.
a Abre el fichero para añadir (escribiendo al final del fichero). El fichero se crea si no existe.
La secuencia se coloca al final del archivo.
a+ Abre el fichero para añadir (escribiendo al final del fichero). El fichero se crea si no existe.
La posición inicial para lectura es al comienzo del fichero, pero la salida es siempre añadida
al final del fichero
Devuelve el objeto File. Para comprobar si el archivo se abrió con éxito, utilice un operador booleano.
File f = SPIFFS.open("/f.txt", "w");
if (!f) {
Serial.println("No se pudo abrir el fichero");
}
exists¶
SPIFFS.exists(path)
Devuelve true si existe el archivo con la ruta indicada, false en caso contrario.
openDir¶
SPIFFS.openDir(path)
Abre un directorio en la ruta absoluta indicada. Devuelve un objeto Dir.
remove¶
SPIFFS.remove(path)
Elimina el fichero de la ruta absoluta indicada. Devuelve true si el fichero se borró satisfactoriamente.
rename¶
SPIFFS.rename(pathFrom, pathTo)
Renombra el fichero pathFrom
a pathTo
. La ruta debe ser absoluta. Devuelve true si el fichero se renombra satisfactoriamente.
info¶
FSInfo fs_info;
SPIFFS.info(fs_info);
Rellena la estructura FSInfo con información sobre el sistema de ficheros. Devuelve true
si tiene éxito, false
en caso contrario.
Estructura de información del sistema de archivos¶
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
Esta es la estructura que se rellena al usar el método FS::info .
totalBytes
— Tamaño total de datos útiles en el sistema de archivos.usedBytes
— Número de bytes usado por los ficheros.blockSize
— Tamaño del bloque SPIFFS.pageSize
— Tamaño de la página lógica SPIFFS.maxOpenFiles
— Número máximo de archivos que pueden estar abiertos simultáneamente.maxPathLength
— Longitud máxima del nombre de archivo (incluido un byte cero de terminación).
Objeto directorio Dir¶
El propósito del objeto Dir es iterar sobre los ficheros dentro del directorio. Provee los métodos: next()
, fileName()
, y openFile(mode)
.
El siguiente ejemplo muestra como debe utilizarse:
Dir dir = SPIFFS.openDir("/data");
while (dir.next()) {
Serial.print(dir.fileName());
File f = dir.openFile("r");
Serial.println(f.size());
if(dir.fileSize()) {
File f = dir.openFile("r");
Serial.println(f.size());
}
}
next¶
Devuelve true mientras haya ficheros en el directorio para iterar. Debe llamarse antes de llamar a las funciones fileName()
, fileSize()
y openFile()
.
fileName¶
Devuelve el nombre del archivo actual apuntado por el iterador interno.
fileSize¶
Devuelve el tamaño del archivo actual apuntado por el iterador interno
openFile¶
Este método toma el argumento mode que tiene el mismo significado que para la función SPIFFS.open()
.
Objeto fichero File¶
Las funciones SPIFFS.open()
y dir.openFile()
devuelven un objeto File. Este objeto soporta todas las funciones de Stream, para que puedas usar readBytes
, findUntil
, parseInt
, println
y todos los otros métodos Stream.
Hay algunas funciones que son específicas del objeto File.
seek¶
file.seek(offset, mode)
Esta función se comporta como la función C fseek
. Dependiendo de un valor de mode
, se mueve a la posición actual en un fichero de la siguiente manera:
- Si
mode
esSeekSet
, la posición se establece aoffset
bytes desde el comienzo del fichero. - Si
mode
esSeekCur
, la posición actual se mueve aoffset
bytes. - Si
mode
esSeekEnd
, la posición se establece aoffset
bytes desde el final del fichero.
Devuelve true si la posición se estableció satisfactoriamente.
name¶
String name = file.name();
Devuelve el nombre del fichero, como const char*
. Conviértelo a String para almacenarlo
close¶
file.close()
Cierra el fichero. Ninguna otra operación debe realizarse sobre el objeto File después de llamar a la función close
.