LittleFS File System with MCU Internal FLASH Memory

In many of my embedded projects I need persistent data or storage for settings. If using an SD card, then FatFS is usually my choice for the file system. But if using an external FLASH memory device, then my preferred choice is usually LittleFS: it is a little fail-safe filesystem, designed for micro-controllers, which I’m using with external flash memory devices.

In the case where there is enough MCU flash, or if there is no external FLASH device available in a design, it can use the MCU internal FLASH as storage storage too. This is the topic of this article:

LittleFS File System Data

Outline

In this project I’ll show you how you can get quickly up and running using LittleFS with FreeRTOS, using the internal flash memory of the MCU. The project used in this article is running with FreeRTOS on the NXP LPC55S16-EVK board.

NXP LPC55S16-EVK Board

Project

First, create a project using the IDE for the device used (in this case, the LPC55S16). You can follow the steps below and/or use the project on GitHub (LPC55S16_Blinky).

McuLib

Add the McuLib to the project. This comes with FreeRTOS plus the littleFS file system. Alternatively you can use the littleFS and FreeRTOS from the NXP SDK, or directly from freeRTOS.org and LittleFS Github.

Configuration

Next, the LittleFS middleware needs to be configured. I’m usually doing this inside header file (source/IncludeMcuLibConfig.h).

First, we need to configure the flash memory: we enable the module, specify the number of flash blocks to be used. The LPC55S16 has 244 KByte of flash, and we allocate the blocks at the end of the memory:

#define McuFlash_CONFIG_IS_ENABLED                    (1) /* enable McuFlash module */
#define McuFlash_CONFIG_NOF_BLOCKS                    (32) /* number of flash blocks */
#define McuFlash_CONFIG_MEM_START                     (((0+244*1024)-((McuFlash_CONFIG_NOF_BLOCKS)*McuFlash_CONFIG_FLASH_BLOCK_SIZE)))

Below is how to enable the file system:

#define LITTLEFS_CONFIG_ENABLED  (1) /* enable the LittleFS file system */

Next, we set the system to use a FLASH based file system

#define McuLittleFSBlockDevice_CONFIG_MEMORY_TYPE McuLittleFSBlockDevice_CONFIG_MEMORY_TYPE_MCU_FLASH

Finally, we have to configure the block size, block count and the block offset. The offset is used as start address inside the memory:

#define McuLittleFS_CONFIG_BLOCK_SIZE                 (McuFlash_CONFIG_FLASH_BLOCK_SIZE)
#define McuLittleFS_CONFIG_BLOCK_COUNT                (McuFlash_CONFIG_NOF_BLOCKS)
#define McuLittleFS_CONFIG_BLOCK_OFFSET             ((McuFlash_CONFIG_MEM_START)/(McuFlash_CONFIG_FLASH_BLOCK_SIZE))

Initialization

To use the file system, I have to initialize it. So I have to call the ‘init’ both for the flash module and the file system module:

McuFlash_Init(); /* initialize flash module */
McuFlash_RegisterMemory((const void*)McuFlash_CONFIG_MEM_START, McuFlash_CONFIG_NOF_BLOCKS*McuFlash_CONFIG_FLASH_BLOCK_SIZE);
McuLFS_Init(); /* initialize LittleFS */

Mounting the file system

To use the file system, I have to mount it:

McuLFS_Mount(McuShell_GetStdio());

Mounting the file system is done usually inside a task.

After that, the LittleFS file system can be used for reading and writing.

Example with Command Line Shell

Everything can be used from a command line shell. For this, connect with a terminal program to the board (UART or USB CDC/VCOM connection). The ‘help’ command shows the availble commands. Most important for our use here are are the ‘McuLittleFS’ and ‘McuFlash’ sections:

McuShell help output

As the LPC55Sxx use a special type of flash memory, the commands to initialize and erase the memory can be very useful during development. So for example if the flash is only in the initialized state, you have to erase it first:

McuFlash erase 0x00039000 0x4000

The ‘status’ commands can be used to show the current settings and status:

Shell status command

In the case above, the file system has not been mounted yet, and the memory has not been formatted yet. Use the following:

McuLittleFS format

To mount it, I can use

McuLittleFS mount

After that, the file system can be used to write and read files, for example:

McuLittleFS ls
McuLittleFS bincat test.txt 0x1 0x2 0x3 0x4 0x5
McuLittleFS printhex test.txt
LittleFS example session

Summary

An embedded file system to store and use data on the device is very useful. In many applications I’m using the LittleFS file system: it is optimized for embedded systems, works nicely with FreeRTOS and can be easily used with on-chip and off-chip flash devices. I hope with the provided example and instructions you can easily use it in your projects.

Do not need a file system to store settings? Then have a look at MinINI which can be used file-system-less.

Happy Flashing 🙂

Links

8 thoughts on “LittleFS File System with MCU Internal FLASH Memory

  1. Interesting post as usual Erich. 👍
    Small typo:
    > Next, the LittleFS middlewar[e] needs to be configured.

    Like

  2. Thanks for the intro to littleFS. More than anything else, the Design Document is worthy of mention as a good case study and reference on file system concepts and design. It manages to summarize most of the important issues in a concise writeup, with examples even.

    Like

  3. I so wish I’d known about this 5 years ago! I basically rolled my own data log storage in external flash, and it was the most non-robust part of the system.
    Thanks Erich.

    Like

    • Hi Rhys,
      yes, that’s what I did too, until I jumped on FatFS (around 8 years ago). FatFS is great if you have a large memory (e.g. eMMC or SD card slot), but was not reliable enough, especially if power gets lost while writing data. LittleFS has a transaction system, and we never had a system failing with it.

      Like

  4. I usually need to manage some non volatile parameters (mostly user settings or device-dependent calibration values).
    Doesn’t LittleFS with a single file (the one that stores non volatile settings) add a complex layer that isn’t strictly needed? Would you use LittleFS even if you needs to save a few parameters?

    Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.