对于FLASH/EEPROM等非易失性存储设备,通常需要存储很多数据,而且数据的用途和类型多种多样,通常我们读取和写入数据都是通过页寻址或者字节寻址或者模块寻址等方式,这种操作很不直观,用户使用起来也比较繁琐,不能满足人性化的需求,而实际上我们用户并不关心数据到底存在什么地方,而只要存进去了,而且能够正确的读出来就可以了,我们只需要给我们存储的数据块指定一个便于我们区分的名字即可,想对内容作修改就只要提供名字和内容和写入的数据量就可以了,至于它到底要写在存储器的什么位置,我们并不关心,而且只需提供名字,就能对对应的数据块进行删除,新建等操作。而文件系统往简单了说,就是实现了这样功能的系统。我们把一个功能数据块称作一个文件,由于我们只关心文件名和文件内容,不关心存储地址,因此文件系统实现了当我需要存储数据时,它能自行给我分配一个未被使用的空间,并注上我的文件名,下次我需要读取时,只需要根据该文件名就能找到对应数据的位置。当然这只是最基本的功能,也只是设想,但实现方式还是看看人家专业人士编写的fatfs吧!
在讲fatfs前先要认识一下你需要将此文件系统移向的平台,因为文件系统需要根据我所在平台作相应的更改,还要写好底层的flash驱动后,文件系统才能使用,现就拿我用的ATMEL公司的data flash来说吧!了解一个非易性存储设备,需要从以下几个性能入手:
1.在目标板的电路上,使用的是哪种接口(SPI/IO)
2.存储器的容量大小,存储结构图,寻址方式(我用的AT45B64系列,有两个SRAM,用作缓冲,每个均1024/1046(可通过写寄存器来选择)BYTE,可字节寻址;存储器每page1024/1046字节,写只能页寻址,读可页寻址,也可字节寻址,)
3.各种功能寄存器的用法,(通信前,先根据相应的寄存器读取器件的ID号看是否相符,以保证正常的通信,然后是状态寄存器(如果有的话)深入了解其功能以便编程)
4.操作方式和流程。(写页,写buffer,读页,读buffer,擦除等,)
5.了解时序,供调试时检错用。
根据以上的特性,驱动FLASH,保证正常的通信后,我们就可以开始移植fatfs,下面先介绍下fasfs。
fatfs实现的方式:在flash中,除了写入需要存储的数据外,还存入了数据相关的属性及设备相关的属性,根据这些属性再进行操作,如打开,编缉,新建,删除,重命名等等。
fatfs规范了属性的写入:
sector 0:DBR(DOS BOOT RECORD)专用于记录了设备相关的属性参数及操作系统引导代码(未用到),现以FAT16为例说明:
1.跳转指令
2.OEM ID
3.BPB
4.扩展BPB
5.引导程序代码(我未用到均为0)
6.扇区结束标志符(0x55AA)
(sector即可分割的最小单元扇区,即相当于存储设备的page)
此扇区的所有参数,在格式化时进行设定。一量格式化完成,这些值都是不变的,除非重新格式化。
格式化时,未使用到的区域都设置成0。
上述6个参数块中,比较重要的是BPB,这里记录了,关于设备的扇区的大小和个数,簇大小和个数,使用的文件系统类型和名字,要目录数及起扇区,FAT数及起扇区等等,具体信息如下:
1.一个扇区字节数,(我们的最小操作单元为page因此为1024字节)
2.每簇扇区数(可自行定义,但原则是,每簇扇区数*每扇区字节数《=32KB针对FAT16而言)
3.保留扇区数(供系统使用的包括引导扇区)
4.FAT数(该分区FAT的副本个数)
5.根目录项数(根目录下允许存放的32字节长名称的文件夹和文件的总个数)
6.小扇区数(用大扇区来取代为总的page数)
7.媒体描述符(描述此硬件的类型FDISK/SFD)
8.每fat有扇区数
9.每道扇区数(兼容硬盘存在的)
10.磁头数(兼容硬盘存在的)
11.隐藏扇区数(引导扇区之前的扇区数)
12.大扇区数
扩展BPB字段:
1.物理驱动号
2.保留
3.扩展引导标签
4.卷序号(分区号,随机产生的,多分区情况下用于区分磁盘)
5.卷标(用来保存卷标号)
6.文件系统类型(FAT/FAT12/FAT16)
以上是扇区0内容,与硬件参数有关,用户仅可在格式化的时候改动,一旦确定不改变,除非再次格式化。
接下来介绍FAT(file allocation table)
(分区开始+保留扇区数)为开始+(每FAT sector数*FAT(副本数))占用扇区个数 结束
此处主要记录了簇(簇为FAT的最小分配单元)的使用情况,用链式结构来索引,以(F8或者F0) FF FF FF 前四个字节固定,表示FAT 介质描述符,不参与簇链关系,簇从第四个字节开始,第四个字节和第五字节是第2簇号(簇的起始号为2),两字节里的内容表示下一个簇的簇号,如果为FF FF则表示,此文件较小仅使用了当前一个簇,如果非FF FF ,则除了使用了当前簇外,还使用了当前簇中所存放簇号中的簇,再跳往此簇号所对应的位置,如果是FF FF则仅使用了两个簇,如非,就同上,再去跳往此簇中存放的簇号对应的位置,直至为FF为止。可见此扇区中仅记录了,所有文件的占用簇的链接关系,而没有存放任何的数据,我们只要根据这些簇号,找出对应簇号中的数据,才实现了对数据的访问。FAT表结束后,就是目录项。
接下来,介绍目录项:目录项用32字节表示,是文件的入口参数信息,里面记录了文件名,扩展名,属性(读/写/隐藏/子目录/系统/归档),创建时间(精确到毫秒),创建日期,文件长度,开始的首簇高16位和低16位(根据首簇去FAT表中查找该文件占用了哪些的簇),最近修改时间,最近修改日期。
根目录总共占用32 sector后,就是以簇号为2开始的数据域。