Fatfs文件系统04.docx
- 文档编号:9259650
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:36
- 大小:79.80KB
Fatfs文件系统04.docx
《Fatfs文件系统04.docx》由会员分享,可在线阅读,更多相关《Fatfs文件系统04.docx(36页珍藏版)》请在冰点文库上搜索。
Fatfs文件系统04
2015-04-18
FATFS文件管理系统
一、FATFS简介
FATFS是一个完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。
它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。
它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。
FATFS的特点有:
✧代码量少、效率高
✧多种配置选项
✧支持多卷(物理驱动器或分区,最多10个卷)
✧多个ANSI/OEM代码页包括DBCS
✧支持长文件名、ANSI/OEM或Unicode
✧支持RTOS
✧支持多种扇区大小
✧只读、最小化的API和I/O缓冲区等
二、FATFS层次结构图
最顶层是应用层,使用者无需理会FATFS的内部结构和复杂的FAT协议,只需要调用FATFS模块提供给用户的一系列应用接口函数,如f_open,f_read,f_write和f_close等,就可以像在PC上读/写文件那样简单。
中间层FATFS模块,实现了FAT文件读/写协议。
FATFS模块提供的是ff.c和ff.h。
除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。
需要我们编写移植代码的是FATFS模块提供的底层接口,它包括存储媒介读/写接口(diskI/O)和供给文件创建修改时间的实时时钟。
三、FATFS源码
1.源码下载
(1)在http:
//elm-chan.org/fsw/ff/00index_e.html下载FatFs源码R0.10b版本;
(2)打开压缩包,里面有doc和src两个文件夹,doc是对FatFs的一些介绍及更新说明,src为FatFs的源码;
2.FatFs源码介绍
(1)与硬件平台无关的文件
✧ffconf.hFATFS模块配置文件
✧ff.hFATFS和应用模块公用的包含文件
✧ff.cFATFS模块
✧diskio.hFATFS和diskI/O模块公用的包含文件
✧interger.h数据类型定义
✧option可选的外部功能(比如支持中文等)
(2)与硬件平台相关的文件
✧diskio.cFATFS和diskI/O模块接口层文件
(3)移植时,重要的选项配置
✧_FS_TINY。
这个选项在R0.07版本中开始出现,之前的版本都是以独立的C文件出现(FATFS和TinyFATFS),有了这个选项之后,两者整合在一起了,使用起来更方便。
我们使用FATFS,所以把这个选项定义为0即可。
✧_FS_READONLY。
这个用来配置是不是只读,本章我们需要读写都用,所以这里设置为0即可。
✧_USE_STRFUNC。
这个用来设置是否支持字符串类操作,比如f_putc,f_puts等,本章我们需要用到,故设置这里为1。
✧_USE_MKFS。
这个用来定时是否使能格式化,本章需要用到,所以设置这里为1。
✧_USE_FASTSEEK。
这个用来使能快速定位,我们设置为1,使能快速定位。
✧_USE_LABEL。
这个用来设置是否支持磁盘盘符(磁盘名字)读取与设置。
我们设置为1,使能,就可以通过相关函数读取或者设置磁盘的名字了。
✧_CODE_PAGE。
这个用于设置语言类型,包括很多选项(见FATFS官网说明),我们这里设置为936,即简体中文(GBK码,需要c936.c文件支持,该文件在option文件夹)。
✧_USE_LFN。
该选项用于设置是否支持长文件名(还需要_CODE_PAGE支持),取值范围为0~3。
0,表示不支持长文件名,1~3是支持长文件名,但是存储地方不一样,我们选择使用3,通过ff_memalloc函数来动态分配长文件名的存储区域。
✧_VOLUMES。
用于设置FATFS支持的逻辑设备数目,我们设置为2,即支持2个设备。
✧_MAX_SS。
扇区缓冲的最大值,一般设置为512。
四、FATFS源码移植步骤
1.数据类型
在integer.h文件中配置数据类型,根据编译器类型配置,如VC中int2字节,在KeilMDK中int占4字节。
Integer.h中的数据类型与MDK中相同,所见就不需要进行配置
2.配置FatFs
在ffconf.h中配置上面介绍的重要的选项配置和其他配置,重要的配置按照上面介绍的配置就可以了,其他配置保持默认;
3.函数编写
在diskio中编写底层驱动函数
∙disk_initialize-Initializediskdrive
∙disk_status-Getdiskstatus
∙disk_read-Readsector(s)
∙disk_write-Writesector(s)
∙disk_ioctl-Controldevicedependentfeatures
∙get_fattime-Getcurrenttime
首先需要定义存储器的号码,我们定义SD卡为0SPIFLASH为1,还需根据不同存储器的类型来定义存储的sector和block,下面介绍必须的六种底层驱动函数
(1)disk_initialize
DSTATUSdisk_initialize(
BYTEpdrv/*Physicaldrivenmuber(0..)*/
){
u8res=0;
switch(pdrv)
{
caseSD_CARD:
res=SD_Init();//SD卡初始化
break;
caseEX_FLASH:
//外部flash
W25QXX_Init();
FLASH_SECTOR_COUNT=2048*12;
break;
default:
res=1;
}
if(res)returnSTA_NOINIT;
elsereturn0;//初始化成功
}
对SD卡和SPIFLASH存储进行初始化
(2)
disk_status
DSTATUSdisk_status(
BYTEpdrv/*Physicaldrivenmuber(0..)*/
)
{
return0;
}
返回0即可,用不到
(3)disk_read
DRESULTdisk_read(
BYTEpdrv,/*Physicaldrivenmuber(0..)*/
BYTE*buff,/*Databuffertostorereaddata*/
DWORDsector,/*Sectoraddress(LBA)*/
UINTcount/*Numberofsectorstoread(1..128)*/
){
u8res=0;
if(!
count)returnRES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
caseSD_CARD:
//SD卡
res=SD_ReadDisk(buff,sector,count);
break;
caseEX_FLASH:
//外部flash
for(;count>0;count--)
{
W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
if(res==0x00)returnRES_OK;
elsereturnRES_ERROR;
}
根据存储器类型,调用存储器相关的读取程序
(4)
disk_write
#if_USE_WRITE
DRESULTdisk_write(
BYTEpdrv,/*Physicaldrivenmuber(0..)*/
constBYTE*buff,/*Datatobewritten*/
DWORDsector,/*Sectoraddress(LBA)*/
UINTcount/*Numberofsectorstowrite(1..128)*/
)
{
u8res=0;
if(!
count)returnRES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
caseSD_CARD:
//SD卡
res=SD_WriteDisk((u8*)buff,sector,count);
while(res)//写出错
{
SD_Init();//重新初始化SD卡
res=SD_WriteDisk((u8*)buff,sector,count);
//printf("sdwrerror:
%d\r\n",res);
}
break;
caseEX_FLASH:
//外部flash
for(;count>0;count--)
{
W25QXX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res==0x00)returnRES_OK;
elsereturnRES_ERROR;
}
#endif
同disk_read函数相同,调用各存储器写入函数进行读写,API接口
(5)disk_ioctl
//其他表参数的获得
//drv:
磁盘编号0~9
//ctrl:
控制代码
//*buff:
发送/接收缓冲区指针
#if_USE_IOCTL
DRESULTdisk_ioctl(
BYTEpdrv,/*Physicaldrivenmuber(0..)*/
BYTEcmd,/*Controlcode*/
void*buff/*Buffertosend/receivecontroldata*/
)
{
DRESULTres;
if(pdrv==SD_CARD)//SD卡
{
switch(cmd)
{
caseCTRL_SYNC:
res=RES_OK;
break;
caseGET_SECTOR_SIZE:
*(DWORD*)buff=512;
res=RES_OK;
break;
caseGET_BLOCK_SIZE:
*(WORD*)buff=SDCardInfo.CardBlockSize;
res=RES_OK;
break;
caseGET_SECTOR_COUNT:
*(DWORD*)buff=SDCardInfo.CardCapacity/512;
res=RES_OK;
break;
default:
res=RES_PARERR;
break;
}
}elseif(pdrv==EX_FLASH)//外部FLASH
{
switch(cmd)
{
caseCTRL_SYNC:
res=RES_OK;
break;
caseGET_SECTOR_SIZE:
*(WORD*)buff=FLASH_SECTOR_SIZE;
res=RES_OK;
break;
caseGET_BLOCK_SIZE:
*(WORD*)buff=FLASH_BLOCK_SIZE;
res=RES_OK;
break;
caseGET_SECTOR_COUNT:
*(DWORD*)buff=FLASH_SECTOR_COUNT;
res=RES_OK;
break;
default:
res=RES_PARERR;
break;
}
}elseres=RES_ERROR;//其他的不支持
returnres;
}
#endif
获得存储器信息,存储容量,sectorblock等
(6)get_fattime函数
没有用到,返回0即可
(7)memalloc和memfree函数等在长文件名功能时会应用
五、FATFS主要API函数及类型结构体和全局变量的介绍
1.结构体
(1)FATFS结构体
FATFS结构(文件系统对象)用来保存独立逻辑驱动器动态工作区域。
这个结构由应用程序给定,使用f_mount函数注册/注销FATFS模块。
在执行f_mount或媒体发生变化后,访问第一个文件时FATFS被初始化。
其他应用程序不能改变结构的任何成员变量。
typedefstruct{
BYTEfs_type;/*FATsub-type(0:
Notmounted)0表示为挂载*/
BYTEdrv;/*Physicaldrivenumber*/物理地址SD:
0FLASH1
BYTEcsize;/*Sectorspercluster(1,2,4...128)*/一个簇有多少扇区
BYTEn_fats;/*NumberofFATcopies(1or2)*/文件分配表数目
BYTEwflag;/*win[]flag(b0:
dirty)*/标记文件是否改写过
BYTEfsi_flag;/*FSINFOflags(b7:
disabled,b0:
dirty)*/标记文件系统信
息是否改动过
WORDid;/*FilesystemmountID*/文件系统挂载的ID
WORDn_rootdir;/*Numberofrootdirectoryentries(FAT12/16)*/根目录
区入口,用于FAT12/16,
#if_MAX_SS!
=_MIN_SS如果在ffconf中定义的不相等,定义的是一个
范围,在这里配置设置存储器sector大小
WORDssize;/*Bytespersector(512,1024,2048or4096)*/
#endif
#if_FS_REENTRANT如果可重入,定义同步对象
_SYNC_tsobj;/*Identifierofsyncobject*/
#endif
#if!
_FS_READONLY如果为可读写
DWORDlast_clust;/*Lastallocatedcluster*/上一个被分配的簇
DWORDfree_clust;/*Numberoffreeclusters*/空闲簇
#endif
#if_FS_RPATH允许相对目录使使用,存储当前目录起始簇
DWORDcdir;/*Currentdirectorystartcluster(0:
root)*/
#endif
DWORDn_fatent;/*NumberofFATentries,=numberofclusters+2*/FAT条目数量,等于簇+2
DWORDfsize;/*SectorsperFAT*/每个FAT扇区数量
DWORDvolbase;/*Volumestartsector*/卷起始扇区?
?
?
DWORDfatbase;/*FATstartsector*/FAT起始扇区
DWORDdirbase;/*Rootdirectorystartsector(FAT32:
Cluster#)*/
根目录起始扇区
DWORDdatabase;/*Datastartsector*/数据起始扇区
DWORDwinsect;/*Currentsectorappearinginthewin[]*/当前缓冲区
存储的扇区号
BYTEwin[_MAX_SS];/*DiskaccesswindowforDirectory,FAT(andfiledataattinycfg)*/单个扇区缓存
}FATFS;
(2)FIL结构体
FIL结构(文件对象)用来保存打开文件的状态。
它由f_open函数创建,由f_close函数废弃。
除cltbl外,其成员不能被其他应用程序改变。
注意:
在non-tiny配置情况下,在结构体中定义了一个扇区缓冲区,因此FIL结构不能够被定义为自动变量。
typedefstruct{
FATFS*fs;/*Pointertotherelatedfilesystemobject(**donotchangeorder**)*/指向相关文件系统的指针
WORDid;/*OwnerfilesystemmountID(**donotchangeorder**)*/所在文件系统的挂在编号,SD:
0FLASH:
1
BYTEflag;/*Statusflags*/状态标志
BYTEerr;/*Abortflag(errorcode)*/错误标志
DWORDfptr;/*Fileread/writepointer(Zeroedonfileopen)*/
文件读写指针,打开文件时清零
DWORDfsize;/*Filesize*/文件大小
DWORDsclust;/*Filestartcluster(0:
noclusterchain,always0whenfsizeis0)*/文件起始簇
DWORDclust;/*Currentclusteroffpter(notvalidwhenfprtis0)*/fpter指向的文件所在的当前簇
DWORDdsect;/*Sectornumberappearinginbuf[](0:
invalid)*/
#if!
_FS_READONLY当前数据扇区
DWORDdir_sect;/*Sectornumbercontainingthedirectoryentry*/
含有目录的扇区数量
BYTE*dir_ptr;/*Pointertothedirectoryentryinthewin[]*/
目录入口指针,(目录应该缓存在win[]中,猜测)
#endif
#if_USE_FASTSEEK指向簇链接映射表的指针
DWORD*cltbl;/*Pointertotheclusterlinkmaptable(Nulledonfileopen)*/
#endif
#if_FS_LOCK
UINTlockid;/*FilelockIDoriginfrom1(indexoffilesemaphoretableFiles[])*/
#endif
#if!
_FS_TINY数据读写缓冲
BYTEbuf[_MAX_SS];/*Fileprivatedataread/writewindow*/
#endif
}FIL;
(3)DIR目录结构体
DIR结构体被f_opendir,f_readdir函数用来读取工作区目录。
其他应用程序不能改变其成员变量。
typedefstruct{
FATFS*fs;/*Pointertotheownerfilesystemobject(**donotchangeorder**)*/文件系统指针
WORDid;/*OwnerfilesystemmountID(**donotchangeorder**)*/文件系统挂在编号SD:
0FALSH:
1
WORDindex;/*Currentread/writeindexnumber*/
当前读写目录索引号
DWORDsclust;/*Tablestartcluster(0:
Rootdir)*/
根目录表起始簇
DWORDclust;/*Currentcluster*/
当前簇,当前扇区
DWORDsect;/*Currentsector*/
当前短文件入口指针
BYTE*dir;/*PointertothecurrentSFNentryinthewin[]*/
BYTE*fn;/*PointertotheSFN(in/out){file[8],ext[3],status[1]}*/文件指针SFNshortfilename
#if_FS_LOCK
UINTlockid;/*FilelockID(indexoffilesemaphoretableFiles[])*/
#endif
#if_USE_LFN指向长文件名的指针缓冲
WCHAR*lfn;/*PointertotheLFNworkingbuffer*/
WORDlfn_idx;/*LastmatchedLFNindexnumber(0xFFFF:
NoLFN)*/
#endif最后匹配的长文件名索引号
}DIR;
(4)FILINFO文件
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Fatfs 文件系统 04