在操作系統(tǒng)中,文件系統(tǒng)是很常用的,能夠讓我們很方便的進(jìn)行文件的建立、存入、讀出、修改等操作。文件系統(tǒng)需要依賴儲存設(shè)備(比如:FLASH、SD卡,U盤),我這里基于外置flash來做文件系統(tǒng)。
RT-thread官網(wǎng)也有關(guān)于文件系統(tǒng)的教程。
虛擬文件系統(tǒng):https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/filesystem/filesystem
在STM32F429上應(yīng)用文件系統(tǒng):https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/application-note/components/dfs/an0012-dfs
特別說明:本教程的配置介紹
MCU:STM32F429VET6
FLASH:W25Q32
RT-thread 源碼版本:v4.0.3
提示:本教程對硬件沒有什么要求,使用stm32f429舉例只是因為我現(xiàn)在手上只有這一塊板子,我用的最多的還是stm32f407和stm32f103,配置的流程都是一樣的。軟件版本不同,可能會有區(qū)別,比如RT-thread官網(wǎng)上面的教程就和本教程就有點區(qū)別,原因是官網(wǎng)的教程使用的是舊版本的bsp,ENV的配置有點不同。
一、掛載FLASH
這個在上一講已經(jīng)介紹過了,沒看過的同學(xué)可以先看下上一講的內(nèi)容:RT-thread應(yīng)用講解——norflash
二、ENV配置
對于ENV我就不多做介紹了,我前面發(fā)布的教程都介紹過了,RT-thread官網(wǎng)上也有很詳細(xì)的說明。
env使用方法:https://www.rt-thread.org/document/site/programming-manual/env/env/#bsp-menuconfig
輸入以下指令,打開配置頁面。
menuconfig
1、使能文件系統(tǒng)
2、設(shè)置扇區(qū)大小
扇區(qū)大小表示可處理的最大字節(jié)數(shù)。設(shè)置的值需要根據(jù)存儲器件手冊確定,不能小于存儲器件的最小可擦除扇區(qū)。我用的是外置FLASH,設(shè)置成4096,小于4096的話是會有問題的。
3、打開libc
因為要使用一些C庫函數(shù),所以需要打開libc功能。
4、重新生成工程
設(shè)置完之后保存退出,然后重新生成工程即可。
在env輸入下面的命令,重新生成新的工程。
提示:會使用env的話應(yīng)該都知道這個操作,不多說了。
scons --target=mdk5
特別說明:文件系統(tǒng)還有其他配置,我就不一一介紹了,感興趣的同學(xué)可以自己研究一下。
我這里重點講解下面這個配置。
這個是文件系統(tǒng)掛載的最大數(shù)量,如果需要把多個存儲設(shè)備掛載到文件系統(tǒng),就要檢查一下這個配置。比如我要把外置flash,sd卡和u盤都掛到文件系統(tǒng),那這個最大數(shù)量至少要設(shè)置為3,不然的話就會有一些設(shè)備掛載不上去了。
還有一點,不同的設(shè)備同時掛載的話,每個設(shè)備掛載的路徑都不能相同。
三、掛載文件系統(tǒng)
掛載文件系統(tǒng)只需要把下面這段加到工程里面調(diào)用就行了。
int mnt_init(void)
{
if (dfs_mount("norflash0", "/", "elm", 0, 0) == 0) // "norflash0":掛載的設(shè)備名稱,"/":掛載路徑,這里掛載到跟目錄下
{
rt_kprintf("norflash0 mount successful! n");
}
else
{
dfs_mkfs("elm", "norflash0"); // 如果是第一次掛載文件系統(tǒng)必須要先格式化
if(dfs_mount("norflash0", "/", "elm", 0, 0) != 0)
{
rt_kprintf("norflash0 mount failed! n");
}
else
{
rt_kprintf("norflash0 mount successful! n");
}
}
return 0;
}
INIT_ENV_EXPORT(mnt_init);
提示:掛載的設(shè)備名稱必須要和第一步掛載flash時自定義的名稱一致。否則會掛載失敗,其次,如果這個flash是第一次掛載那需要先格式化,可以手動輸msh入命令格式化(如:mkfs -t elm norflash0),也可以像我這里用代碼自動格式化。
四、運行測試
正常運行的日志如下:
我這里一開始調(diào)試的時候出現(xiàn)了一個奇怪的問題,log提示的是空間不足,env重新配置文件系統(tǒng)的參數(shù),重新生成工程之后就一直沒有出現(xiàn)了,到最后一直復(fù)現(xiàn)不出來,也沒找到原因,這里特意記錄一下,如果你們有類似的情況,找到原因的話記得評論區(qū)吱一聲哈。
掛載成功之后,可以手動輸入一些文件操作的命令測試一下,和linux的操作是基本一致的。RT-thread的軟件包里面也有一些文件系統(tǒng)的demo,可以自行添加測試。
五、進(jìn)階學(xué)習(xí)
上面的例子是把整個片外flash掛載到文件系統(tǒng),但是我們在實際的應(yīng)用中片外flash可能會同時使用多個功能,比如OTA,easyflash、文件系統(tǒng)等,這個時候為了避免數(shù)據(jù)沖突,我們就要先把flash分成幾個區(qū)域,然后把其中一個分區(qū)單獨掛載到文件系統(tǒng),這樣的話就不用擔(dān)心讀寫文件的時候會把其他分區(qū)的數(shù)據(jù)給覆蓋掉。
關(guān)于FLASH分區(qū)的內(nèi)容,請參考我另外一篇博客。RT-thread應(yīng)用講解——FLASH分區(qū)
分區(qū)分好之后就很簡單了,我們原來是把文件系統(tǒng)掛載到flash的設(shè)備名稱,現(xiàn)在只要改成分區(qū)名稱即可。
例如:我原來外置flash的設(shè)備名稱是"norflsh0",現(xiàn)在分了幾個區(qū)域,如下圖所示。
我現(xiàn)在把文件系統(tǒng)單獨掛載到"filesystem"分區(qū)即可,當(dāng)然,掛載到其他分區(qū)也是可以的,分區(qū)命名和分區(qū)大小、位置這些都是可以自定義的。
示例代碼如下:
int mnt_init(void)
{
fal_init(); // 這個函數(shù)只能調(diào)用一次,這里調(diào)用了其他地方就不能用
fal_blk_device_create("filesystem"); // 注意調(diào)用該函數(shù)前必須要先調(diào)用fal_init函數(shù)初始化
if (dfs_mount("filesystem", "/", "elm", 0, 0) == 0) // "filesystem":掛載的分區(qū)名稱,"/":掛載路徑,這里掛載到跟目錄下
{
rt_kprintf("filesystem mount successful! n");
}
else
{
dfs_mkfs("elm", "filesystem"); // 如果是第一次掛載文件系統(tǒng)必須要先格式化
if(dfs_mount("filesystem", "/", "elm", 0, 0) != 0)
{
rt_kprintf("filesystem mount failed! n");
}
else
{
rt_kprintf("filesystem mount successful! n");
}
}
return 0;
}
INIT_ENV_EXPORT(mnt_init);
// MSH_CMD_EXPORT(mnt_init, mnt_init);
提示:fal_blk_device_create()函數(shù)要在fal_init()之后調(diào)用,否則會出現(xiàn)找不到filesystem分區(qū)的問題,因為分區(qū)表還沒有被加載。
運行結(jié)果:
六、結(jié)束語
好了,關(guān)于文件系統(tǒng)的講解就到這里了,我這里只用了外置flash,如果是用sd卡或者其他設(shè)備,除了第一步掛載存儲設(shè)備不同,其他的流程基本是一樣的,如果你還有什么問題,歡迎評論區(qū)留言。如果這篇文章能夠幫到你,就給我點個贊吧,如果想了解更多RT-thread和單片機的內(nèi)容,可以關(guān)注一下博主,后續(xù)我還會繼續(xù)分享更多的經(jīng)驗給大家。
教程相關(guān)源碼:https://pan.baidu.com/s/1N2D8dM31deKIqNqaIQfPiA
提取碼:7nsx