从8月8号开始,连续一个月利用每天下班时间和周末的时间终于初步完成了一个电子工程师的电路板名片,就像U盘一样,不过这个FLASH只有64KB的大小,用的单片机是C8051F320,是一个USB型的单片机。这次获取的教训是一开始想好要做什么事,无论如何要坚持下来,也许困难有很大,但是和困难磨磨突然会发现原来眼前的困难也是有解决的办法的,突然的豁然开朗。

  整体结构如下:

  我打算把自己所做的按照我自己调试的过程写下来,会连续发几篇博客,欢迎关注我哦。FAT16文件系统是在最后才搞出来,趁热打铁,把它作为第一篇先记下来。

  电子工程师电路板名片之FAT16文件系统

  FAT16文件系统的介绍在这篇博客介绍比较详细:http://blog.csdn.net/menghnhhuan/article/details/4270168

  FAT16文件系统在U盘、MMC卡、SD卡、以及一些小型系统上用的比较多,我在MX25L512这个64KB的FLASH安装的文件系统如下:

注:第一个8*512中包含DBR区,共一个512 Bytes,其余7个512 Bytes内容为0,但这8个512 Bytes都是保留扇区

  一、DBR区(DOS BOOT RECORD):即操作系统引导区,本身只占512Bytes,但是从0地址开始有8个保留扇区(包括DBR区),所以FAT1的起始地址为8×512Bytes

注:BPB区记录本分区的起始扇区,结束扇区,文件存储格式,磁盘介质描述符,根目录大小,FAT个数,分配单元大小等。

  下面是我程序中具体去设置DBR的512个字节

code     unsigned ] =
{
    0xeb,0x3c,0x90,                                //跳转指令,跳转到0x3c+2的引导程序代码处
    0x4d,0x53,0x44, 0x4f, 0x53, 0x35, 0x2e, 0x30,    //厂商标志和OS版本号

    //BPB(BIOS parameter block)
    0x00,0x02,    //扇区字节数512(合法的有512,1024,4096),C8051F单片机是大端模式
    0x01,         //每簇扇区数(合法的有1,2,4,8,16,32,64,128)
    0x08,0x00,    //保留扇区数,这样可以知道FAT1区起始地址,为8×512
    0x02,         //FAT数目
    0x00,0x02,    //根目录数,典型为512个目录,每个文件或文件夹名长度为32 bytes
    0x80,0x00,    //小扇区数,(对于大于65536个扇区的分区,本字段为0,采用大扇区表示,)
    0xf8,         //媒体描述符,0xf8表示硬盘,0xf0表示3.5寸软盘
    0x08,0x00,    //每个FAT占用的扇区数
    0x3F,0x00,    //每道扇区数
    0xFF,0x00,    //磁头数
    0x00,0x00,0x00,0x00,  //隐藏扇区数
    0x00,0x00,0x00,0x00,  //大扇区数,如果小扇区字段为0,本字段就包含了FAT16中的总扇区数
                                    //如果小扇区字段不为0,那么本字段为0

    //BPB扩展字段
    0x80,        //物理驱动器,硬盘被标志为0x80,软盘驱动器被标志为0x00
    0x00,        //保留字段
    0x29,        //扩展引导标签,要有能被windows 2000所识别的0x28或0x29
    0xA8, 0x8B, 0x36, 0x52,     //卷序号,在格式化磁盘时所产生的一个随机号,助于区分磁盘
    0x4E, 0x4F, 0x20, 0x4E, 0x41, 0x4D, 0x45, 0x20, 0x20, 0x20, 0x20,    //卷标
    0x46, 0x41, 0x54, 0x31, 0x36, 0x20,  0x20, 0x20,       //文件系统类型FAT16

    //操作系统引导代码
 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
};

  二、FAT16文件系统

  FAT(File Allocation Table)文件分配表,是微软在FAT文件系统中用于磁盘数据文件索引和定位引进的一种链式结构,有两个,另一个是备份。FAT文件系统之所以有12、16、32不同的版本之分,其根本在于FAT表用来记录任意一簇链接的二进制位数。以FAT16为例,每一簇在FAT表中占据两个字节(二进制16位)。所以,FAT16最大可以表示的簇号为0xFFFF,以32K为一簇的大小,FAT16可以管理的最大磁盘空间为:32KB×65536=2048B,所以FAT16最大支持2GB的分区。

  因此FAT表以2个字节为一个记录项,通常第1、2个记录项用作介质描述(0xF8、0xFF、0xFF、0xFF),从第3个记录项开始记录除根目录外的其他文件夹的簇链情况。具体FAT16表如何用很多个簇号链接表示见http://bbs.ednchina.com/BLOG_ARTICLE_226477.HTM,一个文件结尾的簇号为0xFFFF。

  三、文件目录

  根目录的位置紧随FAT2表之后,系统以32个字节为单位进行目录文件所占簇的分配,文件目录必须占据32个扇区

0x1A~0x1B为文件开始簇号,例如簇号为02 00,因为是使用小端模式,转化后簇号为00 02,根据这个可以找到文件第一个簇号在FAT1中的位置,0x1000H+02H*02H=1004H,因此可以计算文件第一簇数据存放地址为56×512(用户数据起始地址)+(02H-02H)×512(1簇占1个扇区),而在FAT1表1004H的地址上的数据为03 00,转换后为00 03,那么可以计算第二簇的数据存放地址为56×512(用户数据起始地址)+(03H-02H)×512(1簇占1个扇区),一直到FAT1表的某两个字节为FF FF时代表文件结束。

四、处理PC端发来的读写文件系统的固件程序

  U盘固件提供的功能:当主机要求读取某个扇区,定位到该扇区,从扇区里面读出内容,并输出给主机,他不需知道U盘是什么文件,只需把数据读出来,主机通过读取的扇区的内容来判断是什么文件系统。

FLASH知识:64kB的flash本身的sector为4kB,Page为256Byte。Page为写入数据的最小单位,sector为数据擦除的最小单位。

而现在作为文件系统,我已经修改为:LBA(Logical BlockAddress)128个,每个Block的大小为512Byte,128*512B=65536B=64kB。

处理好LBA和Pagenum的关系:LBA指起始逻辑块地址,即flash中的第几个Block(512Byte),Pagenum为有多少个逻辑块地址,最大为上面计算的128个Block。

因为现在文件系统Block的大小为512Bytes,而flash的page大小为256,所以每次写512字节要分两次来写。

SPI_Write_Page(buff,0,2*(LBA+Pagenum)-2);

SPI_Write_Page(buff,0,2*(LBA+Pagenum)-1);

case Read_10://回发MBR主引导扇区数据
    //sector:擦除数据的最小单位
    //page读写数据的最小单位
    // LBA:logical block address
    // PageNum:number of LBA
    // 16 sectors   1 sector=16 page   1 page=256 byte
    )
    {
        ;i<=PageNum;i++)
        {
            PageNumL=*(LBA+i-);
            SPI_READ_Page(, PageNumL);
            ;t<;t++)
            {
                FIFO_Write(buff + t*MaxSize, FIFO1, MaxSize);
                SFR_Write(EINCSRL,0x01);
                while(SFR_Read(EINCSRL) & 0x01);
            }
            PageNumH=*(LBA+i-)+;
            SPI_READ_Page(, PageNumH);
            ;t<;t++)
            {
                FIFO_Write(buff + t*MaxSize, FIFO1, MaxSize);
                SFR_Write(EINCSRL,0x01);
                while(SFR_Read(EINCSRL) & 0x01);
            }
        }
    }
    csw=;
    sendDebug(Read_10);
    sendDebug(LBA);
    sendDebug(PageNum);
break;
case Write_10://host向slave发数据并写在U 盘里面
    )
    {
        SPI_SECTOR_ERASE(LBA/);
        ;i<=PageNum;i++)
        {
            ;j<;j++)
            {
                ;t<;t++)
                    buff[*j+t]=SFR_Read(FIFO1);
                SFR_Write(EOUTCRSL,0x00);
            }
            PageNumL=*(LBA+i-);
            SPI_WRITE_Page(buff, , PageNumL);
            ;j<;j++)
            {
                ;t<;t++)
                    buff[*j+t]=SFR_Read(FIFO1);
                SFR_Write(EOUTCRSL,0x00);
            }
            PageNumH=*(LBA+i-)+;
            SPI_WRITE_Page(buff, , PageNumH);
        }
    }
    flags.epin1=;
    csw=;
    sendDebug(Write_10);
    sendDebug(LBA);
    sendDebug(PageNum);
break;

电子工程师名片——FAT16文件系统的更多相关文章

  1. 电子工程师名片——FAT16文件系统(转)

    源:电子工程师名片——FAT16文件系统 从8月8号开始,连续一个月利用每天下班时间和周末的时间终于初步完成了一个电子工程师的电路板名片,就像U盘一样,不过这个FLASH只有64KB的大小,用的单片机 ...

  2. 电子工程师名片——UFI Command,USB盘符的显示

    USB Mass Storage类规范概述        USB Mass storage Device协议即海量存储设备协议适用于硬盘,U盘等大容量存储设备.协议使用的接口端点有BulkIn.Bul ...

  3. 电子工程师名片——SPI NOR Flash

    使用了MX25L512的SPI接口的Flash 电路连接图: 总的大小512kb,即64kB,sector的大小为256 Bytes,block的大小为4k Bytes 调试时出现的问题: 1.Fla ...

  4. FAT16文件系统简介

    有必要说明一下,以下对FAT16系统的介绍,很多都是参考文献.由于FAT16系统一般在U盘.MMC卡.SD卡以及一些小型存储设备上使用比较多,以后把这些小型存储设备统称为存储卡,这里仅局限于对存储卡的 ...

  5. 基于stm32f103zet6的FAT16文件系统学习1(初识FAT16)

    有了之前读写block的基础之后,准备弄个文件系统,之前没有接触过这东西,所以有很多都晕晕的,但是看到fat的源代码之后还是挺有信心的,因为之前一直过uboot,所以这个文件当然是小巫见大巫了.首先来 ...

  6. 【操作系统】C语言编写的FAT16文件系统

    [操作系统]C语言编写的FAT16文件系统 这是操作系统的期末课程设计作业之一,主要功能是在物理内存中虚拟出一个1M大小的FAT16的文件系统,然后把它读入内存中,进行具体的文件操作,具体的实用性不大 ...

  7. 快速开发MQTT(一)电子工程师眼中的MQTT

    转载:https://zhuanlan.zhihu.com/p/54669124 DigCore 主页http://www.digcore.cn 文章首发于同名微信公众号:DigCore 欢迎关注同名 ...

  8. 解析FAT16文件系统

    引导扇区的信息如下: 1.  偏移地址00H,长度3,内容:EB 3C 90 跳转指令. 2.  偏移地址03H,长度8,内容:4D 53 44 4F 53 35 2E 30 为厂商标志和os 版本号 ...

  9. 基于stm32f103zet6的FAT16文件系统学习0(读SD卡扇区)

    SD卡已经看了两天了,主要是因为测试出来的卡容量不对,所以一直找原因,最终还是发现了,总比不过是单位上面出现了问题,或许是之前没有接触到SD的缘故吧,所以对其中的一些寄存器很不了解,一切都是重新开始, ...

随机推荐

  1. 【转】Kconfig,Makefile 和 .config

    原文网址:http://blog.csdn.net/nxh_love/article/details/11846861 最新在做Sensor驱动移植的时候,发现了Android driver 中有Kc ...

  2. 2016"百度之星" - 资格赛(Astar Round1) 1001

    思路:第一个做法就是:每读入起始位置i和结束位置j,就从这位置i到位置j计算,可是TLE了,后面我想想要是我输入一个最长的字符串,且以最大次数计算开始位置1到结束位置100000,那么这计算量是很大的 ...

  3. 【转】多文件目录下makefile文件递归执行编译所有c文件

    首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,即可编译所有c文件,包括子目录下的. 意义:自动化编译行为,以后编译自己的c文件时可把这些makefile文 ...

  4. 【转】vlc android 代码编译

    转自:http://blog.csdn.net/asircao/article/details/7734201 系统:ubuntu12.04代码:git://git.videolan.org/vlc- ...

  5. poj 3669 Meteor Shower(bfs)

    Description Bessie hears that an extraordinary meteor shower is coming; reports say that these meteo ...

  6. Promise 异步执行的同步操作

    Promise 是用来执行异步操作的. 但有时一个异步操作需要等其他的异步操作完成,这时候就可以使用then来做. function loadImageAsync(url) { return new ...

  7. 零拷贝概念 -- linux内核

    零拷贝(zero-copy) 备快速网络接口的主要技术. 零拷贝技术通过降低或消除关键通信路径影响速率的操作,降低传输数据的操作系统开销和协议处理开销,从而有效提高通信性能,实现快速传输数据. 零拷贝 ...

  8. Swift 全功能的绘图板开发

    要做一个全功能的绘图板,至少要支持以下这些功能: 支持铅笔绘图(画点) 支持画直线 支持一些简单的图形(矩形.圆形等) 做一个真正的橡皮擦 能设置画笔的粗细 能设置画笔的颜色 能设置背景色或者背景图 ...

  9. 在win2008 r2主域控制域上打开“组策略管理”报错“未打开组策略对对象。你可能没有合适的权限”

    在win2008 r2主域控制域上打开“组策略管理”报错“未打开组策略对对象.你可能没有合适的权限” 打开组策略管理其它选项提示:找不到指定路径.之前做过的操作:取消域控主机上的共享目录sysvol和 ...

  10. [canvas]通过动态生成像素点做绚丽效果

    本例中的粒子就是实实在在的像素,由js代码在canvas上动态生成的像素点!这些像素点通过一个运动方法有规律地动了起来.透过这个思路,我们可以想到很多很炫的效果,但是这个性能有待考察.实验证明,动态控 ...