Skip to content

Embedded Filesystems

BCG edited this page Apr 16, 2020 · 9 revisions

Background

Sometimes in an embedded application you might like to be able to read/write from/to some non-volatile memory. It is common for microcontrollers to be paired with SPI flash devices for this purpose, and while it is certainly possible to use such a device without a filesystem, files are a useful and familiar abstraction that can help free up a program from having to manage things like wear leveling, block/sector level erasure, etc.

Request for SPI flash and filesystem support was mentioned in this issue: https://github.com/tinygo-org/drivers/issues/45

Low level I/O driver for SPI NOR flash is available in TinyGo drivers since v0.12.0: https://github.com/tinygo-org/drivers/pull/124

SPI Flash

(TODO: illustrate how to initialize a flash device using the flash driver package, also explain difference between SPI and QSPI peripherals)

Implementations

With low-level IO functions available, it is possible to begin experimenting with more high-level filesystem support. So far I've experimented with 2 filesystem implementations on top of the SPI flash driver:

Of the two, LittleFS is more full-featured and is what I would recommended for use with SPI flash, as it is far superior with respect to wear leveling and resiliency in case of power loss. FAT is not a great filesystem for use with flash memory, especially if you will be constantly be writing/overwriting files, because in that case you would be constantly erasing the same sectors/blocks on the device which will eventually destroy those sectors. That said, FAT is kind of the "lowest common denominator" when it comes to compatibility - Windows, OS X, and Linux all support creating/editing FAT filesystems without special drivers for instance, and nearly all SD cards are formatted this way, so it is useful to have support for FAT, especially for read-only or low-write use cases for which wear leveling is little or no concern.

LittleFS

LittleFS (https://github.com/ARMmbed/littlefs/blob/master/DESIGN.md) is a filesystem designed and optimized for embedded applications and flash memory, and is maintained as part of the ARM Mbed OS. I created CGo wrappers around most of the important functions in the C implementation provided by Mbed to provide a os package style interface from Go, which can be found at https://github.com/bgould/go-littlefs. The library is designed to be usable from both from TinyGo as well as standard Go, so the use of some CGo features that are not yet supported in TinyGo needed to be worked around. I would consider the status of this library to be "beta" at the moment (could be some bugs and/or may rework some of the API at some point) but it works and should be usable for common use cases like reading/writing config files or logging.

(to be continued...)

Clone this wiki locally