Using the LittleFS File System with STM32 Microcontroller Based on RT-Thread
Source: Embedded Learning and Practice
Author: Embedded Learning and Practice
1. Development Environment
- Hardware: STM32F407
- Software: RT-Thread v4.1.1
2. Overview of LittleFS
LittleFS is a lightweight file system developed by ARM, specifically designed for embedded systems. Compared to traditional file systems, LittleFS offers several advantages:
- Built-in Wear-Leveling
- Automatically balances flash memory erase cycles.
2. Power Failure Protection
- Ensures data integrity during unexpected power loss.
3. Low RAM/ROM Footprint
- Optimized for resource-constrained systems.
4. The built-in wear-leveling and power failure protection make LittleFS an ideal choice for developers looking to mount a file system onto NOR flash with confidence.
LittleFS Architecture on RT-Thread
The diagram below illustrates the layered architecture of LittleFS running within the RT-Thread ecosystem
Introduction
DFS Framework
The DFS (Device File System) framework is a virtual file system component provided by RT-Thread. It offers a unified POSIX-style interface for file and directory operations, such as read
, write
, and poll/select
. The DFS framework supports multiple file system types, including FatFS, RomFS, and DevFS, and manages standard files, device files, and network file descriptors.
MTD Device
MTD (Memory Technology Device) refers to a standardized interface for NOR and NAND flash memory. By using MTD devices, file systems are abstracted from the underlying flash storage, ensuring a unified and consistent interface.
FAL Component
FAL stands for Flash Abstraction Layer. It is an abstraction layer designed to manage and operate flash memory and flash-based partitions. FAL provides a unified API for flash and partition operations and includes APIs for creating partitions as MTD devices.
SFUD Component
SFUD (Serial Flash Universal Driver) is an open-source library for serial SPI flash devices. It supports most serial flash devices available on the market. By simply providing SPI or QSPI read/write interfaces, SFUD can identify and operate these devices. Additionally, RT-Thread provides FAL drivers adapted for SFUD, enabling seamless integration between the two components.
Developers utilize the unified POSIX APIs provided by the DFS framework. The DFS framework interacts with the LittleFS APIs, which in turn rely on MTD device read/write interfaces. Developers can leverage RT-Thread’s FAL and SFUD components to perform read/write operations on flash memory or implement custom MTD device drivers to allow LittleFS to be mounted on other types of storage media.
3. Porting LittleFS
To use LittleFS, developers only need to provide an MTD (Memory Technology Device). This can be achieved either by implementing a custom MTD device or by using RT-Thread’s FAL (Flash Abstraction Layer) component, which simplifies the creation process. Compared to constructing an MTD device directly using low-level flash functions, utilizing FAL offers several advantages:
- Ease of Creation:
- Creating an MTD device with FAL is straightforward and efficient.
2. Portability and Reusability:
- Drivers built with FAL are highly portable and reusable across different projects.
3. Partitioning Capability:
- FAL’s partitioning feature allows LittleFS to operate within specific regions of the flash memory, ensuring efficient and organized usage.
The porting process of LittleFS primarily involves the following aspects:
Steps for Setting Up LittleFS
- Enable/Configure the DFS Framework
- Provides a unified POSIX-style interface for file and directory operations for applications.
2. Enable the LittleFS Package
- Ensure the LittleFS file system package is enabled in the build configuration.
3. Enable MTD Devices
- MTD device support is disabled by default and needs to be manually enabled.
4. Enable FAL (Flash Abstraction Layer)
- Used for creating MTD devices easily and managing flash partitions.
5. Enable External Flash
- Automatically enables the SFUD (Serial Flash Universal Driver) as it serves as the physical medium for the file system.
6. Create MTD Devices
- Set up the MTD device for use with LittleFS.
7. Ensure Proper Storage Device Driver Functionality
- Verify that the storage device drivers on the development board are functioning correctly to avoid runtime issues.
Project Based on Using the Serial Flash Universal Driver (SFUD) with RT-Thread on STM32 Microcontrollers
Enable SPI Based on Actual Requirements
In the components configuration, check if the SFUD component is enabled. If it is not, enable it. Optionally, you can also enable debug logging for troubleshooting.
Enable fal
Configure MTD device
Enable LittleFS and select version 2.3.0. Using a version higher than this may cause errors, which could arise later in the process.
v2.3.0:
latest version:
Enable DFS file system
After completing the configuration, exit the settings interface and run pkgs-update
in the env command line.
Porting and Adapting the FAL File Interface
Move to the inc folder.
If the src folder does not exist, move it there as well.
Configure the Partition Table
Open the fal_cfg.h
file in the 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 MTD Device and Mount the File System
The FAL component does not include automatic initialization code, so it is necessary to initialize FAL within the main
function and use the provided API 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>
/* add fal head file*/
#include <fal.h>
/* add file system head file */
#include <dfs_fs.h>
/* add DEBUG head file*/
#define DBG_SECTION_NAME "main"
#define DBG_LEVEL DBG_INFO
#include <rtdbg.h>
/* define the name of partition */
#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); /* initiate fal */ fal_init();
/* generate mtd device*/
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
{
/* mount littlefs */
if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == 0)
{
LOG_I("Filesystem initialized!");
}
else
{
/* format file system */
dfs_mkfs("lfs", FS_PARTITION_NAME);
/* mount 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;
}
compile project and error occurs
packages\littlefs-latest\dfs_lfs.c(566): error: #393: pointer to incomplete class type is not allowed
The issue is due to using the latest version of LittleFS, which includes changes. Downgrading LittleFS to version 2.3.0 will resolve the issue.
4. Testing
Download the program to the development board and run tests. Check whether the FAL partition is working correctly, whether the MTD device is successfully created, and whether the file system is properly mounted. After compiling and downloading the project, verify if the system prints messages indicating successful creation of the FAL partition, MTD device, and file system initialization during startup.
The printed partition table and MTD device creation success messages are as follows:
Using the File System
RT-Thread supports a variety of file systems, all of which are integrated with the DFS framework. For upper-layer applications, the DFS framework provides a unified POSIX interface for file and directory operations. After switching to a different file system, developers can seamlessly port the existing code to the new file system without needing to modify the code.
// using ls command to check the currect directory info
msh />ls
Directory /:
msh />
msh />
//se the echo command to output the entered string to a specified location
msh />echo "123" 123.txt # Output the string to the file 123.txt
msh />
msh />ls
Directory /:
123.txt 3
msh />
msh />
//using cat command to check the file contents
msh />cat 123.txt
123
msh />
msh />
Reference:
https://club.rt-thread.org/ask/question/0fefb68b5b66cace.html