Uploading files to LittleFS
Your sketch and your files are two separate uploads to two separate partitions. Knowing that explains why re-flashing does not delete your web page, and why re-uploading the folder does.
Two uploads, two partitions
data/ goes in, keeping its name and its path. Nothing else does: a file one level up is invisible to the tool.The sketch goes into the app partition. Everything under data/ in your sketch
folder goes into the filesystem partition. They are different regions of the
same flash chip with different sizes decided by the partition table, and one
upload does not touch the other.
That single fact answers most of the questions people ask about this:
- Re-flashing the sketch does not erase your files.
- Re-uploading the folder replaces the whole filesystem, including anything the sketch wrote at runtime.
- "Erase all flash before sketch upload" erases both.
The steps
- Make a folder called
datanext to your.inofile, not inside any other folder. - Put the files in it, with the paths you want them to have.
data/www/app.jsbecomes/www/app.json the board. - Run the upload command. In Arduino IDE 2.x it is in the command palette
(
Ctrl+Shift+P→ Upload LittleFS to Pico/ESP8266/ESP32), not the Tools menu. - Close the Serial Monitor first. It holds the port, and the upload needs it.
Why LittleFS and not SPIFFS
SPIFFS is deprecated and has no directories, no power-loss safety worth the name, and gets slower as it fills. LittleFS has all three and is built into the core, so there is no library to install. Every SPIFFS example on the internet works if you change the header and the object name, and there is no reason left to start a new project on it.
Watch the size
A microcontroller's filesystem is measured in hundreds of kilobytes. The
default 4 MB layout leaves about 1.4 MB. One web font and one logo can spend
most of it, and nothing warns you — so gzip what you serve, and check
usedBytes() in the same sketch that mounts it.
The code
After the folder upload, this proves the files arrived — it mounts the filesystem and lists what is in it with sizes.
#include <LittleFS.h>
void setup() {
Serial.begin(115200);
delay(200);
if (!LittleFS.begin(false)) { // true = format if the mount fails
Serial.println("mount failed — was the data folder ever uploaded?");
return;
}
Serial.printf("%u of %u bytes used\n", LittleFS.usedBytes(), LittleFS.totalBytes());
File dir = LittleFS.open("/");
for (File f = dir.openNextFile(); f; f = dir.openNextFile())
Serial.printf(" %-20s %6u\n", f.name(), f.size());
}
void loop() {}Passing true to begin() formats the partition if the mount fails. Convenient on a first run, and a silent way to erase everything on a board in the field.
MicroPython has no separate data folder: the board's flash is already a filesystem and mpremote copies onto it directly.
import os
def tree(path="/"):
for name, kind, *_ in os.ilistdir(path):
full = path.rstrip("/") + "/" + name
if kind == 0x4000:
tree(full)
else:
print("%-24s %6d" % (full, os.stat(full)[6]))
tree()This is the one place MicroPython is simply less awkward. There is no plugin, no partition scheme to choose, and the same cp command that puts main.py there puts index.html there.
When it does not work
Arduino IDE 2.x uses a different mechanism from 1.x. Install the arduino-littlefs-upload extension, put the .vsix in the IDE's plugins folder, restart, and the command appears in the Ctrl+Shift+P palette rather than in Tools.
The partition scheme has no filesystem in it. Several schemes — the OTA ones especially — spend the whole chip on two app slots. Tools → Partition Scheme, pick one whose name mentions SPIFFS or FATFS, and upload the folder again.
The partition filled up. Nothing errors; the tool writes until there is no room and stops. Check usedBytes against totalBytes, and remember that a web font and a PNG will each be larger than all your code.
Only if the partition table changed. Changing the partition scheme moves the filesystem's start address, so the old contents are still in flash and no longer where anything looks for them. Re-upload the folder after any scheme change.
A filesystem is the wrong place for a Wi-Fi password and a calibration constant. For those there is a smaller store with wear levelling built in.
Preferences and NVS →Edit this page — content/esp32/uploading-files-to-littlefs.mdx
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.