当前位置: 首页 > article >正文

stm32单片机基于rt-thread 的 littlefs 文件系统 的使用

一、开发环境介绍

硬件:基于野火stm32f407 开发板
软件:基于rt-thread v4.1.1版本的 stm32f407-atk-explorer bsp工程。

二、littlefs 简介

littlefs 是 ARM 官方推出的,专为嵌入式系统设计的文件系统,相比传统的文件系统,littlefs 具有以下优点:
1、自带擦写均衡
2、支持掉电保护
3、占用的 RAM/ROM 少
4、littlefs 自带的擦写均衡和掉电保护使开发者可以放心的将文件系统挂载到 nor flash 上。
littlefs 在 RT-Thread 上运行的层级关系图
在这里插入图片描述
名词解释
DFS 框架
DFS 框架 是 RT-Thread 提供的虚拟文件系统组件,全称为 Device File System,即设备虚拟文件系统。DFS 框架为应用程序提供统一的 POSIX 文件和目录操作接口,如 read、write、poll/select 等。DFS 框架支持多种类型的文件系统,如 FatFS、RomFS、DevFS 等,并提供普通文件、设备文件、网络文件描述符的管理。

MTD 设备
MTD 设备,全称为 Memory Technology Device,使用 MTD 设备为 NOR FLASH 和 NAND FLASH 提供统一接口,将文件系统与底层 FLASH 存储器进行了隔离。

fal 组件
fal 全称为 Flash Abstraction Layer,即 Flash 抽象层,是对 Flash 及基于 Flash 的分区进行管理、操作的抽象层,对上层统一了 Flash 及 分区操作的 API。并提供了将分区创建成 MTD 设备的 API。

SFUD 组件
SFUD 是一款开源的串行 SPI Flash 通用驱动库。现有市面的大部分串行 Flash,用户只需要提供 SPI 或 QSPI 的读写接口,SFUD 就可以识别并驱动。同时 RT-Thread 提供了 FAL 针对 SFUD 的驱动移植,可以使两个组件无缝连接。

开发者使用的是 DFS 框架提供的统一的 POSIX API,DFS 框架会调用 littlefs 的 API,littlefs 会使用 MTD 设备的读写接口,开发者可以使用 RT-Thread 提供的 fal 组件和 SFUD 组件来完成对 FLASH 的读写任务,也可以自己实现 MTD 设备的驱动程序,使 littlefs 可以挂载到更多的存储介质上。

三、littlefs 移植

开发者只需要提供一个 MTD 设备即可使用 littlefs。开发者可以自己实现一个 MTD 设备,也可以利用 RT-Thread 提供的 fal 组件,非常方便的创建出一个 MTD 设备。相比于直接使用 flash 底层函数来自己构造一个 MTD 设备,使用 fal 创建 MTD 设备有以下三个优点:
1、创建 MTD 设备方便。
2、驱动的可移植性和可重用性强。
3、fal 的分区功能可以让 littlefs 只使用指定区域的 flash。

littlefs 的移植主要包括下面几个方面:
在这里插入图片描述
工程基于 <stm32单片机基于rt-thread 的 串行 Flash 通用驱动库 SFUD 的使用>

**开启SPI,根据实际选择 **
在这里插入图片描述
在这里插入图片描述
在组件中,查看 SFUD 组件是否开启,没开启则需要开启,打开调试信息(可选)
在这里插入图片描述
开启 fal
在这里插入图片描述
配置 MTD 设备
在这里插入图片描述
开启littlefs,选择V2.3.0版本,高于此版本会报错,后面会遇到。
在这里插入图片描述
v2.3.0版本:
在这里插入图片描述

latest 版本:
在这里插入图片描述

开启DFS文件系统
在这里插入图片描述

设置完成后,退出配置界面,在 env 中输入 pkgs --update
在这里插入图片描述
fal文件接口移植适配
在这里插入图片描述
在这里插入图片描述
配置分区表
打开工程中的 fal_cfg.h,修改如下:

/*
 * 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_ */

创建 MTD 设备并挂载文件系统
fal 组件并没有加入自动初始化的代码,所以需要在 main 函数中初始化 fal,并使用 fal 提供的 API 来创建一个 MTD 设备。创建 MTD 设备后,就可以将 littlefs 挂载到刚刚生成的 MTD 设备上了。

测试代码如下:

/*
 * 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;
}

编译工程,报错

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

在这里插入图片描述
原因是使用的 littlefs 最新版本,最新版本做了修改。降级 littlefs 版本即可,降到V2.3.0版本。

四、测试

将程序下载到开发板,进行测试。检查 fal 分区是否正常,MTD 设备是否创建成功,文件系统有没有挂载成功。将工程编译下载,查看系统启动时是否打印了 fal 分区、 MTD 设备创建成功和文件系统初始化成功的提示信息。

分区表的打印和 MTD 设备创建成功的提示信息如下所示:

在这里插入图片描述
文件系统的使用
RT-thread 支持的文件系统很多,但是所有的文件系统都对接到 DFS 框架。对于上层应用,DFS 框架提供了统一的 POSIX 文件和目录操作接口。开发者更换文件系统后,可以将原来的代码无缝的移植到新的文件系统上而不需要修改代码。

// 使用 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 />

参考:
在 STM32L4 上应用 littlefs 文件系统

https://club.rt-thread.org/ask/question/0fefb68b5b66cace.html


http://www.kler.cn/news/368486.html

相关文章:

  • ReactOS系统中平衡二叉树。给定地址超导其所属区块MmFindRegion()
  • Python的协程与传统的线程相比,是否能更有效地利用计算资源?在多大程度上,这种效率是可测量的?如何量化Python协程的优势|协程|线程|性能优化
  • Python酷库之旅-第三方库Pandas(170)
  • 基于huggingface训练数据处理(load_dataset、map、data_loader等内容)
  • 使用Python计算相对强弱指数(RSI)进阶
  • Vue 3 的组件式开发(3)
  • 使用Python Pillow库生成九宫格图片
  • ICP之点云特征计算
  • Python浪漫之画星星
  • Swarm集群管理常用命令与详解
  • Java程序设计:spring boot(8)——API ⽂档构建⼯具 - Swagger2
  • 论文略读:AnyGPT: Unified Multimodal LLM with Discrete Sequence Modeling
  • python学习记录11
  • 【云原生】云原生后端:网络架构详解
  • Springboot项目中使用WebSocket与前端通信时,AOP的before注解未起作用
  • 探索网页组件化:原生JavaScript动态加载HTML与iframe的使用与比较
  • 基于IMX6ULL开发板LCD点阵显示字符学习
  • FreeSWITCH JSON API
  • 【服务器】服务器部署后端,开放后端端口
  • stm32 开发环境的 搭建
  • Oracle 运维相关概念及操作
  • 逻辑推理学习笔记
  • [mysql]单行函数的练习
  • css知识点梳理2
  • 【论文阅读】PGAN
  • 【北京迅为】《STM32MP157开发板嵌入式开发指南》-第六十七章 Trusted Firmware-A 移植