stm32 模拟U盘IAP升级 与 FAT16文件系统
如果用的MCU有USB接口,那么使用模擬U盤升級程序,不失為一個好辦法,因為
第1,模擬U盤,不需要驅動,也不需要上位機,現場操作非常方便,
第2,USB傳輸速度快,升級過程耗時少,且可靠。
這項技術的難點在于FAT16文件系統,因為STM32并沒有真正的實現一個FAT文件系統,一切都是模擬的,這要求研發者對FAT16文件系統認識的非常深刻。下面為FAT16系統的簡易結構圖:
1DBR引導扇區
首先是DBR引導扇區,這里面保存著很多參數,這個不要求 每個參數都弄懂,這個數據也可以直接從一個小U盤中用winhex軟件讀出來使用,我用的是
const uint8_t FAT16_BootSector[FATBootSize]=?
{
? ? 0xEB, ? ? ? ? ? /*00 - BS_jmpBoot */
? ? 0x3C, ? ? ? ? ? /*01 - BS_jmpBoot */
? ? 0x90, ? ? ? ? ? /*02 - BS_jmpBoot */
? ? 'M','S','D','O','S','5','.','0', ? ?/* 03-10 - BS_OEMName */
? ? 0x00, ? ? ? ? ? /*11 - BPB_BytesPerSec = 2048 */
? ? 0x08, ? ? ? ? ? /*11 - BPB_BytesPerSec = 2048 */
? ? 0x04, ? ? ? ? ? /*13 - BPB_Sec_PerClus = 2K*4 = 8K*/
? ? 2, ? ? ? ? ? ? ?/*14 - BPB_RsvdSecCnt = 2 */
? ? 0, ? ? ? ? ? ? ?/*15 - BPB_RsvdSecCnt = 2 */
? ? 2, ? ? ? ? ? ? ?/*16 - BPB_NumFATs = 2 */
? ? 0x0, ? ? ? ? ? ?/*17 - BPB_RootEntCnt = 512 */
? ? 0x2, ? ? ? ? ? ?/*18 - BPB_RootEntCnt = 512 */
? ? 0, ? ? ? ? ? ? ?/*19 - BPB_TotSec16 = 0 */
? ? 0, ? ? ? ? ? ? ?/*20 - BPB_TotSec16 = 0 */
? ? 0xF8, ? ? ? ? ? /*21 - BPB_Media = 0xF8 */
? ? 0x0D, ? ? ? ? ? /*22 - BPBFATSz16 = 0x000D */
? ? 0, ? ? ? ? ? ? ?/*23 - BPBFATSz16 = 0x000D */
? ? 0x3F, ? ? ? ? ? /*24 - BPB_SecPerTrk = 0x003F */
? ? 0, ? ? ? ? ? ? ?/*25 - BPB_SecPerTrk = 0x003F */
? ? 0xFF, ? ? ? ? ? /*26 - BPB_NumHeads = 255 */
? ? 0, ? ? ? ? ? ? ?/*27 - BPB_NumHeads = 255 */
? ? 0, ? ? ? ? ? ? ?/*28 - BPB_HiddSec = 0 */
? ? 0, ? ? ? ? ? ? ?/*29 - BPB_HiddSec = 0 */
? ? 0, ? ? ? ? ? ? ?/*30 - BPB_HiddSec = 0 */
? ? 0, ? ? ? ? ? ? ?/*31 - BPB_HiddSec = 0 */
? ? 0x00, ? ? ? ? ? /*32 - BPB_TotSec32 = */
? ? 0xC8, ? ? ? ? ? /*33 - BPB_TotSec32 = 0x0000C800 100Mb*/
? ? 0x00, ? ? ? ? ? /*34 - BPB_TotSec32 = */
? ? 0x00, ? ? ? ? ? /*35 - BPB_TotSec32 = */
? ? 0x80, ? ? ? ? ? /*36 - BS_DrvNum = 0x80 */
? ? 0, ? ? ? ? ? ? ?/*37 - BS_Reserved1 = 0 , dirty bit = 0*/ /* Updated from FSL*/
? ? 0x29, ? ? ? ? ? /*38 - BS_BootSig = 0x29 */
? ? 0xBD, ? ? ? ? ? /*39 - BS_VolID = 0x02DDA5BD */
? ? 0xA5, ? ? ? ? ? /*40 - BS_VolID = 0x02DDA5BD */
? ? 0xDD, ? ? ? ? ? /*41 - BS_VolID = 0x02DDA5BD */
? ? 0x02, ? ? ? ? ? /*42 - BS_VolID = 0x02DDA5BD */
? ? 'N','O',' ','N','A','M','E',' ',' ',' ',' ', ?/*43-53 - BS_VolLab */
? ? 'F','A','T','1','6',' ',' ',' ' ? /*54-61 - BS_FilSysType */
};
實時證明最后的55 AA不要也是可以的。
2。FAT文件分區表
FAT16文件分區表,其實就是一個鏈表結構,下面描述了2個文件使用的簇號分布。(顧名思義,FAT16使用16bit表示簇號)
文件1:? 3? 5
文件2: 4 6 7 8 9 10 11 12 13 14
3根目錄
根目錄也可重要,FAT32是沒有根目錄了,因為FAT32把根目錄也當成文件存儲到數據區了, 下圖為目錄項的定義,
讀文件的過程就是先找到文件,確定文件的首簇號,在FAT表中找到首簇號對應的鏈表,就可以依次把此文件所有的內容讀出來了。
參考程序USB固件升級_像U盤一樣升級程序.zip-嵌入式文檔類資源-CSDN下載轉自amobbs,版權歸原作者所有
啟動扇區 Boot Sector
在沒有分區表的設備中,第一個扇區是啟動扇區,包含了訪問該磁盤分卷所需的基本信息,扇區數據解釋如下,注意,除文本和特殊數據外,其余數據均按照小段格式存儲:
| 0x00 | 3 | EB 3C 90 | x86 跳轉指令,JMP 003E NOP |
| 0x08 | 8 | MSDOS5.0 | OEM 名稱,空格補齊不足的字節 |
| 0x0B | 2 | 00 02 | 每扇區字節數,一般為 512 字節 |
| 0x0D | 1 | 08 | 每簇扇區數,太大會浪費磁盤空間,太小會導致文件碎片過多 |
| 0x0E | 2 | 01 00 | 保留扇區數,包括啟動扇區,最小值為 1 |
| 0x10 | 1 | 02 | FAT 數目 |
| 0x11 | 2 | 00 02 | 根目錄最大條目數,其中第一個條目作為卷標 |
| 0x13 | 2 | 總扇區數,要求小于 65536,如果扇區數大于 65536,則此字段為 0,使用偏移為 0x20 的 4 字節字段。 | |
| 0x15 | 1 | F8 | 存儲介質類型,0xF8 表示該介質為硬盤 |
| 0x16 | 2 | 18 00 | 每個 FAT 的扇區數 |
| 0x18 | 2 | 20 00 | 每軌道扇區數 |
| 0x1A | 2 | 40 00 | 磁頭數量 |
| 0x1C | 4 | 00 00 00 00 | 隱藏扇區數 |
| 0x20 | 4 | 00 00 00 00 | 4 字節扇區數,當 2 字節的扇區數為 0 時,該字段被使用 |
| 0x24 | 1 | 80 | 物理硬盤號 |
| 0x25 | 1 | 00 | 當前磁頭號,不被 FAT 文件系統使用 |
| 0x26 | 1 | 29 | 簽名,用于被 Windows NT 系統識別 |
| 0x27 | 4 | CE 13 46 30 | 分卷序列號 |
| 0x2B | 11 | NO NAME | 卷標,但現在卷標被存儲在根目錄中 |
| 0x36 | 8 | FAT 16 | 磁盤文件系統格式,FAT12 或 FAT16 |
| 0x3E | 448 | 啟動代碼 | |
| 0x1FE | 2 | 55 AA | 啟動扇區結束標志 |
總結
以上是生活随笔為你收集整理的stm32 模拟U盘IAP升级 与 FAT16文件系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【C语言】结构体类型的定义与使用
- 下一篇: 【嵌入式单元测试】C语言单元测试框架搭建