Using the LittleFS File System on STM32 Based on RT-Thread

7 min readMar 21, 2025

This article is contributed by Embedded Learning and Practice

1. Development Environment Overview

● Hardware: Based on the Firefly STM32F407 development board.

● Software: BSP project for STM32F407, built on RT-Thread version 4.1.1.

2. LittleFS Introduction

LittleFS is an embedded file system developed by ARM, designed specifically for embedded systems. Compared to traditional file systems, LittleFS offers the following advantages:

Built-in Wear Leveling: It automatically distributes write and erase cycles across memory to extend its lifespan.

Power Loss Protection: It is designed to safeguard data integrity in the event of unexpected power loss.

Minimal RAM/ROM Usage: It is lightweight, making it suitable for resource-constrained environments.

Safe for NOR Flash: With its built-in wear leveling and power loss protection, developers can confidently mount the file system on NOR Flash.

Here’s a visual representation of how LittleFS operates within the RT-Thread environment.

Terminology Explanation

DFS Framework

The DFS Framework, or Device File System, is a virtual file system component provided by RT-Thread. It offers a unified POSIX interface for file and directory operations, including functions like read, write, and poll/select. The DFS Framework supports multiple types of file systems, such as FatFS, RomFS, and DevFS, while also managing ordinary files, device files, and network file descriptors.

MTD Device

MTD, which stands for Memory Technology Device, provides a unified interface for NOR FLASH and NAND FLASH. It serves to isolate the file system from the underlying FLASH memory, abstracting the complexities of different flash technologies.

FAL Component

FAL, or Flash Abstraction Layer, is an abstraction layer that manages and operates on flash memory and flash-based partitions. It standardizes the API for flash and partition operations, allowing for easier interaction. FAL also provides an API for creating partitions as MTD devices.

SFUD Component

SFUD is an open-source universal driver library for serial SPI Flash. It supports most commercially available serial Flash devices. Users need only to provide the read and write interfaces for SPI or QSPI, and SFUD will automatically recognize and interface with the devices. Additionally, RT-Thread offers driver integration for SFUD within FAL, ensuring seamless compatibility between the two components.

Developers use the unified POSIX API provided by the DFS Framework, which internally calls LittleFS API functions. LittleFS accesses the read and write interfaces of MTD devices. Developers can use the FAL component and SFUD component provided by RT-Thread to perform read and write operations on FLASH. Alternatively, they can implement their own MTD device drivers to enable LittleFS to mount on a variety of storage media.

3. LittleFS Porting

To use LittleFS, developers only need to provide an MTD device. They may implement their own MTD device or easily create one using the FAL component provided by RT-Thread. Compared to directly using low-level FLASH functions to create an MTD device, using FAL to create an MTD device offers three key advantages:

Convenience: Creating an MTD device is straightforward.

Portability and Reusability: The drivers are highly portable and reusable across different settings.

Partition Functionality: FAL’s partitioning capabilities allow LittleFS to utilize only specified regions of FLASH.

The key aspects involved in porting LittleFS primarily include:

● Enable/Configure the DFS framework

○ Provide a unified interface for POSIX file and directory

● Enable LittleFS package

● Enable the MTD device

○ Not enabled by default

● Enable fal

○ Used to create the MTD device

● Enable external flash

○ SFUD is automatically enabled

○ Physical carrier for the filesystem

● Creating the MTD device

● Ensure that the storage device driver on the development board is working properly

The project is based on the usage of the Serial Flash Universal Driver (SFUD) on STM32 microcontrollers with RT-Thread.

Enable SPI based on actual selection

In the components section, check if the SFUD component is enabled. If it is not, enable it and optionally turn on the debug information.

Enable the FAL (Flash Abstraction Layer).

Configure the MTD (Memory Technology Device).

Enable LittleFS and select version 2.3.0, as versions above this will cause errors later on.

For version 2.3.0:

For the latest version:

Enable the DFS (Dynamic File System).

Once the settings are complete, exit the configuration interface and enter pkgs — update in the environment.

Adapt the FAL file interface.

Configure the partition table.

Open `fal_cfg.h` in your project and modify it as follows:

/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-17 armink the first version
*/

#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_

#include <rtconfig.h>
#include <board.h>

#define NOR_FLASH_DEV_NAME "W25Q128"

/* ===================== Flash device Configuration ========================= */

extern struct fal_flash_dev nor_flash0;

/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&nor_flash0, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "filesystem", NOR_FLASH_DEV_NAME, 0, 1024*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \
{FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME, 2*1024*1024, 14*1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */

#endif /* _FAL_CFG_H_ */

Create an MTD device and mount the file system.

The FAL component does not include automatic initialization code, so you need to initialize FAL in the main function. Use the APIs provided by FAL to create an MTD device. Once the MTD device is created, you can mount LittleFS on the newly created MTD device.

The test code is as follows:

/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 SummerGift first version
* 2018-11-19 flybreak add stm32f407-atk-explorer bsp
*/

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
/* 添加 fal 头文件 */
#include <fal.h>
/* 添加文件系统头文件 */
#include <dfs_fs.h>

/* 添加 DEBUG 头文件 */
#define DBG_SECTION_NAME "main"
#define DBG_LEVEL DBG_INFO
#include <rtdbg.h>
/* 定义要使用的分区名字 */
#define FS_PARTITION_NAME "filesystem"

/* defined the LED0 pin: PF7 */
#define LED0_PIN GET_PIN(F, 7)

int main(void)
{
struct rt_device *mtd_dev = RT_NULL;

rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
/* 初始化 fal */

fal_init();
/* 生成 mtd 设备 */
mtd_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);
if (!mtd_dev)
{
LOG_E("Can't create a mtd device on '%s' partition.", FS_PARTITION_NAME);
}
else
{
/* 挂载 littlefs */
if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == 0)
{
LOG_I("Filesystem initialized!");
}
else
{
/* 格式化文件系统 */
dfs_mkfs("lfs", FS_PARTITION_NAME);
/* 挂载 littlefs */
if (dfs_mount("filesystem", "/", "lfs", 0, 0) == 0)
{
LOG_I("Filesystem initialized!");
}
else
{
LOG_E("Failed to initialize filesystem!");
}
}
}

while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);
}

return RT_EOK;
}

Compilation Error

packages\littlefs-latest\dfs_lfs.c(566): error:  #393: pointer to incomplete class type is not allowed

When compiling the project, you may encounter an error. This is due to the use of the latest version of LittleFS, which has undergone changes. To resolve this, you should downgrade LittleFS to version 2.3.0.

Test

Download the program to the development board for testing. Verify whether the FAL partitions are functioning correctly, if the MTD device has been successfully created, and whether the file system is mounted properly. After compiling and downloading the project, check the system startup logs for messages indicating successful creation of the FAL partition, the MTD device, and the initialization of the file system.

The output for the partition table and the success message for MTD device creation should look like the following:

Using the File System

RT-Thread supports various file systems, but all of them interface with the DFS (Dynamic File System) framework. The DFS framework provides a unified POSIX-compliant interface for file and directory operations for upper-layer applications. This means that developers can switch file systems seamlessly, allowing existing code to be easily ported to the new file system without modification.

// 使用 ls 命令查看当前目录信息
msh />ls
Directory /:
msh />
msh />

//使用 echo 命令将输入的字符串输出到指定输出位置
msh />echo "123" 123.txt # 将字符串出输出到 123.txt 文件
msh />
msh />ls
Directory /:
123.txt 3
msh />
msh />

//使用 cat 命令查看文件内容
msh />cat 123.txt
123
msh />
msh />

Reference

For guidance on using the LittleFS file system on STM32L4, you can refer to the following link:https://club.rt-thread.org/ask/question/0fefb68b5b66cace.html

--

--

RT-Thread IoT OS
RT-Thread IoT OS

Written by RT-Thread IoT OS

An Open-Source Community-Powered Real-Time Operating System (RTOS) Project! Let’s develop, DIY, create, share, and explore this new IoT World together!

No responses yet