【BLE】TLSR8258开发记录之15--模拟FATFS
1、說明
基于SDK3.4,前期移植了Fatfs,發(fā)現(xiàn)在芯片進(jìn)入睡眠后重新喚醒后,文件系統(tǒng)會失效需重新掛載,這是絕對不允許滴,故而自己模擬fat文件系統(tǒng),采用FAT12。
FATFS文件系統(tǒng)簡介請自行上網(wǎng)查詢資料學(xué)習(xí)…本文主要做記錄
2、操作
2.1、本FATFS的定義
包含DBR、FAT、RootDir、data四個(gè)區(qū)域;每個(gè)扇區(qū)512byte,每個(gè)簇占4個(gè)扇區(qū),因而每個(gè)簇為2048byte
FAT表中每12bit代表一個(gè)簇,即3個(gè)字節(jié)表示2個(gè)簇(項(xiàng))
2.2、將FATFS進(jìn)行劃分
如下表,數(shù)據(jù)區(qū)地址從簇2開始,分為單PDF文件和PDF、CSV雙文件
| DBR引導(dǎo)區(qū) | 固化在內(nèi)部flash | 512(內(nèi)部) |
| FAT分配表區(qū) | 0~0x7FF | 2048 |
| Rootdir根目錄區(qū) | 0x800~0xFFF | 2048 |
| data(PDF) | 0x1000~0x200000 | 2093056? |
| DBR引導(dǎo)區(qū) | 固化在內(nèi)部flash | 512(內(nèi)部) |
| FAT分配表區(qū) | 0~0x7FF | 2048 |
| Rootdir根目錄區(qū) | 0x800~0xFFF | 2048 |
| data(PDF) | 0x1000~0x180FFF | 1572864?(1.5M) |
| data(CSV) | 0x181000~0x200000 | 520192? |
2.3、每個(gè)區(qū)域的數(shù)據(jù)處理
2.3.1、DBR引導(dǎo)區(qū),拷貝任意一個(gè)U盤的,作為固定字段,可以寫進(jìn)內(nèi)部flash
2.3.2、FAT區(qū),該區(qū)域數(shù)據(jù),需要進(jìn)行文件長度與FAT表項(xiàng)的轉(zhuǎn)換而得出,算法如下
//update the fat1 unsigned int sectorsum; unsigned int i=0; unsigned int k=0; char tempfatbuf[2048]={0xf8,0xff,0xff,0x00,0x00,0x00,0x00,0x00};sectorsum = (data_stop_address-data_start_address)/2048 + ((((gdata_stop_address-data_start_address)%2048)==0)?0:1);for(i=0;i<sectorsum;i++){if(i==(sectorsum-1))k = 0xFFF;elsek = i+3;if((i%2)==0){tempfatbuf[3+i+i/2]=k&0xff;tempfatbuf[4+i+i/2]= (tempfatbuf[4+i+i/2]&0xF0)|((k>>8)&0x0F);}else{tempfatbuf[3+i+i/2]=(tempfatbuf[3+i+i/2]&0x0F)|((k&0x0F)<<4);tempfatbuf[4+i+i/2]=k>>4;}}2.3.3、Rootdir根目錄區(qū)
對于長文件名的處理
①短文件名是DOS+FAT12/FAT16時(shí)代的產(chǎn)物,命名規(guī)則為8.3
②8是指文件名,3是指擴(kuò)展名(完整文件=文件名.擴(kuò)展名)
③文件名不能超過8個(gè)字節(jié),如果多于8個(gè)字節(jié),在DOS里不會被識別
④擴(kuò)展名不能超過3個(gè)字節(jié),如果多于3個(gè)字節(jié),在DOS里不會被識別
⑤文件名超出8個(gè)字節(jié)或擴(kuò)展名超出3個(gè)字節(jié)都是長文件名 ,長文件名與短文件名必須同時(shí)存在且一一對應(yīng)
⑥目錄項(xiàng)的長文件名字段中未用到的字段,要先用2byte的0x00填充,再用0xFF填充,否則window會識別到文件名后綴還帶有空格,如下左圖為識別異常
⑦短文件名和長文件名都是存儲于RootDir根目錄區(qū),短文件名的目錄項(xiàng)和長文件名的目錄項(xiàng)定義如下圖
⑧舉例,PDF文件的名字為“202002020001.PDF”,總共16個(gè)字符,每個(gè)長目錄項(xiàng)可以有13個(gè)字符,故而需要2個(gè)長目錄項(xiàng)+1個(gè)短目錄項(xiàng)。 以“202002020001.PDF”文件名為例,長文件名的2個(gè)目錄項(xiàng)如下(倒序、目錄項(xiàng)在實(shí)際存儲時(shí)為倒序):
| 42 50 00 44 00 46 00 00 00 FF FF 0F 00 0B FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF | 長文件目錄項(xiàng)2-32byte |
| 01 32 00 30 00 32 00 30 00 30 00 0F 00 0B 32 00 30 00 32 00 30 00 30 00 30 00 00 00 31 00 2E 00 | 長文件目錄項(xiàng)1-32byte |
| 32 30 32 30 30 32 7E 31 50 44 46 00 00 00 創(chuàng)建 時(shí)間 創(chuàng)建 日期 訪問 日期 00 00 修改 時(shí)間 修改 日期 02 00 文 件 長 度 | 長文件目錄項(xiàng)0-32byte |
⑨短文件名的前8個(gè)字符為:長文件名的前6個(gè)字符+"~"+“1”,目錄項(xiàng)0中標(biāo)黑部分為“PDF”
⑩舉例,PDF文件的名字為“2004010001.PDF”,總共14個(gè)字符,每個(gè)長目錄項(xiàng)可以有13個(gè)字符,故而需要2個(gè)長目錄項(xiàng)+1個(gè)短目錄項(xiàng)。
以“2004010001.PDF”文件名為例,長文件名的2個(gè)目錄項(xiàng)如下(倒序、目錄項(xiàng)在實(shí)際存儲時(shí)為倒序):
| 42 46 00 00 00 FF FF FF FF FF FF 0F 00 B9 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF | 長文件目錄項(xiàng)2-32byte |
| 01 32 00 30 00 30 00 34 00 30 00 0F 00 B9 31 00 30 00 30 00 30 00 31 00 2E 00 00 00 50 00 44 00 | 長文件目錄項(xiàng)1-32byte |
| 32 30 32 30 30 32 7E 31 50 44 46 00 00 00 創(chuàng)建 時(shí)間 創(chuàng)建 日期 訪問 日期 00 00 修改 時(shí)間 修改 日期 02 00 文 件 長 度 | 短文件目錄項(xiàng)-32byte |
表中標(biāo)黑部分為長文件名的校驗(yàn)和,是由短文件名通過特定算法算出,算法C代碼如下
//根據(jù)短文件名計(jì)算出長文件名的校驗(yàn)和 unsigned char LongName_CheckkSum (unsigned char *pShortName) {short FcbNameLen;unsigned char Sum; //必須為無符號型Sum = 0;for (FcbNameLen=11; FcbNameLen!=0; FcbNameLen--){// NOTE: The operation is an unsigned char rotate rightSum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pShortName++;}return (Sum); }2.3.4、data數(shù)據(jù)區(qū)
本區(qū)域就是實(shí)際存儲的文件數(shù)據(jù)了…
總結(jié)
以上是生活随笔為你收集整理的【BLE】TLSR8258开发记录之15--模拟FATFS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【BLE】TLSR8258开发记录之12
- 下一篇: [学习笔记]C++