本应用笔记介绍了 RT-Thread 文件系统的基本知识和使用方法,帮助开发者更好地使用 RT-Thread 文件系统。并给出了在正点原子
STM32F429-apollo
开发板上验证的代码示例。
本文的目的和结构
本文的目的和背景
第一次接触 RT-Thread 文件系统的开发者可能觉得 RT-Thread 文件系统过于复杂,不知道该从何入手。想要在项目中使用文件系统,却不知道该怎么做。产生这种印象的原因是对 RT-Thread DFS 框架没有足够的了解,如果理解了 DFS 框架,在使用 RT-Thread 文件系统时就可以得心应手了。
为了能让开发者清楚地理解 RT-Thread DFS 框架的概念,学会使用 RT-Thread 文件系统。本应用笔记将一步步深入介绍 RT-Thread DFS 框架的相关知识以及实现原理。通过演示 shell 命令和使用示例的方式来操作文件系统,让开发者能够学会 RT-Thread 文件系统的使用方法。
本文的结构
本应用笔记将从以下三个方面来介绍 RT-Thread 文件系统:
-
RT-Thread DFS 框架
-
RT-Thread 文件系统的移植
-
RT-Thread 文件系统的使用
问题阐述
本应用笔记将围绕下面几个问题来介绍RT-Thread 文件系统。
-
如何移植各种类型的文件系统?
-
如何对文件系统进行操作?
-
如何在文件系统中对文件和文件夹进行操作?
想要解决这些问题,就要了解 RT-Thread DFS 框架。下面我们就通过 DFS 框架一步一步地将文件系统使用起来。
问题的解决
DFS 框架介绍
RT-Thread 的文件系统采用了三层结构,这种结构就是 RT-Thread DFS 框架。
下图为
RT-Thread 文件系统结构图
:
DFS 框架的最顶层是一套面向嵌入式系统,专门优化过的设备虚拟文件系统 POSIX 文件接口,中间层是各种文件系统的实现,最底层是各类存储设备驱动。
DFS 框架的来源
DFS 框架各层次说明
顶层:POSIX 文件接口层
中间层:文件系统实现层
底层:存储设备驱动层
文件系统的移植
准备工程
移植过程介绍
文件系统的移植主要包括下面几个方面:
-
开启/配置 DFS 框架
-
开启/配置 指定的文件系统
-
确保开发板上的存储设备驱动正常工作
通过 env 工具可以方便地开启文件系统,将所需的文件系统类型添加到工程中。
对存储设备进行功能测试,可以确保存储设备驱动是正常工作的。驱动程序的稳定工作是文件系统正常使用的基础。
文件系统的配置
使用 env 工具进入
rt-thread\bsp\stm32f429-apollo
目录,在命令行中输入
menuconfig
命令进入配置界面。
-
这里需要注意的是还需要进入到
elm-chan's FatFs, Generic FAT Filesystem Module
选项中修改关于长文件名支持的选项,否则在后面使用文件系统的过程中,创建的文件或者文件夹的名称不能超过 8 个字符。修改方式如下图所示:
-
因为要使用一些 C 库函数,所以需要打开
libc
功能:
存储设备初始化
开启 SPI 设备驱动
-
DFS 框架的文件系统实现层需要存储设备驱动层提供驱动接口用于对接,本次使用的存储设备为
SPI Flash
,底层设备初始化过程可以参考 《SPI 设备应用笔记》 。
-
重新打开 menuconfig 配置界面,在
RT-Thread Components → Device Drivers
界面中选中
Using SPI Bus/Device device drivers
以及
Using Serial Flash Universal Driver
选项,如下图所示:
检查存储设备驱动
创建存储设备
-
由于只有块设备类型的设备才能和文件系统对接,所以需要根据
SPI Device
找到
SPI Flash
设备,并创建与其对应的
Block Device
。
-
这里需要使用到万能 SPI Flash 驱动库:SFUD ,RT-Thread 已经集成了该组件,在上面的配置过程中我们已经开启这个功能。此时只需要使用 SFUD 提供的
rt_sfud_flash_probe
函数即可。该函数将执行如下操作:
-
如果开启了组件自动初始化功能,该函数会被自动执行,否则需要手动调用运行。
static int rt_hw_spi_flash_with_sfud_init(void)
{ if (RT_NULL == rt_sfud_flash_probe("W25Q256", "spi50"))
{ return RT_ERROR;
}; return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_with_sfud_init)
文件系统的使用
文件系统的初始化
RT-Thread 文件系统初始化过程一般按以下流程来进行:
-
初始化 DFS 框架
-
初始化具体文件系统
-
初始化存储设备
下面我们按照这样的顺序来逐步讲解文件系统的初始化过程:
DFS 框架的初始化
DFS 框架的初始化主要是对内部数据结构以及资源的初始化。这一过程包括初始化文件系统必须的数据表,以及互斥锁。该功能由如下函数完成。如果开启了组件自动初始化功能,该函数会被自动执行,否则需要手动调用运行。
中间层文件系统的初始化
这一步的初始化主要是将
elm FatFS
的操作函数注册到 DFS 框架中。该功能由如下函数完成。如果开启了组件自动初始化功能,该函数会被自动执行,否则需要手动调用运行。
存储设备的初始化
存储设备的初始化可以参考 《创建存储设备》章节。
创建文件系统
-
第一次使用
SPI Flash
作为文件系统地存储设备时,如果我们直接重启开发板来挂载文件系统,就会看到
spi flash mount to /spi failed!
的提示。这是因为此时在 SPI Flash 中还没有创建相应类型的文件系统,这就用到了创建文件系统 shell 命令:
mkfs
。
-
mkfs
命令的功能是在指定的存储设备上创建指定类型的文件系统。使用格式为:
mkfs [-t type] device
。第一次挂载文件系统前需要使用
mkfs
命令在存储设备上创建相应的文件系统,否则就会挂载失败。如果要在
W25Q256
设备上创建
elm
类型的文件系统,就可以使用
mkfs -t elm W25Q256
命令,使用方法如下图:
文件系统的挂载
文件系统的挂载指的是将文件系统和具体的存储设备关联起来,并挂载到某个挂载点,这个挂载点即为这个文件系统的根目录。在下面的示例中,我们将
elm FatFS
文件系统和名为
W25Q256
的存储设备关联起来,并且挂载到
/spi
文件夹中。(这里可以挂载到
/spi
文件夹的原因是
stm32f429-apollo BSP
的文件系统根目录已经挂载了
RomFS
,并且已经创建了
/spi
文件夹。如果没有特殊情况,文件系统可以直接挂载到根目录
/
上。)
文件与目录操作 shell 命令
在这一小节介绍关于文件和目录操作常用的 shell 命令:
-
ls
功能:显示文件和目录的信息,示例如下图:
-
cd
功能:切换到指定工作目录,示例如下图:
-
cp
功能:copy 文件,示例如下图:
-
rm
功能:删除文件或目录,示例如下图:
-
mv
功能:将文件移动位置或者改名,示例如下图:
-
echo
功能:将指定内容写入文件:
-
cat
功能:展示文件的内容,示例如下图:
-
pwd
功能:打印出当前目录地址,示例如下图:
-
mkdir
功能:创建文件夹,示例如下图:
文件操作示例
本节以创建文件夹操作为例,介绍如何使用 RT-Thread 文件系统 Sample 来对文件系统进行操作。