本應用筆記介紹了 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 框架的來源
RT-Thread 為了能夠支持各種文件系統,設計了這樣一個 DFS 框架,各個層次獨立實現,提高了操作系統的可擴展性。使用 DFS 框架可以使得各種文件系統經過簡單的修改即可匹配到這個框架上,降低了文件系統移植難度,讓 開發者有更多的文件系統類型可供選擇。
DFS 框架各層次說明
頂層:POSIX 文件接口層
這一層是給開發者使用的接口函數層,開發者使用這一層提供的POSIX文件接口進行文件的相關操作,不用關心文件系統是如何實現的,也不用關心數據是存放在哪個存儲器中。
中間層:文件系統實現層
中間層是各種具體文件系統的實現,這里所說文件系統指各種不同類型的文件系統,比如ELM FatFS、RomFS、devfs、Yaffs2、Uffs2等。需要知道的是,不同的文件系統類型是獨立于存儲設備驅動而實現的。因此,想要正確地使用這些文件系統,需要把底層存儲設備的驅動接口和文件系統對接起來。
底層:存儲設備驅動層
這一層是存儲設備驅動層,具體的功能是初始化存儲設備并向上層提供存儲設備的驅動接口。存儲設備的類型可能是SPI Flash,SD卡等。
文件系統的移植
本次演示使用正點原子開發板STM32F429-Apollo,選擇的文件系統類型是 elm FatFS。由于 RT-Thread 自帶了這個文件系統,所以移植工作較為簡單,只需要通過 env 工具對系統進行合適的配置既可。其他 RT-Thread 支持的文件系統,移植過程也是類似的,只需要對系統進行合適的配置即可使用。
準備工程
下載 RT-Thread 源碼 。
env 工具
移植過程介紹
文件系統的移植主要包括下面幾個方面:
開啟/配置 DFS 框架
開啟/配置 指定的文件系統
確保開發板上的存儲設備驅動正常工作
通過 env 工具可以方便地開啟文件系統,將所需的文件系統類型添加到工程中。
對存儲設備進行功能測試,可以確保存儲設備驅動是正常工作的。驅動程序的穩定工作是文件系統正常使用的基礎。
文件系統的配置
使用 env 工具進入rt-threadspstm32f429-apollo目錄,在命令行中輸入menuconfig命令進入配置界面。
在menuconfig配置界面依次選擇RT-Thread Components → Device virtual file system,如下圖所示:
下面介紹 DFS 的配置項:
Using device virtual file system : 使用設備虛擬文件系統,即 RT-Thread 文件系統。
Using working directory : 打開這個選項,在finsh/msh中就可以使用基于當前工作目錄的相對路徑。
The maximal number of mounted file system : 最大掛載文件系統的數量。
The maximal number of file system type : 最大支持文件系統類型的數量。
The maximal number of opened files : 打開文件的最大數量。
Enable elm-chan fatfs : 使用 elm-chan FatFs。
elm-chan’s FatFs, Generic FAT Filesystem Module : elm-chan 文件系統的配置項。
Using devfs for device objects : 開啟 devfs 文件系統。
Enable BSD socket operated by file system API : 使 BSD socket 可以使用文件系統的 API 來管理,比如讀寫操作和 select/poll 的 POSIX API 調用。
Enable ReadOnly file system on flash : 在 Flash 上使用只讀文件系統。
Enable RAM file system : 使用 RAM 文件系統。
Enable UFFS file system: Ultra-low-cost Flash File System :使用 UFFS。
Enable JFFS2 file system : 使用 JFFS2 文件系統。
Using NFS v3 client file system :使用 NFS 文件系統。
進入到 DFS 的配置界面,開啟下圖所示的選項,就可以將FatFS添加到系統中。如圖所示:
這里需要注意的是還需要進入到elm-chan's FatFs, Generic FAT Filesystem Module選項中修改關于長文件名支持的選項,否則在后面使用文件系統的過程中,創建的文件或者文件夾的名稱不能超過 8 個字符。修改方式如下圖所示:
因為要使用一些 C 庫函數,所以需要打開libc功能:
保存選項后即可退出,此時elm FatFS已經添加到項目中 。
存儲設備初始化
開啟 SPI 設備驅動
DFS 框架的文件系統實現層需要存儲設備驅動層提供驅動接口用于對接,本次使用的存儲設備為SPI Flash,底層設備初始化過程可以參考 《SPI 設備應用筆記》 。
重新打開 menuconfig 配置界面,在RT-Thread Components → Device Drivers界面中選中Using SPI Bus/Device device drivers以及Using Serial Flash Universal Driver選項,如下圖所示:
為了方便地使用 shell 命令,我們在RT-Thread Components → Command shell選項中開啟Using module shell選項,如下圖所示:
保存選項并退出,在 env 中輸入命令scons --target=mdk5 -s生成 mdk5 工程,編譯并下載程序。
檢查存儲設備驅動
在 stm32f429-apollo 開發板上SPI Flash掛在了 SPI5 總線上,對應的SPI Device的設備名為spi50。在終端輸入list_device命令可以看到名為spi50的設備類型為SPI Device,就說明 SPI 設備添加成功。如果沒有出現相應的設備,則需要檢查驅動程序,查找錯誤。
為了確保該驅動工作正常,可以使用sf命令對該設備做benchmark測試。該功能由sfud組件提供,可以通過檢查存儲設備的讀、寫和擦除功能來判斷存儲設備的驅動程序是否正常。 如果像下圖一樣提示成功,所示則認為該驅動工作正常。如果無法通過測試,則需要檢查驅動程序,使用邏輯分析儀對存儲設備的接口波形進行分析。測試過程如下圖:
創建存儲設備
由于只有塊設備類型的設備才能和文件系統對接,所以需要根據SPI Device找到SPI Flash設備,并創建與其對應的Block Device。
這里需要使用到萬能 SPI Flash 驅動庫:SFUD ,RT-Thread 已經集成了該組件,在上面的配置過程中我們已經開啟這個功能。此時只需要使用 SFUD 提供的rt_sfud_flash_probe函數即可。該函數將執行如下操作:
根據名為spi50的SPI Device設備找到對應的Flash存儲設備。
初始化Flash設備。
在 Flash 存儲設備上創建名為W25Q256的 Block Device。
如果開啟了組件自動初始化功能,該函數會被自動執行,否則需要手動調用運行。
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)
在終端輸入list_device命令如果看到名為W25Q256的設備類型為Block Device,這說明塊設備已經創建成功,如果失敗則需要對spi50設備進行檢查。
如下圖所示:
獲得可以用于掛載的塊類型設備,那么移植的工作就算完成了。
文件系統的使用
文件系統的初始化
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文件夾。如果沒有特殊情況,文件系統可以直接掛載到根目錄/上。)
掛載文件系統的操作由dfs_mount()函數完成,dfs_mount()函數的參數分別為:塊設備名、文件系統掛載點路徑、掛載文件系統類型、讀寫標志位以及文件系統的私有數據,使用方法如下圖所示:
經過了上面的創建文件系統操作,我們重啟開發板(會自動重新執行掛載函數),就可以成功地掛載文件系統了。可以看到提示spi flash mount to /spi !。這時再次使用list_device命令可以看到W25Q256設備已經被掛載成功。如下圖所示:
到這一步為止,文件系統已經初始化完成,接下來可以對文件和目錄進行操作了。
文件與目錄操作 shell 命令
在這一小節介紹關于文件和目錄操作常用的 shell 命令:
ls功能:顯示文件和目錄的信息,示例如下圖:
cd功能:切換到指定工作目錄,示例如下圖:
cp功能:copy 文件,示例如下圖:
rm功能:刪除文件或目錄,示例如下圖:
mv功能:將文件移動位置或者改名,示例如下圖:
echo功能:將指定內容寫入文件:
cat功能:展示文件的內容,示例如下圖:
pwd功能:打印出當前目錄地址,示例如下圖:
mkdir功能:創建文件夾,示例如下圖:
文件操作示例
本節以創建文件夾操作為例,介紹如何使用 RT-Thread 文件系統 Sample 來對文件系統進行操作。
在menuconfig配置界面依次選擇RT-Thread online packages → miscellaneous packages → filesystem sample options,選中 [filesystem] mkdir選項,如下圖所示:
保存并退出后,使用pkgs --update命令更新軟件包,然后使用scons --target=mdk5 -s命令重新生成工程。可以看到該 Sample 已經添加到工程中:
這里需要注意的是由于我們文件系統的根目錄掛載了RomFS,不可修改,所以我們不能直接在根目錄創建文件夾。因此,我們需要對程序進行簡單的修改,如下圖所示:
重新編譯后下載運行,在 msh 中可以使用mkdir_sample_init命令來創建 web 文件夾,效果如下圖所示:
此時切換到/spi文件夾中可以看到 web 文件夾已經被創建。
文件系統提供的 Sample 還有openfile、readwrite、stat、rename、opendir、readdir、tell_seek_dir,大家可以用上面的方法來使用這些功能。
常見問題
(1)發現文件名或者文件夾名稱顯示不正常怎么辦?
檢查是否開啟了長文件名支持,可以參考本應用筆記《文件系統的配置》章節。
(2)文件系統初始化失敗怎么辦?
檢查文件系統配置項目中的允許掛載的文件系統類型和數量是否充足。
(3)創建文件系統mkfs命令失敗怎么辦?
檢查存儲設備是否存在,如果存在檢查設備驅動是否可以通過功能測試,如果不能通過,則檢查驅動錯誤。
檢查 libc 功能是否開啟,參見 《文件系統的配置》章節。
(4)文件系統掛載失敗怎么辦?
檢查指定的掛載路徑是否存在。文件系統可以直接掛載到根目錄(“/”),但是如果想要掛載到其他路徑上,如 (“/sdcard”)。需要確保(“/sdcard”)路徑是存在的,否則需要先在根目錄創建sdcard文件夾才能掛載成功。
檢查是否在存儲設備上創建了文件系統,如果存儲設備上沒有文件系統,需要使用mkfs命令在存儲器上創建文件系統。
(5)SFUD 探測不到 Flash 所使用的具體型號怎么辦?
檢查硬件引腳設置錯誤
SPI 設備是否已經注冊
SPI 設備是否已經掛載到總線
檢查在RT-Thread Components → Device Drivers -> Using SPI Bus/Device device drivers -> Using Serial Flash Universal Driver菜單下的Using auto probe flash JEDEC SFDP parameter和Using defined supported flash chip information table配置項是否選中,如果沒有選中那么需要開啟這兩個選項。配置圖可參考 《開啟 SPI 設備驅動》 章節。
如果開啟了上面的選項仍然無法識別存儲設備,那么可以在 SFUD 項目中提出 issues。
(6)elm FatFS 的最大扇區大小該如何設置?
根據所使用的存儲設備的不同,也會有些不一樣,一般根據 Flash 設備的要求可以設置為 4K,也就是填寫 4096。
一般常見的 TF 卡和 SD 卡的扇區大小設置為 512。
(7)存儲設備的benchmark測試耗時過長是怎么回事?
可對比system tick為 1000 時的 benchmark 測試數據 和本次測試所需的時長,如果耗時差距過大,則可以認為測試工作運行不正常。
檢查系統 tick 的設置,因為一些延時操作會根據 tick 時間來決定,所以需要根據系統情況來設置合適的system tick值。如果系統的system tick值不低于 1000,則需要使用邏輯分析儀檢查波形確定通信速率正常。
(8)SPI Flash 實現 elmfat 文件系統,如何保留部分扇區不被文件系統使用?
可以使用 RT-Thread 提供的 partition 工具軟件包為整個存儲設備創建多個塊設備,為創建的多個塊設備分配不同的功能即可。
(9)測試文件系統過程中程序卡住了怎么辦?
嘗試使用調試器或者打印一些必要的調試信息,確定程序卡住的位置再提出問題。
(10)如何一步步檢查文件系統出現的問題?
可以采用從底層到上層的方法來逐步排查問題。
首先檢查存儲設備是否注冊成功,功能是否正常。
檢查存儲設備中是否創建了文件系統。
檢查指定文件系統類型是否注冊到 DFS 框架,經常要檢查允許的文件系統類型和數量是否足夠。
檢查 DFS 是否初始化成功,這一步的初始化操作是純軟件的,因此出錯的可能性不高。需要注意的是如果開啟了組件自動初始化,就無需再次手動初始化。
-
文件系統
+關注
關注
0文章
284瀏覽量
19884 -
RTOS
+關注
關注
22文章
809瀏覽量
119451 -
RT-Thread
+關注
關注
31文章
1274瀏覽量
39940 -
物聯網操作系統
+關注
關注
3文章
114瀏覽量
13341 -
嵌入式實時操作系統
+關注
關注
1文章
127瀏覽量
7827
原文標題:10分鐘學會文件系統的基本知識和使用方法——周四RTOS專欄
文章出處:【微信號:elecfans,微信公眾號:電子發燒友網】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論