|
問渠那得清如許? 為有源頭活水來 |
裙子好像太短了, 離題了。這次要站在巨人的肩膀上, 使用的是這個
FatFs - Generic FAT File System Module 讀寫 fat 的 library, 這個 library 支援 fat12, fat16, fat32, 還有長檔名以及中文檔名, 也會從硬碟分割區找到第一個 fat 檔案系統, 真的好用, 站在巨人的肩膀真好。
一樣是參考 STM32 不完原手冊的範例:
相關函式庫的用法:
FatFs - Generic FAT File System Module
當然, 在可以使用這些函式之前得先把要移植的部份搞定才行。
該怎麼開始驗證呢? 先從能正常讀取 fat 的檔案開始, 依照慣例, 得想個好方法來測試, 我決定在 pc 上測試這個 library, 一開始就在 stm32f4discovery 開發板寫程式, 不好除錯, 也很容易失敗。
先建立 fat 檔案系統的 image file, 再用它來測試 fat, 慣用 linux 的人對這一定不陌生。
以下分別建立軟碟以及硬碟影像檔, 建立硬碟影像檔是為了測試能不能從硬碟分割表找到 fat 檔案系統。
硬碟影像檔比較複雜一點, 用 boch bximage 建立硬碟影像檔。
fig 2 是不完原手冊講解這部份的內容, 建議仔細閱讀這章節。
fig 2 STM32 不完原手冊相關章節
|
在 diskio.c 補上讀取 fat image 的相關程式:
FILE_IMAGE_01, FILE_IMAGE_02 就是我額外補上的, 所以
f_mount(fs[2],"2:",1))
2, 2: 就是 FILE_IMAGE_01
3, 3: 就是 FILE_IMAGE_02
0, 0: 就是執行 spi sd card 相關的程式碼
diskio.c L188 disk_image_read() 就是很單純的呼叫 fread 而已。
大概描述一下 fatfs 運作方式:
f_mount() call find_volume()
一開始會從 sector 0 開始讀起, 看看是不是 fat, 如果不是, 就當作 partition 來看待, 找出第一個 partition (L2248), 在 L2303 會確認出是那一個 fat 類型, fat12, fat16 或是 fat32。
這就是其支援硬碟分割表的程式碼。
再來我把 malloc/free 的函式改成使用 array pool 去要記憶體, 雖然我已經實作了 c++ 標準程式庫 (有 new/delete), 但
連我自己也不敢用讓這個實驗簡單點是我的原則, 也讓程式很容易就可以移植到任何系統上。不過 bss 又暴了, 我得縮小這些 array pool。
ff.c 就是用這樣的手法改動 malloc/free。ff.c L538 的 512 太大了, bss 暴了, 改成 8 就可以了, 這是在 128k ram 上寫程式的挑戰, 我曾經認為 128k 的記憶體實在太小, 不過我現在很享受這樣的挑戰。
所需要的改動不只這樣, 只要 malloc/free 的部份, 全都被我改成類似的作法。
最後測試了 f_open, f_opendir 這些函式, load_elf.c L178 FILINFO f_info 一定要宣告成 static, 要不然會有 segment fault 的錯誤, 我搞不懂為什麼會這樣? 文件範例也是宣告成 static。
FATFS文件系统的中文长文件名配置的几个注意事项
《STM32 不完原手冊範例》配置的設定就可以支援中文以及長檔名, 繁體中文要用 cp950, 雖然是 unicode, 不過讀出來的卻是 big5 編碼, 真是奇怪, 我得把終端機設定為 big5 編碼, 才能正確讀到中文檔名。
我的重點並不是把 fat 檔案列出來而已, 我要讀取 elf, 並載入其 program body, 所以我加入了這些測試。
在 elf 的測試方面, 已經可以正確讀到 elf program header 以及其中的 machine code, 再來就只剩下載入以及執行它就好了, 這部份就不太好在 linux 環境中測試了。
這個 library 似乎只會用 512 byte 讀取一個 sector, 算是記憶體用量很小的程式, 這樣的程式可不好寫, 蠻厲害的。
這篇夠折磨人了, 到這裡就好了, 下一篇再來談談怎麼載入這個 elf 和執行它。
ref:
stm32 fat 檔案系統文件
「雖然我已經實作了 c++ 標準程式庫 (有 new/delete), (但連我自己也不敢用)(刪除線)」
回覆刪除也太誠實了!!