1.1 文件系統(tǒng)引入
在早期的嵌入式系統(tǒng)中,需要存儲(chǔ)的數(shù)據(jù)比較少,數(shù)據(jù)類型也比較單一,往往使用直接在存儲(chǔ)設(shè)備中的指定地址寫入數(shù)據(jù)的方法來(lái)存儲(chǔ)數(shù)據(jù)。然而隨著嵌入式設(shè)備功能的發(fā)展,需要存儲(chǔ)的數(shù)據(jù)越來(lái)越多,也越來(lái)越復(fù)雜,這時(shí)仍使用舊方法來(lái)存儲(chǔ)并管理數(shù)據(jù)就變得非常繁瑣困難。因此我們需要新的數(shù)據(jù)管理方式來(lái)簡(jiǎn)化存儲(chǔ)數(shù)據(jù)的組織形式,這就是文件系統(tǒng)的由來(lái)。
1.2 虛擬文件系統(tǒng)引入
為了統(tǒng)一眾多不同類型的文件系統(tǒng),虛擬文件系統(tǒng)對(duì)實(shí)際文件系統(tǒng)進(jìn)行抽象,采用統(tǒng)一的文件系統(tǒng)向用戶提供相應(yīng)的一組統(tǒng)一的標(biāo)準(zhǔn)的文件操作接口(open,read,close,select,poll等)。
2 DFS 簡(jiǎn)介
DFS( Device File System)是一種抽象的文件機(jī)制,RT-Thread中對(duì)文件系統(tǒng)的相關(guān)操作實(shí)際上都是通過(guò)操作DFS實(shí)現(xiàn),也就是說(shuō)DFS是對(duì)各種文件系統(tǒng)的抽象。DFS使的其他部分無(wú)須關(guān)心不同文件系統(tǒng)之間的差異,使得RT-Thread可以支持多種類型的文件系統(tǒng)。
3 DFS 框架
RT-Thread DFS 組件的主要功能特點(diǎn)有:
為應(yīng)用程序提供統(tǒng)一的 POSIX 文件和目錄操作接口:read、write、poll/select 等。
支持多種類型的文件系統(tǒng),如 FatFS、RomFS、DevFS 等,并提供普通文件、設(shè)備文件、網(wǎng)絡(luò)文件描述符的管理。
支持多種類型的存儲(chǔ)設(shè)備,如 SD Card、SPI Flash、Nand Flash 等。
DFS 的層次架構(gòu)如下圖所示,主要分為 POSIX 接口層、虛擬文件系統(tǒng)層和設(shè)備抽象層。
POSIX 接口層:
POSIX 表示可移植操作系統(tǒng)接口(Portable Operating System Interface of UNIX,縮寫 POSIX),POSIX 標(biāo)準(zhǔn)定義了操作系統(tǒng)應(yīng)該為應(yīng)用程序提供的接口標(biāo)準(zhǔn),是 IEEE 為要在各種 UNIX 操作系統(tǒng)上運(yùn)行的軟件而定義的一系列 API 標(biāo)準(zhǔn)的總稱。
虛擬文件系統(tǒng)層:
用戶可以將具體的文件系統(tǒng)注冊(cè)到 DFS 中,如 FatFS、RomFS、DevFS 等。
設(shè)備抽象層:設(shè)備抽象層將物理設(shè)備如 SD Card、SPI Flash、Nand Flash,抽象成符合文件系統(tǒng)能夠訪問(wèn)的設(shè)備,例如 FAT 文件系統(tǒng)要求存儲(chǔ)設(shè)備必須是塊設(shè)備類型。
不同文件系統(tǒng)類型是獨(dú)立于存儲(chǔ)設(shè)備驅(qū)動(dòng)而實(shí)現(xiàn)的,因此把底層存儲(chǔ)設(shè)備的驅(qū)動(dòng)接口和文件系統(tǒng)對(duì)接起來(lái)之后,才可以正確地使用文件系統(tǒng)功能。
4 DFS 數(shù)據(jù)結(jié)構(gòu)
文件系統(tǒng)操作表:
1const struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
文件系統(tǒng)表:
1struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX];
文件描述符:
1static struct dfs_fdtable _fdtab;
5 虛擬文件系統(tǒng)使用步驟
初始化 DFS 組件。
注冊(cè)具體類型的文件系統(tǒng)。
掛載文件系統(tǒng)
當(dāng)文件系統(tǒng)不再使用,可以將它卸載。
5.1 初始化 DFS 組件
dfs_init() 函數(shù)會(huì)初始化 DFS 所需的相關(guān)資源,創(chuàng)建一些關(guān)鍵的數(shù)據(jù)結(jié)構(gòu), 有了這些數(shù)據(jù)結(jié)構(gòu),DFS 便能在系統(tǒng)中找到特定的文件系統(tǒng),并獲得對(duì)特定存儲(chǔ)設(shè)備內(nèi)文件的操作方法。
dfs_init()加入了自動(dòng)初始化機(jī)制,在系統(tǒng)上電后會(huì)自動(dòng)運(yùn)行dfs_init()。
1INIT_PREV_EXPORT(dfs_init);
實(shí)例化DFS 組件相關(guān)的數(shù)據(jù)結(jié)構(gòu)
1const struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
1struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX]
1static struct dfs_fdtable _fdtab
創(chuàng)建當(dāng)前目錄表
1char working_directory[DFS_PATH_MAX] = {“/”}
初始化 DFS:
清除文件系統(tǒng)操作表
清除文件系統(tǒng)表
清除文件描述符表
初始化互斥量
設(shè)置當(dāng)前工作目錄為“/”
5.2 注冊(cè)具體類型的文件系統(tǒng)
在 DFS 組件初始化之后,還需要初始化使用的具體類型的文件系統(tǒng),也就是將具體類型的文件系統(tǒng)注冊(cè)到 DFS 中。注冊(cè)文件系統(tǒng)的接口如下所示:
1int dfs_register(const struct dfs_filesystem_ops *ops);
檢查這個(gè)文件系統(tǒng)是否已經(jīng)存在于文件系統(tǒng)操作表的目錄中
在文件系統(tǒng)操作表中找出一個(gè)空的文件類型條目
將這個(gè)文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)地址賦值給空的文件系統(tǒng)操作表目錄
5.3 掛載文件系統(tǒng)
在掛載文件系統(tǒng)之前,如果是用作存儲(chǔ)設(shè)備,還需要先存儲(chǔ)設(shè)備注冊(cè)為塊設(shè)備,然后格式化成對(duì)應(yīng)的文件系統(tǒng)后,才能掛載。
在 RT-Thread 中,掛載是指將一個(gè)存儲(chǔ)設(shè)備掛接到一個(gè)已存在的路徑上。我們要訪問(wèn)存儲(chǔ)設(shè)備中的文件,必須將文件所在的分區(qū)掛載到一個(gè)已存在的路徑上,然后通過(guò)這個(gè)路徑來(lái)訪問(wèn)存儲(chǔ)設(shè)備。掛載文件系統(tǒng)的接口如下所示:
1int dfs_mount(const char *device_name,
2 const char *path,
3 const char *filesystemtype,
4 unsigned long rwflag,
5 const void *data);
在文件系統(tǒng)操作表中找出特定的文件系統(tǒng)
為特殊文件系統(tǒng)建立完整路徑
檢查路徑是否存在
檢查文件系統(tǒng)是否掛載在文件系統(tǒng)表中
檢查文件系統(tǒng)表是否有空余,如果有,把空余地址指向給此文件系統(tǒng)
注冊(cè)文件系統(tǒng)
調(diào)用此文件系統(tǒng)的掛載接口
5.4 卸載文件系統(tǒng)
當(dāng)某個(gè)文件系統(tǒng)不需要再使用了,那么可以將它卸載掉。卸載文件系統(tǒng)的接口如下所示:
1int dfs_unmount(const char *specialfile);
檢查路徑是否存在
在文件系統(tǒng)表中找到此文件系統(tǒng)
清除文件系統(tǒng)表的這個(gè)條目?jī)?nèi)容
調(diào)用此文件系統(tǒng)的卸載接口
6 文件系統(tǒng)實(shí)例演示
6.1 devfs文件系統(tǒng)
6.1.1 簡(jiǎn)介
devfs是設(shè)備文件系統(tǒng),設(shè)備文件系統(tǒng)是用來(lái)把一切設(shè)備都抽象為像文件那樣操作(如可讀,可寫)。devfs默認(rèn)掛載在“/dev”路徑下。但是會(huì)發(fā)現(xiàn)在根目錄下使用shell 的ls命令不能看到“/dev”目錄, 但是cd “/dev” 能進(jìn)入dev 目錄 ,并且進(jìn)入dev目錄后也能顯示dev下的設(shè)備。因?yàn)楦夸洝?“下并沒(méi)有創(chuàng)建任何文件夾,所以在根目錄下ls命令自然看不到“/dev”目錄。由于掛載文件系統(tǒng)需要掛載在一個(gè)已存在的路徑上,devfs屬于特殊文件系統(tǒng),DFS為devfs設(shè)備文件系統(tǒng)注冊(cè)時(shí)設(shè)置了專門的“/dev”路徑以供設(shè)備文件系統(tǒng)掛載。
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 注冊(cè)devfs文件系統(tǒng)
如果開啟了DFS,devfs設(shè)備文件系統(tǒng)會(huì)在dfs_init()里自動(dòng)初始化和掛載。
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
設(shè)置devfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu):_device_fs
1static 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文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)掛載到文件系統(tǒng)操作表里
1int devfs_init(void)
2{
3 /* register rom file system */
4 dfs_register(&_device_fs);
5
6 return 0;
7}
檢查devfs文件系統(tǒng)是否已經(jīng)存在于文件系統(tǒng)操作表的目錄中
在文件系統(tǒng)操作表中找出一個(gè)空的文件類型條目
將devfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)_device_fs地址賦值給空的文件系統(tǒng)操作表目錄
文件系統(tǒng)操作表filesystem_operation_table的第一個(gè)目錄:
6.1.2 掛載devfs文件系統(tǒng)
1dfs_mount(NULL, ”/dev“, ”devfs“, 0, 0)
在文件系統(tǒng)操作表中找出devfs文件系統(tǒng)
跳過(guò)檢查”/dev“路徑是否存在
檢查devfs文件系統(tǒng)是否已經(jīng)掛載在文件系統(tǒng)表中
檢查文件系統(tǒng)表是否有空余,如果有,把空余地址賦值給devfs文件系統(tǒng)
注冊(cè)文件系統(tǒng)
調(diào)用devfs文件系統(tǒng)的掛載接口
文件系統(tǒng)表filesystem_table的第一個(gè)目錄:
6.1.3 測(cè)試devfs文件系統(tǒng)
在根目錄下使用shell 的cd命令切換到/dev目錄,然后使用ls命令:
6.2 RomFS文件系統(tǒng)
6.2.1 簡(jiǎn)介
RomFS是在嵌入式設(shè)備上常用的一種文件系統(tǒng),具備體積小,可靠性高,讀取速度快等優(yōu)點(diǎn),常用來(lái)作為系統(tǒng)初始文件系統(tǒng)。但也具有其局限性,RomFS是一種只讀文件系統(tǒng)。
6.2.2 注冊(cè)devfs文件系統(tǒng)
把RomFS當(dāng)作初始文件系統(tǒng)rootfs掛載在根目錄,在RomFS里創(chuàng)建幾個(gè)目錄,用于其他文件系統(tǒng)的掛載點(diǎn)。
更改… omfs.c文件,添加mnt文件夾和user文件夾。
1#include 《rtthread.h》
2#include 《dfs_romfs.h》
3
4static const struct romfs_dirent _romfs_root[] = {
5 {ROMFS_DIRENT_DIR, ”mnt“, RT_NULL, 0},
6 {ROMFS_DIRENT_DIR, ”user“, RT_NULL, 0}
7};
8
9const struct romfs_dirent romfs_root = {
10 ROMFS_DIRENT_DIR, ”/“, (rt_uint8_t *)_romfs_root, sizeof(_romfs_root)/sizeof(_romfs_root[0])
11};
設(shè)置romfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu):_romfs
1static 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文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)掛載到文件系統(tǒng)操作表里
1int dfs_romfs_init(void)
2{
3 /* register rom file system */
4 dfs_register(&_romfs);
5 return 0;
6}
7INIT_COMPONENT_EXPORT(dfs_romfs_init);//自動(dòng)初始化
檢查romfs文件系統(tǒng)是否已經(jīng)存在于文件系統(tǒng)操作表的目錄中
在文件系統(tǒng)操作表中找出一個(gè)空的文件類型條目
將romfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)_romfs地址賦值給空的文件系統(tǒng)操作表目錄
文件系統(tǒng)操作表filesystem_operation_table的第二個(gè)目錄:
6.2.3 掛載romfs文件系統(tǒng)
1int 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}
13INIT_ENV_EXPORT(mnt_init);
在文件系統(tǒng)操作表中找出romfs文件系統(tǒng)
檢查”/“路徑是否存在
檢查romfs文件系統(tǒng)是否已經(jīng)掛載在文件系統(tǒng)表中
檢查文件系統(tǒng)表是否有空余,如果有,把空余地址指向romfs文件系統(tǒng)
注冊(cè)文件系統(tǒng)
調(diào)用romfs文件系統(tǒng)的掛載接口
文件系統(tǒng)表filesystem_table的第二個(gè)目錄:
6.2.4 測(cè)試RomFS文件系統(tǒng)
在根目錄下使用shell 的ls命令:
6.3 RamFS文件系統(tǒng)
6.3.1 簡(jiǎn)介
RamFS是內(nèi)存文件系統(tǒng),它不能格式化,可以同時(shí)創(chuàng)建多個(gè),在創(chuàng)建時(shí)可以指定其最大能使用的內(nèi)存大小。其優(yōu)點(diǎn)是讀寫速度很快,但存在掉電丟失的風(fēng)險(xiǎn)。如果一個(gè)進(jìn)程的性能瓶頸是硬盤的讀寫,那么可以考慮在RamFS上進(jìn)行大文件的讀寫操作。
RT-Thread的RamFS設(shè)計(jì)之初未考慮支持文件夾,所以不能使用mkdir。
6.3.2 注冊(cè)RamFS文件系統(tǒng)
設(shè)置ramfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu):_ramfs
1static 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文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)掛載到文件系統(tǒng)操作表里
1int dfs_ramfs_init(void)
2{
3 /* register ram file system */
4 dfs_register(&_ramfs);
5
6 return 0;
7}
8INIT_COMPONENT_EXPORT(dfs_ramfs_init);
檢查ramfs文件系統(tǒng)是否已經(jīng)存在于文件系統(tǒng)操作表的目錄中
在文件系統(tǒng)操作表中找出一個(gè)空的文件類型條目
將ramfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)_ramfs地址賦值給空的文件系統(tǒng)操作表目錄
文件系統(tǒng)操作表filesystem_operation_table的第三個(gè)目錄:
6.3.3 掛載RamFS文件系統(tǒng)
1int 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}
13INIT_ENV_EXPORT(mnt_ram_elminit);
在文件系統(tǒng)操作表中找出ramfs文件系統(tǒng)
檢查”/mnt“路徑是否存在
檢查ramfs文件系統(tǒng)是否已經(jīng)掛載在文件系統(tǒng)表中
檢查文件系統(tǒng)表是否有空余,如果有,把空余地址指向ramfs文件系統(tǒng)
注冊(cè)文件系統(tǒng)
調(diào)用ramfs文件系統(tǒng)的掛載接口
文件系統(tǒng)表filesystem_table的第三個(gè)目錄:
6.3.4 測(cè)試RamFS文件系統(tǒng)
在根目錄下使用shell 的cd命令切換到/mnt目錄,然后使用ls命令:
6.4 elm-FAT文件系統(tǒng)
6.4.1 簡(jiǎn)介
FatFs 是一個(gè)通用的文件系統(tǒng)(FAT/exFAT)模塊,用于在小型嵌入式系統(tǒng)中實(shí)現(xiàn)FAT文件系統(tǒng)。
6.4.2 使用流程
初始化 DFS 組件。
初始化具體類型的文件系統(tǒng)。
在存儲(chǔ)器上創(chuàng)建塊設(shè)備。
格式化塊設(shè)備。
掛載塊設(shè)備到 DFS 目錄中。
當(dāng)文件系統(tǒng)不再使用,可以將它卸載
6.4.3 注冊(cè)elm-FAT文件系統(tǒng)
設(shè)置fatfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu):dfs_elm
1static 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文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)掛載到文件系統(tǒng)操作表里
1int elm_init(void)
2{
3 /* register fatfs file system */
4 dfs_register(&dfs_elm);
5
6 return 0;
7}
8INIT_COMPONENT_EXPORT(elm_init);
檢查fatfs文件系統(tǒng)是否已經(jīng)存在于文件系統(tǒng)操作表的目錄中
在文件系統(tǒng)操作表中找出一個(gè)空的文件類型條目
將fatfs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)dfs_elm 地址賦值給空的文件系統(tǒng)操作表目錄
elm-FAT文件系統(tǒng)注冊(cè)過(guò)程如下圖所示:
6.4.4 掛載elm-FAT文件系統(tǒng)
1void 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
21int 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}
37INIT_APP_EXPORT(stm32_sdcard_mount);
在文件系統(tǒng)操作表中找出elm文件系統(tǒng)
檢查”/fatfs“路徑是否存在
檢查elm文件系統(tǒng)是否已經(jīng)掛載在文件系統(tǒng)表中
檢查文件系統(tǒng)表是否有空余,如果有,把空余地址指向elm文件系統(tǒng)
注冊(cè)文件系統(tǒng)
調(diào)用elm文件系統(tǒng)的掛載接口
6.4.5 測(cè)試elm-FAT文件系統(tǒng)
在根目錄下使用shell 的cd命令切換到/fatfs目錄,然后使用ls命令:
6.5 littlefs文件系統(tǒng)
6.5.1 簡(jiǎn)介
littlefs 是 ARM 官方推出的,專為嵌入式系統(tǒng)設(shè)計(jì)的文件系統(tǒng),相比傳統(tǒng)的文件系統(tǒng),littlefs 具有以下優(yōu)點(diǎn):
自帶擦寫均衡
支持掉電保護(hù)
占用的 RAM/ROM 少
littlefs 自帶的擦寫均衡和掉電保護(hù)使開發(fā)者可以放心的將文件系統(tǒng)掛載到 nor flash 上。層級(jí)關(guān)系
littlefs 在 RT-Thread 上運(yùn)行的層級(jí)關(guān)系圖如下所示:
6.5.2 使用流程
初始化 DFS 組件。
使能 littlefs 軟件包。
使能 MTD 設(shè)備。
使能 fal,用來(lái)創(chuàng)建 MTD 設(shè)備。
創(chuàng)建 MTD 設(shè)備
掛載MTD設(shè)備到 DFS 目錄中。
6.5.3 注冊(cè)littlefs文件系統(tǒng)
設(shè)置littlefs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu):_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文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)掛載到文件系統(tǒng)操作表里
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文件系統(tǒng)是否已經(jīng)存在于文件系統(tǒng)操作表的目錄中
在文件系統(tǒng)操作表中找出一個(gè)空的文件類型條目
將littlefs文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)_dfs_lfs_ops 地址賦值給空的文件系統(tǒng)操作表目錄
6.5.4 掛載littlefs文件系統(tǒng)
1 。..
2 struct rt_device *mtd_dev = RT_NULL;
3
4 。..
5 /* 初始化 fal */
6 fal_init();
7 /* 生成 mtd 設(shè)備 */
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 /* 格式化文件系統(tǒng) */
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 。..
在文件系統(tǒng)操作表中找出lfs文件系統(tǒng)
檢查”/littlefs“路徑是否存在
檢查littlefs文件系統(tǒng)是否已經(jīng)掛載在文件系統(tǒng)表中
檢查文件系統(tǒng)表是否有空余,如果有,把空余地址指向littlefs文件系統(tǒng)
注冊(cè)文件系統(tǒng)
調(diào)用littlefs文件系統(tǒng)的掛載接口
6.5.5 測(cè)試littlefs文件系統(tǒng)
在根目錄下使用shell 的cd命令切換到/littlefs目錄,然后使用ls命令:
注意:spi_flash.h中缺少一個(gè)頭文件,需要自行添加
6.6 文件系統(tǒng)綜合例程
DevFS、RomFS、RamFS、FatFS文件系統(tǒng)配置:
littlefs文件系統(tǒng)配置;
主程序:
1#include 《rtthread.h》
2#include 《rtdevice.h》
3#include 《board.h》
4#include 《fal.h》
5
6#include 《dfs_fs.h》
7#include 《dfs_romfs.h》
8#include 《dfs_ramfs.h》
9#include 《dfs_posix.h》
10
11#define DBG_TAG ”main“
12#define DBG_LVL DBG_LOG
13#include 《rtdbg.h》
14
15/* defined the LED0 pin: PH10 */
16#define LED0_PIN GET_PIN(H, 10)
17
18int 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}
33rt_uint8_t rampool[128];
34
35void 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
55int 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}
117INIT_COMPONENT_EXPORT(fs_init);
測(cè)試:
? ? ? ?責(zé)任編輯:pj
評(píng)論
查看更多