Getting SPIFFS

Using the ESP8266 to host a micro-application is one of it's most appealing uses. In addition to the EEPROM ( electrically erasable programmable read-only memory ) where a very limited amount of data can be stored, there is another special allocation for "actual files" called SPIFFS ( I won't pretend to know the acronym, it has something to do with SPI and flash )

I wanted to learn more about this ability to serve, save, and otherwise utilize files stored inside this tiny, flash-based file system.

Using platformIO as my framework I set out to learn how the SPIFFS filesystem works.

Uploading to SPIFFS

The actual mechanics of uploading the files is surprisingly easy. The files to be uploaded go into a directory at the project root named /data. PlatformIO cli then provides:

pio run --target uploadfs

( only differing from the regular upload command by that trailing -fs )

This allows uploading the files to SPIFFS to be a separate operation from flashing the main program. I'm sure the official platformIO IDE makes this even easier, but the cli interface is nice and simple.

Using SPIFFS in a project

Some familiar-feeling steps, requiring a core filesystem library and accessing files:

#include <FS.h>   // Include the SPIFFS library

Include the FS header

setup () {
	...
  SPIFFS.begin();
  ...
  // then you're able to:
  server.on("/photo.jpg", [](){
    if (SPIFFS.exists('/photo.jpg')) {
      File file = SPIFFS.open("/photo.jpg", "r"); 
      size_t sent = server.streamFile(file, "image/jpeg");
      file.close();
    }
  }
}

Then during setup() call 'SPIFFS.begin()'

Limitations

Different boards will have different allocations so the amount of space available will be between a very small amount ( 500kb? ) up to 4MB on the ESP8266 dev kit board I'm using!

You're allowed only 31 characters for filenames and that includes directories ( which are just considered part of filenames - in reality there are no directories ) . That's a pretty low limit and apparently the warning thrown if that limit is violated is not very clear.

Demo

I wanted to serve an SVG file, so I tried it two ways. ( using ESP8266WebServer )

server.on("/spiffs-svg", [](){
	webString = "<img src='/muertos.svg' />";   
	server.send(200, "text/html", webString);            
});

Serving an image tag that then requests the svg file

server.on("/muertos.svg", [](){ // serves svg file
  if (SPIFFS.exists("/muertos.svg")) {                           
    File file = SPIFFS.open("/muertos.svg", "r"); 
    size_t sent = server.streamFile(file, "image/svg+xml");
    file.close();
  } else {
    server.send(404, "text/html", "what file?");            
  }
});

Serving the file directly

The result:

art credit: https://freesvg.org/1539641493
because how else are you going to serve a favicon?

I threw a little javascript application on there have been thinking about the various use cases this enables for my IoT projects.

SPIFFS is Deprecated

After learning all of this I was bummed to hear this

SPIFFS is currently deprecated and may be removed in future releases of the core. Please consider moving your code to LittleFS. SPIFFS is not actively supported anymore by the upstream developer, while LittleFS is under active development, supports real directories, and is many times faster for most operations.

https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html

To convert most applications from SPIFFS to LittleFS simply requires changing the SPIFFS.begin() to LittleFS.begin() and SPIFFS.open() to LittleFS.open() with the rest of the code remaining untouched.

I tried this and it turns out it isn't that easy. In addition to re-uploading my files to SPIFFS I think it may also need to be reformatted. A subject for another post.

References