LittleFS – the Best File System for Embedded Projects?

Introduction

Microcontrollers don't usually have a built-in file system. Projects that need a file system have a choice of which file system to use. Popular choices include the FAT file system and SPIFFS, and the Moddable SDK supports both. These file systems work well, but have limitations that make them difficult for developers to work with, especially developers more familiar with the full featured file systems on computers. The LittleFS file system created by ARM is an excellent alternative to both SPIFFS and FAT, that is also easier for developers to use. LittleFS is now fully supported in the Moddable SDK.

This blog post explains the benefits of LittleFS and how to start using it in your projects.

Benefits of LittleFS

Both the design and implementation of LittleFS meet the needs of today's embedded projects, combining essential features with ease of use.

Real Directories and Long File Names

LittleFS supports real directories, just like the file system on your computer. This is very important for managing a large number of files and for interoperability with code that runs both on embedded devices and computers. Many embedded systems are so-called flat file systems which don't support directories.

LittleFS also allows file names of up to 254 bytes. While long file names are not always essential, they can ease development by allowing more descriptive file names to be used. File names can use UTF-8 encoding, allowing non-ASCII characters to be included in file names, which can be convenient for projects deployed world-wide.

High Reliability

LittleFS is designed to ensure that the file system does not become corrupted and does not wear out from overuse. It provides two different features to help with this.

First, LittleFS organizes its on-disk data structures to be resilient to loss of power. This is critical for embedded devices that can lose power at any time, especially battery powered products. If power is lost while updating the file system, the update being written may be lost, but the file system will not be corrupted. Instead, the file system's state will simply reflect the last successful write.

Second, LittleFS implements wear leveling to extend the life of the flash memory chip. Each block of flash memory supports only a limited number of erases, after which they become unreliable. If a single block is written to over and over, it will become unable to store new data. LittleFS works around this by spreading out writes across all available blocks significantly extending the usable lifetime of a flash memory chip.

To learn more about wear-leveling and resilience to unexpected power loss, see the blog post from ARM introducing LittleFS. The LittleFS repository contains a detailed description of the LittleFS data structures that enable these features, as well as interesting background on its design.

Small Size

LittleFS has a very small code size and uses surprisingly little RAM. The code footprint on the Xtensa processor in the ESP32 is about 14 KB. The RAM use is around 100 bytes when the file system is mounted. Each open file requires a few dozen bytes of additional memory.

As an additional memory optimization, the Moddable SDK LittleFS module unmounts the LittleFS volume when no files are open. This drops the RAM footprint to zero when the file system is idle.

Thread Safe

LittleFS provides hooks that allow it to be thread safe. The Moddable SDK implements these hooks on devices running FreeRTOS, which includes the ESP32. This support allows safe access to the file system from the main JavaScript virtual machine and any workers running in separate threads.

Configurable

The light RAM use of LittleFS comes at a price: performance is not as fast as it could be. Fortunately, LittleFS can be configured to use a little more memory, with the result being greatly improved performance. As little as 1 KB more memory makes a significant difference.

Using LittleFS

The Moddable SDK makes it very easy to use LittleFS. There's no new API to learn. That's because the existing Moddable SDK File module has been extended to support LittleFS.

Let's take a quick look at using LittleFS in your project by updating the Moddable SDK's file example to use LittleFS. No changes are needed to the project's source code, just a small change to the project's manifest. Here's the part of the manifest that includes the file system module:

"include": [
    "$(MODDABLE)/examples/manifest_base.json",
    "$(MODDABLE)/modules/files/file/manifest.json"
],

To use LittleFS, just change the second include line from manifest.json to manifest_littlefs.json:

"include": [
    "$(MODDABLE)/examples/manifest_base.json",
    "$(MODDABLE)/modules/files/file/manifest_littlefs.json"
],

The Moddable SDK supports LittleFS on ESP8266 and ESP32 embedded devices today. Supporting additional devices in the future is straightforward. LittleFS also works in the desktop simulator using a RAM disk, which is useful for testing.

The default configuration of LittleFS minimizes RAM which sacrifices some performance. To boost performance, your project's manifest can configure LittleFS to use more RAM.

Conclusion

There's no single best choice for a file system in an embedded project. Each project has its own requirements. For example, if reading data from an SD Card is a requirement, then FAT32 is the only choice. That said, for many projects LittleFS is now the best choice. Its compact code size, minimal use of RAM, support for directories and long file names, and error resilience make it an easy choice. Because LittleFS behaves more like the file systems on computers, it is also easier for developers to work with. Projects using the Moddable SDK with another file system today can switch over to LittleFS easily without the need for any code changes.