Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread进阶笔记之虚拟文件系统
发布于 2020-06-29 11:16:20 浏览:2118
订阅该版
* 本帖最后由 Aladdin-Wang 于 2020-6-29 11:22 编辑 * **1.引入 ****1.1 文件系统引入**在早期的嵌入式系统中,需要存储的数据比较少,数据类型也比较单一,往往使用直接在存储设备中的指定地址写入数据的方法来存储数据。然而随着嵌入式设备功能的发展,需要存储的数据越来越多,也越来越复杂,这时仍使用旧方法来存储并管理数据就变得非常繁琐困难。因此我们需要新的数据管理方式来简化存储数据的组织形式,这就是文件系统的由来。**1.2 虚拟文件系统引入**为了统一众多不同类型的文件系统,虚拟文件系统对实际文件系统进行抽象,采用统一的文件系统向用户提供相应的一组统一的标准的文件操作接口(open,read,close,select,poll等)。**2 DFS 简介**DFS( Device File System)是一种抽象的文件机制,RT-Thread中对文件系统的相关操作实际上都是通过操作DFS实现,也就是说DFS是对各种文件系统的抽象。DFS使的其他部分无须关心不同文件系统之间的差异,使得RT-Thread可以支持多种类型的文件系统。**3 DFS 框架**RT-Thread DFS 组件的主要功能特点有:* 为应用程序提供统一的 POSIX 文件和目录操作接口:read、write、poll/select 等。 * 支持多种类型的文件系统,如 FatFS、RomFS、DevFS 等,并提供普通文件、设备文件、网络文件描述符的管理。 * 支持多种类型的存储设备,如 SD Card、SPI Flash、Nand Flash 等。 DFS 的层次架构如下图所示,主要分为 POSIX 接口层、虚拟文件系统层和设备抽象层。 ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepJV1IFXy1xHXj4CKh1jBySyH6IjXTCgUOVFYoPWfBskibQ8Vciaa2fEaA/640?wx_fmt=png) **POSIX 接口层:** POSIX 表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写 POSIX),POSIX 标准定义了操作系统应该为应用程序提供的接口标准,是 IEEE 为要在各种 UNIX 操作系统上运行的软件而定义的一系列 API 标准的总称。 **虚拟文件系统层:** 用户可以将具体的文件系统注册到 DFS 中,如 FatFS、RomFS、DevFS 等。 **设备抽象层:** 设备抽象层将物理设备如 SD Card、SPI Flash、Nand Flash,抽象成符合文件系统能够访问的设备,例如 FAT 文件系统要求存储设备必须是块设备类型。 不同文件系统类型是独立于存储设备驱动而实现的,因此把底层存储设备的驱动接口和文件系统对接起来之后,才可以正确地使用文件系统功能。**4 DFS 数据结构****文件系统操作表:**```
1
const
struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
``` **文件系统表:**```
1
struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX];
``` **文件描述符:**```
1
static
struct dfs_fdtable _fdtab;
``` **5 虚拟文件系统使用步骤**[list=1] (*)初始化 DFS 组件。 (*)注册具体类型的文件系统。 (*)挂载文件系统 (*)当文件系统不再使用,可以将它卸载。 [/list]**5.1 初始化 DFS 组件**dfs_init() 函数会初始化 DFS 所需的相关资源,创建一些关键的数据结构, 有了这些数据结构,DFS 便能在系统中找到特定的文件系统,并获得对特定存储设备内文件的操作方法。 dfs_init()加入了自动初始化机制,在系统上电后会自动运行dfs_init()。1INIT_PREV_EXPORT(dfs_init); **实例化DFS 组件相关的数据结构**```
1
const
struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
``````
1
struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX]
``` ```
1
static
struct dfs_fdtable _fdtab
``` 创建当前目录表```
1
char
working_directory[DFS_PATH_MAX] = {
"/"
}``` **初始化 DFS:*** 清除文件系统操作表 * 清除文件系统表 * 清除文件描述符表 * 初始化互斥量 * 设置当前工作目录为“/” **5.2 注册具体类型的文件系统**在 DFS 组件初始化之后,还需要初始化使用的具体类型的文件系统,也就是将具体类型的文件系统注册到 DFS 中。注册文件系统的接口如下所示:1int dfs_register(const struct dfs_filesystem_ops *ops); * 检查这个文件系统是否已经存在于文件系统操作表的目录中 * 在文件系统操作表中找出一个空的文件类型条目 * 将这个文件系统的数据结构地址赋值给空的文件系统操作表目录 **5.3 挂载文件系统**在挂载文件系统之前,如果是用作存储设备,还需要先存储设备注册为块设备,然后格式化成对应的文件系统后,才能挂载。 在 RT-Thread 中,挂载是指将一个存储设备挂接到一个已存在的路径上。我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的路径上,然后通过这个路径来访问存储设备。挂载文件系统的接口如下所示:```
1
int dfs_mount(const char *device_name, 2 const char *path, 3 const char *filesystemtype, 4 unsigned long rwflag, 5 const void *data)
;``` * 在文件系统操作表中找出特定的文件系统 * 为特殊文件系统建立完整路径 * 检查路径是否存在 * 检查文件系统是否挂载在文件系统表中 * 检查文件系统表是否有空余,如果有,把空余地址指向给此文件系统 * 注册文件系统 * 调用此文件系统的挂载接口 **5.4 卸载文件系统**当某个文件系统不需要再使用了,那么可以将它卸载掉。卸载文件系统的接口如下所示:1int dfs_unmount(const char *specialfile); * 检查路径是否存在 * 在文件系统表中找到此文件系统 * 清除文件系统表的这个条目内容 * 调用此文件系统的卸载接口 **6 文件系统实例演示****6.1 devfs文件系统****6.1.1 简介**devfs是设备文件系统,设备文件系统是用来把一切设备都抽象为像文件那样操作(如可读,可写)。 devfs默认挂载在"/dev"路径下。但是会发现在根目录下使用shell 的ls命令不能看到“/dev”目录, 但是cd "/dev" 能进入dev 目录 ,并且进入dev目录后也能显示dev下的设备。 因为根目录“/"下并没有创建任何文件夹,所以在根目录下ls命令自然看不到“/dev”目录。由于挂载文件系统需要挂载在一个已存在的路径上,devfs属于特殊文件系统,DFS为devfs设备文件系统注册时设置了专门的“/dev”路径以供设备文件系统挂载。```
1
/* Check if the path exists or not, raw APIs call, fixme */
2
if
((
strcmp
(fullpath,
"/"
) !=
0
) && (
strcmp
(fullpath,
"/dev"
) !=
0
))
3
{
4
struct dfs_fd fd;
5
6
if
(dfs_file_open(&fd, fullpath, O_RDONLY | O_DIRECTORY) <
0
)
7
{
8
rt_free(fullpath);
9
rt_set_errno(-ENOTDIR);
10
11
return
-1
;
12
}
13
dfs_file_close(&fd);
14
}``` **6.1.2 注册devfs文件系统**如果开启了DFS,devfs设备文件系统会在dfs_init()里自动初始化和挂载。```
1
#ifdef RT_USING_DFS_DEVFS
2
{
3
extern int devfs_init(void)
;
4
5
/* if enable devfs, initialize and mount it as soon as possible */
6
devfs_init();
7
8
dfs_mount(
NULL
,
"/dev"
,
"devfs"
,
0
,
0
);
9
}
10
#endif
``` **设置devfs文件系统的数据结构:_device_fs**```
1
static
const
struct dfs_filesystem_ops _device_fs = 2{
3
"devfs"
,
4
DFS_FS_FLAG_DEFAULT,
5
&_device_fops,
6
7
dfs_device_fs_mount,
8
RT_NULL,
9
RT_NULL,
10
RT_NULL,
11
12
RT_NULL,
13
dfs_device_fs_stat,
14
RT_NULL,
15
};``` **将devfs文件系统的数据结构挂载到文件系统操作表里**```
1
int devfs_init(void) 2
{
3
/* register rom file system */
4
dfs_register(&_device_fs);
5
6
return
0
;
7
}``` * 检查devfs文件系统是否已经存在于文件系统操作表的目录中 * 在文件系统操作表中找出一个空的文件类型条目 * 将devfs文件系统的数据结构_device_fs地址赋值给空的文件系统操作表目录 **文件系统操作表filesystem_operation_table的第一个目录:** ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepicFLtK8fMJAS0aUWriarRNJbRibTyn6ibhntDEGqoYMclic7aITZDb7pIlA/640?wx_fmt=png)**6.1.2 挂载devfs文件系统**1dfs_mount(NULL, "/dev", "devfs", 0, 0) * 在文件系统操作表中找出devfs文件系统 * 跳过检查"/dev"路径是否存在 * 检查devfs文件系统是否已经挂载在文件系统表中 * 检查文件系统表是否有空余,如果有,把空余地址赋值给devfs文件系统 * 注册文件系统 * 调用devfs文件系统的挂载接口 **文件系统表filesystem_table的第一个目录:** ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALep5BJ3Ix1WibrQxvUnh4jLKRbsydR9y1X0XIa1YLnHkFbKsEia4TIRZEDw/640?wx_fmt=png)**6.1.3 测试devfs文件系统**在根目录下使用shell 的cd命令切换到/dev目录,然后使用ls命令: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepMlTGve48iaNUj76GBngicS5AbfiabqPUncZTassNR1jEoeB8QvuiakI39A/640?wx_fmt=png) **6.2 RomFS文件系统****6.2.1 简介**RomFS是在嵌入式设备上常用的一种文件系统,具备体积小,可靠性高,读取速度快等优点,常用来作为系统初始文件系统。但也具有其局限性,RomFS是一种只读文件系统。**6.2.2 注册devfs文件系统**把RomFS当作初始文件系统rootfs挂载在根目录,在RomFS里创建几个目录,用于其他文件系统的挂载点。 更改… omfs.c文件,添加mnt文件夹和user文件夹。```
1
#include
2
#include
3
4
static
const
struct romfs_dirent _romfs_root[] = {
5
{ROMFS_DIRENT_DIR,
"mnt"
, RT_NULL,
0
},
6
{ROMFS_DIRENT_DIR,
"user"
, RT_NULL,
0
}
7
};
8
9
const
struct romfs_dirent romfs_root = {
10
ROMFS_DIRENT_DIR,
"/"
, (
rt_uint8_t
*)_romfs_root,
sizeof
(_romfs_root)/
sizeof
(_romfs_root[
0
])
11
};``` **设置romfs文件系统的数据结构:_romfs**```
1
static
const
struct dfs_filesystem_ops _romfs = 2{
3
"rom"
,
4
DFS_FS_FLAG_DEFAULT,
5
&_rom_fops,
6
7
dfs_romfs_mount,
8
dfs_romfs_unmount,
9
NULL
,
10
NULL
,
11
12
NULL
,
13
dfs_romfs_stat,
14
NULL
,
15
};``` **将romfs文件系统的数据结构挂载到文件系统操作表里**```
1
int dfs_romfs_init(void) 2
{
3
/* register rom file system */
4
dfs_register(&_romfs);
5
return
0
;
6
}``` 7INIT_COMPONENT_EXPORT(dfs_romfs_init);//自动初始化 * 检查romfs文件系统是否已经存在于文件系统操作表的目录中 * 在文件系统操作表中找出一个空的文件类型条目 * 将romfs文件系统的数据结构_romfs地址赋值给空的文件系统操作表目录 **文件系统操作表filesystem_operation_table的第二个目录:** ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepKPYWLR6ib0bXibPyicqm06ef4GSWXibl2GquicAib3GAX06SxfRt9pImYaicw/640?wx_fmt=png)**6.2.3 挂载romfs文件系统** ```
1
int mnt_init(void) 2
{
3
if
(dfs_mount (RT_NULL,
"/"
,
"rom"
,
0
,&(romfs_root)) ==
0
)
4
{
5
rt_kprintf(
"ROM file system initializated;
"
);
6
}
7
else
8
{
9
rt_kprintf(
"ROM file system initializate failed;
"
);
10
}
11
return
0
;
12
}
13
INIT_ENV_EXPORT(mnt_init);``` * 在文件系统操作表中找出romfs文件系统 * 检查"/"路径是否存在 * 检查romfs文件系统是否已经挂载在文件系统表中 * 检查文件系统表是否有空余,如果有,把空余地址指向romfs文件系统 * 注册文件系统 * 调用romfs文件系统的挂载接口 **文件系统表filesystem_table的第二个目录:** ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepbwZwFwXvc58iayKhfx4scHodfr5NZtt5iaTymoxJcltP5ohHF7pvOKVQ/640?wx_fmt=png) **6.2.4 测试RomFS文件系统**在根目录下使用shell 的ls命令: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALep2YkYyLDicZhEUtq21VIL62ILy2v6t94xNCdljm9zeS7h3esChHPDQzw/640?wx_fmt=png) **6.3 RamFS文件系统****6.3.1 简介**RamFS是内存文件系统,它不能格式化,可以同时创建多个,在创建时可以指定其最大能使用的内存大小。其优点是读写速度很快,但存在掉电丢失的风险。如果一个进程的性能瓶颈是硬盘的读写,那么可以考虑在RamFS上进行大文件的读写操作。 RT-Thread的RamFS设计之初未考虑支持文件夹,所以不能使用mkdir。**6.3.2 注册RamFS文件系统****设置ramfs文件系统的数据结构:_ramfs**```
1
static
const
struct dfs_filesystem_ops _ramfs = 2{
3
"ram"
,
4
DFS_FS_FLAG_DEFAULT,
5
&_ram_fops,
6
7
dfs_ramfs_mount,
8
dfs_ramfs_unmount,
9
NULL
,
/* mkfs */
10
dfs_ramfs_statfs,
11
12
dfs_ramfs_unlink,
13
dfs_ramfs_stat,
14
dfs_ramfs_rename,
15
};``` **将ramfs文件系统的数据结构挂载到文件系统操作表里**```
1
int dfs_ramfs_init(void) 2
{
3
/* register ram file system */
4
dfs_register(&_ramfs);
5
6
return
0
;
7
}
8
INIT_COMPONENT_EXPORT(dfs_ramfs_init);``` * 检查ramfs文件系统是否已经存在于文件系统操作表的目录中 * 在文件系统操作表中找出一个空的文件类型条目 * 将ramfs文件系统的数据结构_ramfs地址赋值给空的文件系统操作表目录 **文件系统操作表filesystem_operation_table的第三个目录:** ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALephrq7e0ketNSAzJqsEgsiaUjakgtqOZ94AK0rAic2dqoibduLXCibQc671Q/640?wx_fmt=png) **6.3.3 挂载RamFS文件系统** ```
1
int mnt_ram_elminit(void) 2
{
3
if
(dfs_mount (RT_NULL,
"/mnt"
,
"ram"
,
0
,dfs_ramfs_create(rampool,
1024
)) ==
0
)
4
{
5
rt_kprintf(
"ram file system initializated;
"
);
6
}
7
else
8
{
9
rt_kprintf(
"ram file system initializate failed;
"
);
10
}
11
return
0
;
12
}
13
INIT_ENV_EXPORT(mnt_ram_elminit);``` * 在文件系统操作表中找出ramfs文件系统 * 检查"/mnt"路径是否存在 * 检查ramfs文件系统是否已经挂载在文件系统表中 * 检查文件系统表是否有空余,如果有,把空余地址指向ramfs文件系统 * 注册文件系统 * 调用ramfs文件系统的挂载接口 **文件系统表filesystem_table的第三个目录:** ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepetnO3h9saZQOwuIJqP0OXfKt1rKEDGbvvJvzItOxg3hXSUewJuKZNw/640?wx_fmt=png) **6.3.4 测试RamFS文件系统**在根目录下使用shell 的cd命令切换到/mnt目录,然后使用ls命令: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepfMOqLKenlSUibC81FtGbsEHFiagnjicP10GC6myCF4ymbUZRuJldDcAZw/640?wx_fmt=png) **6.4 elm-FAT文件系统****6.4.1 简介**FatFs 是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。**6.4.2 使用流程*** 初始化 DFS 组件。 * 初始化具体类型的文件系统。 * 在存储器上创建块设备。 * 格式化块设备。 * 挂载块设备到 DFS 目录中。 * 当文件系统不再使用,可以将它卸载 **6.4.3 注册elm-FAT文件系统****设置fatfs文件系统的数据结构:dfs_elm**```
1
static
const
struct dfs_filesystem_ops dfs_elm = 2{
3
"elm"
,
4
DFS_FS_FLAG_DEFAULT,
5
&dfs_elm_fops,
6
7
dfs_elm_mount,
8
dfs_elm_unmount,
9
dfs_elm_mkfs,
10
dfs_elm_statfs,
11
12
dfs_elm_unlink,
13
dfs_elm_stat,
14
dfs_elm_rename,
15
};``` **将fatfs文件系统的数据结构挂载到文件系统操作表里**```
1
int elm_init(void) 2
{
3
/* register fatfs file system */
4
dfs_register(&dfs_elm);
5
6
return
0
;
7
}
8
INIT_COMPONENT_EXPORT(elm_init);``` * 检查fatfs文件系统是否已经存在于文件系统操作表的目录中 * 在文件系统操作表中找出一个空的文件类型条目 * 将fatfs文件系统的数据结构dfs_elm 地址赋值给空的文件系统操作表目录 elm-FAT文件系统注册过程如下图所示: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepwbC8iabtIEZhEXj0NvvMeny5ZgUW6v1kp7LefhCkRempruBqXm9VPAw/640?wx_fmt=png) **6.4.4 挂载elm-FAT文件系统** ```
1
void sd_mount(void *parameter) 2
{
3
while
(
1
)
4
{
5
rt_thread_mdelay(
500
);
6
if
(rt_device_find(
"sd0"
) != RT_NULL)
7
{
8
if
(dfs_mount(
"sd0"
,
"/fatfs"
,
"elm"
,
0
,
0
) == RT_EOK)
9
{
10
LOG_I(
"sd card mount to '/fatfs'"
);
11
break
;
12
}
13
else
14
{
15
LOG_W(
"sd card mount to '/fatfs' failed!"
);
16
}
17
}
18
}
19
}
20
21
int stm32_sdcard_mount(void) 22
{
23
rt_thread_t
tid;
24
25
tid = rt_thread_create(
"sd_mount"
, sd_mount, RT_NULL,
26
1024
, RT_THREAD_PRIORITY_MAX -
2
,
20
);
27
if
(tid != RT_NULL)
28
{
29
rt_thread_startup(tid);
30
}
31
else
32
{
33
LOG_E(
"create sd_mount thread err!"
);
34
}
35
return
RT_EOK;
36
}
37
INIT_APP_EXPORT(stm32_sdcard_mount);``` * 在文件系统操作表中找出elm文件系统 * 检查"/fatfs"路径是否存在 * 检查elm文件系统是否已经挂载在文件系统表中 * 检查文件系统表是否有空余,如果有,把空余地址指向elm文件系统 * 注册文件系统 * 调用elm文件系统的挂载接口 **6.4.5 测试elm-FAT文件系统**在根目录下使用shell 的cd命令切换到/fatfs目录,然后使用ls命令: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepAUzmWD4ibhTHia3csUBmDyrjCaia1EEUCOmRic81OLZ9oXsiboBBv6MUyeA/640?wx_fmt=png) **6.5 littlefs文件系统****6.5.1 简介**littlefs 是 ARM 官方推出的,专为嵌入式系统设计的文件系统,相比传统的文件系统,littlefs 具有以下优点:* 自带擦写均衡 * 支持掉电保护 * 占用的 RAM/ROM 少 littlefs 自带的擦写均衡和掉电保护使开发者可以放心的将文件系统挂载到 nor flash 上。**层级关系** littlefs 在 RT-Thread 上运行的层级关系图如下所示: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepd6HU1ISgaJsPUonCcLiaXnwRse5UXHrmR59luYibfYF8786ocib9RQSrQ/640?wx_fmt=png) **6.5.2 使用流程*** 初始化 DFS 组件。 * 使能 littlefs 软件包。 * 使能 MTD 设备。 * 使能 fal,用来创建 MTD 设备。 * 创建 MTD 设备 * 挂载MTD设备到 DFS 目录中。 **6.5.3 注册littlefs文件系统****设置littlefs文件系统的数据结构:_dfs_lfs_ops ** 1static const struct dfs_filesystem_ops _dfs_lfs_ops = { 2 "lfs", 3 DFS_FS_FLAG_DEFAULT, 4 &_dfs_lfs_fops, 5 6 _dfs_lfs_mount, 7 _dfs_lfs_unmount, 8 9 _dfs_lfs_mkfs, 10 _dfs_lfs_statfs, 11 _dfs_lfs_unlink, 12 _dfs_lfs_stat, 13 _dfs_lfs_rename, 14}; **将littlefs文件系统的数据结构挂载到文件系统操作表里**1int dfs_lfs_init(void) 2{ 3 /* init file system lock */ 4 rt_mutex_init(&_lfs_lock, "lfsmtx", RT_IPC_FLAG_FIFO); 5 /* register ram file system */ 6 return dfs_register(&_dfs_lfs_ops); 7} 8INIT_COMPONENT_EXPORT(dfs_lfs_init); * 检查littlefs文件系统是否已经存在于文件系统操作表的目录中 * 在文件系统操作表中找出一个空的文件类型条目 * 将littlefs文件系统的数据结构_dfs_lfs_ops 地址赋值给空的文件系统操作表目录 **6.5.4 挂载littlefs文件系统** 1 ... 2 struct rt_device *mtd_dev = RT_NULL; 3 4 ... 5 /* 初始化 fal */ 6 fal_init(); 7 /* 生成 mtd 设备 */ 8 mtd_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME); 9 if (!mtd_dev) 10 { 11 LOG_E("Can't create a mtd device on '%s' partition.", FS_PARTITION_NAME); 12 } 13 else 14 { 15 /* 挂载 littlefs */ 16 if (dfs_mount(FS_PARTITION_NAME, "/littlefs", "lfs", 0, 0) == 0) 17 { 18 LOG_I("Filesystem initialized!"); 19 } 20 else 21 { 22 /* 格式化文件系统 */ 23 dfs_mkfs("lfs", FS_PARTITION_NAME); 24 /* 挂载 littlefs */ 25 if (dfs_mount("filesystem", "/littlefs", "lfs", 0, 0) == 0) 26 { 27 LOG_I("Filesystem initialized!"); 28 } 29 else 30 { 31 LOG_E("Failed to initialize filesystem!"); 32 } 33 } 34 } 35 ... * 在文件系统操作表中找出lfs文件系统 * 检查"/littlefs"路径是否存在 * 检查littlefs文件系统是否已经挂载在文件系统表中 * 检查文件系统表是否有空余,如果有,把空余地址指向littlefs文件系统 * 注册文件系统 * 调用littlefs文件系统的挂载接口 **6.5.5 测试littlefs文件系统**在根目录下使用shell 的cd命令切换到/littlefs目录,然后使用ls命令: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepcIxgMNM8oO2rpIYkAp62SugicM1oAmoKaQicgicnicGxBNyw6PsxiaZJgvg/640?wx_fmt=png) **注意:spi_flash.h中缺少一个头文件,需要自行添加** ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALep8WcuW693jcZDaicZzsbNowib5IsD6tmyRT1DBEWhoHXxtJ5MrSlT9Acg/640?wx_fmt=png) **6.6 文件系统综合例程**DevFS、RomFS、RamFS、FatFS文件系统配置: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALep85wC3FjicCcictqDvc8UtbP2LHiaG45SUfoILpBkmqYeZDAMlyzFkwyOQ/640?wx_fmt=png) littlefs文件系统配置; ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepDtGsUAV1iceVGqhs0nAwwic1UGIlS1REW5Yqt0yDzPtFEc7CQy1JjIKA/640?wx_fmt=png) 主程序: ```
1
#include
2
#include
3
#include
4
#include
5
6
#include
7
#include
8
#include
9
#include
10
11
#define DBG_TAG "main"
12
#define DBG_LVL DBG_LOG
13
#include
14
15
/* defined the LED0 pin: PH10 */
16
#define LED0_PIN GET_PIN(H, 10)
17
18
int main(void) 19
{
20
int
count =
1
;
21
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
22
23
while
(count++)
24
{
25
rt_pin_write(LED0_PIN, PIN_HIGH);
26
rt_thread_mdelay(
1000
);
27
rt_pin_write(LED0_PIN, PIN_LOW);
28
rt_thread_mdelay(
1000
);
29
}
30
31
return
RT_EOK;
32
}
33
rt_uint8_t
rampool[
128
];
34
35
void sd_mount(void *parameter) 36
{
37
while
(
1
)
38
{
39
rt_thread_mdelay(
500
);
40
if
(rt_device_find(
"sd0"
) != RT_NULL)
41
{
42
if
(dfs_mount(
"sd0"
,
"/fatfs"
,
"elm"
,
0
,
0
) == RT_EOK)
43
{
44
LOG_I(
"sd card mount to '/fatfs'"
);
45
break
;
46
}
47
else
48
{
49
LOG_W(
"sd card mount to '/fatfs' failed!"
);
50
}
51
}
52
}
53
}
54
55
int fs_init(void) 56
{
57
/* partition initialized */
58
fal_init();
59
60
if
(dfs_mount (RT_NULL,
"/"
,
"rom"
,
0
,&(romfs_root)) ==
0
)
61
{
62
LOG_I(
"ROM file system initializated;
"
);
63
}
64
else
65
{
66
LOG_I(
"ROM file system initializate failed;
"
);
67
}
68
69
if
(dfs_mount (RT_NULL,
"/ram"
,
"ram"
,
0
,dfs_ramfs_create(rampool,
sizeof
(rampool))) ==
0
)
70
{
71
LOG_I(
"ram file system initializated;
"
);
72
}
73
else
74
{
75
LOG_I(
"ram file system initializate failed;
"
);
76
}
77
78
/* Create a block device on the file system partition of spi flash */
79
struct rt_device *flash_dev = fal_mtd_nor_device_create("filesystem");
80
81
if
(flash_dev == RT_NULL)
82
{
83
LOG_I(
"Can't create a mtd device on '%s' partition."
,
"filesystem"
);
84
}
85
else
86
{
87
LOG_I(
"Create a mtd device on the %s partition of flash successful."
,
"filesystem"
);
88
}
89
/* mount the file system from "filesystem" partition of spi flash. */
90
if
(dfs_mount(flash_dev->parent.name,
"/littlefs"
,
"lfs"
,
0
,
0
) ==
0
)
91
{
92
LOG_I(
"littlefs initialized!"
);
93
}
94
else
95
{
96
dfs_mkfs(
"lfs"
, flash_dev->parent.name);
97
if
(dfs_mount(flash_dev->parent.name,
"/"
,
"lfs"
,
0
,
0
) ==
0
)
98
{
99
LOG_I(
"littlefs initialized!"
);
100
}
101
}
102
103
rt_thread_t
tid;
104
105
tid = rt_thread_create(
"sd_mount"
, sd_mount, RT_NULL,
106
1024
, RT_THREAD_PRIORITY_MAX -
2
,
20
);
107
if
(tid != RT_NULL)
108
{
109
rt_thread_startup(tid);
110
}
111
else
112
{
113
LOG_E(
"create sd_mount thread err!"
);
114
}
115
return
0
;
116
}
117
INIT_COMPONENT_EXPORT(fs_init);``` 测试: ![FastAdmin](https://mmbiz.qpic.cn/mmbiz_png/PTFpic4NGgAEvNLNicXZl06cGWYQ1bALepLeXlsY3PW6CVTaMNshzRAVfLjMtNIKe9LLxDfUTg5ibKYkDQcQHbTrw/640?wx_fmt=png) 工程地址:[https://gitee.com/Aladdin-Wang/R ... aster/stm32f429_app](https://gitee.com/Aladdin-Wang/RT-FOTA-STM32L431/tree/master/stm32f429_app)
查看更多
2
个回答
默认排序
按发布时间排序
Aladdin-Wang
认证专家
2020-06-29
这家伙很懒,什么也没写!
原文地址:[https://blog.csdn.net/sinat_31039061/article/details/104145805](https://blog.csdn.net/sinat_31039061/article/details/104145805)
Aladdin-Wang
认证专家
2020-06-29
这家伙很懒,什么也没写!
欢迎关注公众号: [attach]15955[/attach]
撰写答案
登录
注册新账号
关注者
0
被浏览
2.1k
关于作者
Aladdin-Wang
这家伙很懒,什么也没写!
提问
5
回答
39
被采纳
7
关注TA
发私信
相关问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
a1012112796
13
个答案
1
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部