【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引导区固化在内部flash512(内部)
FAT分配表区0~0x7FF2048
Rootdir根目录区0x800~0xFFF2048
data(PDF)0x1000~0x2000002093056‬
功能flash地址大小(byte)
DBR引导区固化在内部flash512(内部)
FAT分配表区0~0x7FF2048
Rootdir根目录区0x800~0xFFF2048
data(PDF)0x1000~0x180FFF1572864‬(1.5M)
data(CSV)0x181000~0x200000520192‬

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数据区
本区域就是实际存储的文件数据了…

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值