【BLE】TLSR8258開發記錄之15--模擬FATFS

1、說明

基於SDK3.4,前期移植了Fatfs,發現在芯片進入睡眠後重新喚醒後,文件系統會失效需重新掛載,這是絕對不允許滴,故而自己模擬fat文件系統,採用FAT12。
FATFS文件系統簡介請自行上網查詢資料學習…本文主要做記錄

2、操作

2.1、本FATFS的定義
包含DBR、FAT、RootDir、data四個區域;每個扇區512byte,每個簇佔4個扇區,因而每個簇爲2048byte
FAT表中每12bit代表一個簇,即3個字節表示2個簇(項)
2.2、將FATFS進行劃分
如下表,數據區地址從簇2開始,分爲單PDF文件和PDF、CSV雙文件

功能 flash地址 大小(byte)
DBR引導區 固化在內部flash 512(內部)
FAT分配表區 0~0x7FF 2048
Rootdir根目錄區 0x800~0xFFF 2048
data(PDF) 0x1000~0x200000 2093056‬
功能 flash地址 大小(byte)
DBR引導區 固化在內部flash 512(內部)
FAT分配表區 0~0x7FF 2048
Rootdir根目錄區 0x800~0xFFF 2048
data(PDF) 0x1000~0x180FFF 1572864‬(1.5M)
data(CSV) 0x181000~0x200000 520192‬

2.3、每個區域的數據處理
2.3.1、DBR引導區,拷貝任意一個U盤的,作爲固定字段,可以寫進內部flash

const unsigned char Dbr[512]=
{
0xeb, 0x3e, 0x90,          //跳轉指令,不能改爲0,否則提示未格式化
'M','S','D','O','S','5','.','0', //文件系統及版本信息"MSDOS5.0"
0x00, 0x02,                //每扇區字節數,爲0x200=512字節
0x4,                       //每簇扇區數,爲4扇區
0x01, 0x00,                //保留扇區數,爲1
0x01,                      //該分區的FAT份數,爲1
0x40, 0x00,                //根目錄項數,爲64項
0x00, 0x10,                //小扇區數,這裏不用,爲0 當值小於65536時使用小扇區數,2M爲0x1000
0xF8,                      //媒體描述符,0xF8表示硬盤
0x04, 0x00,                //每FAT扇區數,爲4個
0x8, 0x00,                 //每道扇區數,爲8
0x10, 0x00,                //磁頭數爲64
0x00, 0x00, 0x00, 0x00,    //隱藏扇區數這裏沒有隱藏扇區,爲0
0x00, 0x00, 0x00, 0x00,    //大扇區數,扇區的總數,2M爲0x1000
0x80,                      //磁盤驅動器參數,80表示硬盤
0x00,                      //保留
0x29,                      //擴展引導標記,0x29表示接下來的三個域可用
0x88, 0x09, 0x71, 0x20,    //標卷序列號
//磁盤標卷
'M','e','g','a','i','n','-','T','e','m','p',
//文件系統類型信息,爲字符串"FAT12   "
'F', 'A', 'T', '1', '2', 0x20,0x20, 0x20,
//以下爲引導代碼
0xf1, 0x7d,
0xfa, 0x33, 0xc9, 0x8e,  0xd1, 0xbc, 0xfc, 0x7b,  0x16, 0x07, 0xbd,  0x78,  0x00, 0xc5, 0x76, 0x00,
0x1e, 0x56, 0x16, 0x55,  0xbf, 0x22, 0x05, 0x89,  0x7e, 0x00, 0x89,  0x4e,  0x02, 0xb1, 0x0b, 0xfc,
0xf3, 0xa4, 0x06, 0x1f,  0xbd, 0x00, 0x7c, 0xc6,  0x45, 0xfe, 0x0f,  0x8b,  0x46, 0x18, 0x88, 0x45,
0xf9, 0xfb, 0x38, 0x66,  0x24, 0x7c, 0x04, 0xcd,  0x13, 0x72, 0x3c,  0x8a,  0x46, 0x10, 0x98, 0xf7,
0x66, 0x16, 0x03, 0x46,  0x1c, 0x13, 0x56, 0x1e,  0x03, 0x46, 0x0e,  0x13,  0xd1, 0x50, 0x52, 0x89,
0x46, 0xfc, 0x89, 0x56,  0xfe, 0xb8, 0x20, 0x00,  0x8b, 0x76, 0x11,  0xf7,  0xe6, 0x8b, 0x5e, 0x0b,
0x03, 0xc3, 0x48, 0xf7,  0xf3, 0x01, 0x46, 0xfc,  0x11, 0x4e, 0xfe,  0x5a,  0x58, 0xbb, 0x00, 0x07,
0x8b, 0xfb, 0xb1, 0x01,  0xe8, 0x94, 0x00, 0x72,  0x47, 0x38, 0x2d,  0x74,  0x19, 0xb1, 0x0b, 0x56,
0x8b, 0x76, 0x3e, 0xf3,  0xa6, 0x5e, 0x74, 0x4a,  0x4e, 0x74, 0x0b,  0x03,  0xf9, 0x83, 0xc7, 0x15,
0x3b, 0xfb, 0x72, 0xe5,  0xeb, 0xd7, 0x2b, 0xc9,  0xb8, 0xd8, 0x7d,  0x87,  0x46, 0x3e, 0x3c, 0xd8,
0x75, 0x99, 0xbe, 0x80,  0x7d, 0xac, 0x98, 0x03,  0xf0, 0xac, 0x84,  0xc0,  0x74, 0x17, 0x3c, 0xff,
0x74, 0x09, 0xb4, 0x0e,  0xbb, 0x07, 0x00, 0xcd,  0x10, 0xeb, 0xee,  0xbe,  0x83, 0x7d, 0xeb, 0xe5,
0xbe, 0x81, 0x7d, 0xeb,  0xe0, 0x33, 0xc0, 0xcd,  0x16, 0x5e, 0x1f,  0x8f,  0x04, 0x8f, 0x44, 0x02,
0xcd, 0x19, 0xbe, 0x82,  0x7d, 0x8b, 0x7d, 0x0f,  0x83, 0xff, 0x02,  0x72,  0xc8, 0x8b, 0xc7, 0x48,
0x48, 0x8a, 0x4e, 0x0d,  0xf7, 0xe1, 0x03, 0x46,  0xfc, 0x13, 0x56,  0xfe,  0xbb, 0x00, 0x07, 0x53,
0xb1, 0x04, 0xe8, 0x16,  0x00, 0x5b, 0x72, 0xc8,  0x81, 0x3f, 0x4d,  0x5a,  0x75, 0xa7, 0x81, 0xbf,
0x00, 0x02, 0x42, 0x4a,  0x75, 0x9f, 0xea, 0x00,  0x02, 0x70, 0x00,  0x50,  0x52, 0x51, 0x91, 0x92,
0x33, 0xd2, 0xf7, 0x76,  0x18, 0x91, 0xf7, 0x76,  0x18, 0x42, 0x87,  0xca,  0xf7, 0x76, 0x1a, 0x8a,
0xf2, 0x8a, 0x56, 0x24,  0x8a, 0xe8, 0xd0, 0xcc,  0xd0, 0xcc, 0x0a,  0xcc,  0xb8, 0x01, 0x02, 0xcd,
0x13, 0x59, 0x5a, 0x58,  0x72, 0x09, 0x40, 0x75,  0x01, 0x42, 0x03,  0x5e,  0x0b, 0xe2, 0xcc, 0xc3,
0x03, 0x18, 0x01, 0x27,  0x0d, 0x0a, 0x49, 0x6e,  0x76, 0x61, 0x6c,  0x69,  0x64, 0x20, 0x73, 0x79,
0x73, 0x74, 0x65, 0x6d,  0x20, 0x64, 0x69, 0x73,  0x6b, 0xff, 0x0d,  0x0a,  0x44, 0x69, 0x73, 0x6b,
0x20, 0x49, 0x2f, 0x4f,  0x20, 0x65, 0x72, 0x72,  0x6f, 0x72, 0xff,  0x0d,  0x0a, 0x52, 0x65, 0x70,
0x6c, 0x61, 0x63, 0x65,  0x20, 0x74, 0x68, 0x65,  0x20, 0x64, 0x69,  0x73,  0x6b, 0x2c, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x74,  0x68, 0x65, 0x6e, 0x20,  0x70, 0x72, 0x65,  0x73,  0x73, 0x20, 0x61, 0x6e,
0x79, 0x20, 0x6b, 0x65,  0x79, 0x0d, 0x0a, 0x00,  0x49, 0x4f, 0x20,  0x20,  0x20, 0x20, 0x20, 0x20,
0x53, 0x59, 0x53, 0x4d,  0x53, 0x44, 0x4f, 0x53,  0x20, 0x20, 0x20,  0x53,  0x59, 0x53, 0x80, 0x01,
0x00, 0x57, 0x49, 0x4e,  0x42, 0x4f, 0x4f, 0x54,  0x20, 0x53, 0x59,  0x53,  0x00, 0x00, 0x55, 0xaa,

2.3.2、FAT區,該區域數據,需要進行文件長度與FAT表項的轉換而得出,算法如下

//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;
       else
           k = 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根目錄區
對於長文件名的處理
①短文件名是DOS+FAT12/FAT16時代的產物,命名規則爲8.3
②8是指文件名,3是指擴展名(完整文件=文件名.擴展名)
③文件名不能超過8個字節,如果多於8個字節,在DOS裏不會被識別
④擴展名不能超過3個字節,如果多於3個字節,在DOS裏不會被識別
⑤文件名超出8個字節或擴展名超出3個字節都是長文件名 ,長文件名與短文件名必須同時存在且一一對應
⑥目錄項的長文件名字段中未用到的字段,要先用2byte的0x00填充,再用0xFF填充,否則window會識別到文件名後綴還帶有空格,如下左圖爲識別異常
在這裏插入圖片描述
⑦短文件名和長文件名都是存儲於RootDir根目錄區,短文件名的目錄項和長文件名的目錄項定義如下圖
在這裏插入圖片描述⑧舉例,PDF文件的名字爲“202002020001.PDF”,總共16個字符,每個長目錄項可以有13個字符,故而需要2個長目錄項+1個短目錄項。 以“202002020001.PDF”文件名爲例,長文件名的2個目錄項如下(倒序、目錄項在實際存儲時爲倒序):

目錄項數據 說明
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 長文件目錄項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 長文件目錄項1-32byte
32 30 32 30 30 32 7E 31 50 44 46 00 00 00 創建 時間 創建 日期 訪問 日期 00 00 修改 時間 修改 日期 02 00 文 件 長 度 長文件目錄項0-32byte

⑨短文件名的前8個字符爲:長文件名的前6個字符+"~"+“1”,目錄項0中標黑部分爲“PDF”
⑩舉例,PDF文件的名字爲“2004010001.PDF”,總共14個字符,每個長目錄項可以有13個字符,故而需要2個長目錄項+1個短目錄項。
以“2004010001.PDF”文件名爲例,長文件名的2個目錄項如下(倒序、目錄項在實際存儲時爲倒序):

目錄項數據 說明
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 長文件目錄項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 長文件目錄項1-32byte
32 30 32 30 30 32 7E 31 50 44 46 00 00 00 創建 時間 創建 日期 訪問 日期 00 00 修改 時間 修改 日期 02 00 文 件 長 度 短文件目錄項-32byte

表中標黑部分爲長文件名的校驗和,是由短文件名通過特定算法算出,算法C代碼如下

//根據短文件名計算出長文件名的校驗和
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 right
            Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pShortName++;
      }
      return (Sum);
}

2.3.4、data數據區
本區域就是實際存儲的文件數據了…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章