从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. hdu 2807 The Shortest Path

    http://acm.hdu.edu.cn/showproblem.php?pid=2807 第一次做矩阵乘法,没有优化超时,看了别人的优化的矩阵乘法,就过了. #include <cstdio ...

  2. Codeforces 358D Dima and Hares

    http://codeforces.com/contest/358/problem/D 题意:给出n个数,每个数取走的贡献与相邻的数有关,如果取这个数的时候,左右的数都还没被取,那么权值为a,如果左右 ...

  3. UltraChart画柱状图上面显示数值

    http://www.cnblogs.com/kevin-h-wang/archive/2013/06/05/UltraChart.html 1.柱状图上显示数值 ? //第一种方法 this.Ult ...

  4. 测试jsp

    一. get.jsp <%@ page contentType="text/html;charset=UTF-8"%> <%@ page import=" ...

  5. 【转】ubuntu下解压缩zip,tar,tar.gz和tar.bz2文件

    原文网址:http://blog.sina.com.cn/s/blog_5da93c8f0101h1uj.html 在Linux下面如何去压缩文件或者目录呢? 在这里我们将学习zip, tar, ta ...

  6. Java宝典(四)------Java中也存在内存泄露。

    --Java中会存在内存泄露吗? --如果你想当然的以为Java里有了垃圾回收机制就不会存在内存泄露,那你就错了. Java里也会存在内存泄露! 我们慢慢来分析. 所谓内存泄露就是指一个不再被程序使用 ...

  7. UVa10653.Prince and Princess

    题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. Animation Override Controller动画重载器

    假设游戏有很多个小人, 每一个人有2种动画站立,跑.  在通常情况下每一个人物都需要一个动画控制器. 有没有想过定义一个动画控制器 无须在定义全新的动画充值器实现每一个小人都播放自己的动画呢?没错An ...

  9. pyqt信号事件相关网址说明及python相关

    pyqt在线文档: http://www.rzcucc.com/search/pyqt.sourceforge.net/Docs/PyQt4/-qdatetime-2.html PyQT信号槽_学习笔 ...

  10. handsontable插件事件

    Hook插件 afterChange (changes: Array, source: String):1个或多个单元格的值被改变后调用     changes:是一个2维数组包含row,prop,o ...