
A little fail-safe filesystem designed for microcontrollers (2017) - opless
https://github.com/ARMmbed/littlefs
======
woodrowbarlow
i am very impressed that, although it's designed for the mbed ecosystem, this
code is obviously written so that it can be used in any embedded project
(especially those that use a single, statically-compiled binary for the entire
firmware) with virtually no changes. i could have this working on my project's
bespoke hardware in a couple hours.

* zero dependencies, no assumptions about libc, doesn't use timers or heap, fully synchronous, and it's passive when you're not interacting with it.

* variables, constants, and functions are well-prefixed (without being too verbose) to avoid collisions.

* BSD license is friendly for single-binary firmwares.

* the Makefile doesn't assume anything, it just outputs a .a file which you can link however you want.

* the Makefile is simple and doesn't require cmake or autotools. it's easy to point it at your cross-compile toolchain.

it has other hallmarks of a well-planned and well-maintained project too:

* the readme shows exactly why i might want this (or might not), and how to use it. the separate design doc shows exactly how it works.

* functionality is cleanly separated by file.

* consistent style (could specify which style guide they're using, though).

* the tests serve their usual purpose but also serve as examples. they're well encapsulated and the code was obviously written to be tested.

these authors have absolutely nailed everything i strive for at my embedded
firmware development job.

~~~
scoutt
I had the same reaction. Really impressive and well documented. I will surely
do some tests.

> variables, constants, and functions are well-prefixed (without being too
> verbose) to avoid collisions.

Unfortunately it has the same name (Little File System, LFS) and the same
function prototypes (lfs_*) of a filesystem for NOR/NAND based systems I did
like 10 years ago and still in use, so it will be at least confusing.

As a matter of fact, I guess every embedded technology company using
NAND/NOR/whatever memories have their own version of a LFS.

~~~
loeg
You're referring to LFS as in LogFS?

------
notacoward
I didn't read _all_ of the design, but it looks like the author had an
unusually clear understanding of the tradeoffs involved and how they relate to
the specific target environment. There are some clever solutions there, all
explained quite well. Definitely worth a look.

~~~
SlowRobotAhead
I think you can be sure this is not his first attempt at a file system.

Documentation does look really good. I’ll hang in to this.

------
roland35
I am curious - does anyone have some feedback from using the mbed ecosystem? I
have generally shied away from using too much vendor middleware but it does
look like there are a lot of useful libraries.

~~~
hak8or
I would also love to hear replies to this. I used mbed in the past and have
been fairly dissatisfied with it for two reasons:

It uses c++ for the sake of using c++ instead of leveraging the extreme
bonuses c++ provides over using c for embedded. For example, it tends to use
dynamic memory allocation heavily, doesn't make use of unique/shared pointer,
doesn't use templates properly (if at all) in places it would be ideal (hence
increasing code size and slowing things down).

Last I checked, it doesn't support cmake at all, and instead used an extremely
complicated and conveluted build system/process.

Both of those combined made me run away and never look back. Another side
thing as of late is it seems to be officially supported by arm, which means it
will never run on other cores like risc-v. I am not interested in getting
stuck with one platform when riscv (in my opinion) has incredible potential
for microcontrollers and is seemingly right around the corner.

~~~
notacoward
Your criticism seems a bit idiosyncratic, to put it kindly. So it doesn't use
the flavor of C++ you prefer? Sure, but there's a _lot_ of room for argument
about whether shared_ptr or template-instantiation bloat would be good choices
for an IoT-level embedded system. Similarly, the fact that it doesn't use
cmake seems like more a matter of preference than of actual suitability. As
for being supported by ARM, well hey, at least it's open source. It could
_theoretically_ be forked for RISC-V. Lacking any mention of alternatives,
that criticism also seems rather hollow. Beggars can't be choosers, y'know.

BTW, you maybe should have mentioned that you work on a competing project.

~~~
swiley
Dynamic memory allocation on an embedded system is pretty bad. Even in desktop
applications you should usually try and avoid that.

Over complicating the build system is a reason for dropping almost anything
but especially this. The whole point of a framework like that is to make
things easier.

~~~
notacoward
> Dynamic memory allocation on an embedded system is pretty bad.

That's the one criticism I found valid. I even called it one of the "Four
Horsemen of Poor Performance" in a pretty widely read article I wrote on
server performance back in 2002. On the other hand, over-reliance on static
allocation means allocating many arrays/pools for the worst case, even when
they couldn't possibly all hit worst case at the same time, and that can be a
pretty bad choice on a highly memory-constrained device. (Doing it for the
sake of real-time predictability is actually a different issue.)

OTOH complaining about not using templates because of performance seems
exactly backwards, and complaining that it's not likely the the project
sponsor will port already-open-source code to a competing architecture
themselves seems a bit too entitled. When I see a list of negatives that are
mostly bogus, and no mention of positives at all, it's a strong indicator of
NIH syndrome.

------
howard941
Nice, perhaps a more robust fatfs replacement?

If you've used this (or are the author) how is the "storage on disk ... always
kept in a valid state" feature implemented? Does it write two copies in case a
write's interrupted so one can always roll back to the earlier valid copy?

~~~
notacoward
[https://github.com/ARMmbed/littlefs/blob/master/DESIGN.md](https://github.com/ARMmbed/littlefs/blob/master/DESIGN.md)
answers those questions in admirable detail.

~~~
howard941
Thank you. Makes me wish everything else in the world was so thoughtfully
documented.

------
pkaye
One problem I see is when they write the pairs of metadata blocks for
redundancy, in many FTL implementations they might fall on the same physical
page of flash so there is not much redundancy. When FTL write metadata for
their own needs, they are congnizant of the flash layout and make sure to
write metadata to separate die/block/page.

------
TickleSteve
Seems well thought through, but the concept of putting a general-purpose file
system on an embedded microcontroller is a common mistake.

These are single-purpose systems, you don't need to use filenames and have
POSIX semantics, you typically just need to put your data into a circular
buffer on FLASH. The circular buffer (with checksummed elements) will take
care of bad-block management and wear levelling for you.

I've seen this far too often, filesystems are not ideal for this class of
system.

~~~
diydsp
i have the exact opposite opinion. such circular buffers only suit limited
file system activities, such as logs. if you want editable config files of
varying lengths, you need a real fs. i'll concede that features like directory
structures and timestamps can be omitted though.

~~~
TickleSteve
No, you can do log-structured BLOBs which essentially given you version
control in a simple manner with circular buffers.

As for variable-length configs, yes, but you should always be allocating the
worst-case (i.e. defined maximum), hence no need for variable length.

