FATFS文件系统剖析全Word格式.docx
《FATFS文件系统剖析全Word格式.docx》由会员分享,可在线阅读,更多相关《FATFS文件系统剖析全Word格式.docx(11页珍藏版)》请在冰豆网上搜索。
![FATFS文件系统剖析全Word格式.docx](https://file1.bdocx.com/fileroot1/2023-2/5/b3ef54c2-80d1-4864-a961-74bb3deb7b6d/b3ef54c2-80d1-4864-a961-74bb3deb7b6d1.gif)
integer.h:
仅实现数据类型重定义,增加系统的可移植性。
ffconf.h:
文件系统配置---逐个配置,先配置实现一个最小的fat文件系统,下面来分析各配置选项:
#define_FFCONF8255
//版本号
#define
_FS_TINY
0
/*0:
Normalor1:
Tiny*/
//在这里与先前版本有些许变化,是通过配置头配置两种不同大小的文件系统,这里配置为0。
#define_FS_READONLY
1
//定义文件系统只读,也就不能写修改,在此定义为1,这样文件系统会大大缩小,简化学习理解过程。
#define_FS_MINIMIZE
3
/*0to3*/
这个选项是用于过滤掉一些文件系统功能,为0时是全功能,3是功能实现最小
_USE_STRFUNC
Disableor1/2:
Enable*/
是否使用字符串文件接口,为0,不使用
_USE_MKFS
0/*0:
Disableor1:
制作文件系统,这个功能实现是还要_FS_READONLY=0
#define
_USE_FORWARD
f_forwardfunction
实现还需_FS_TINY
=1
_USE_FASTSEEK
快速查找功能
#define_CODE_PAGE
936
//
-SimplifiedChineseGBK(DBCS,OEM,Windows)
_USE_LFN
/*0to3*/
0:
不使用长文件名
_MAX_LFN
255
/*MaximumLFNlengthtohandle(12to255)*/
_LFN_UNICODE
ANSI/OEMor1:
Unicode*/
#define_FS_RPATH
0
/*0to2*/不使用相对路径
/*---------------------------------------------------------------------------/
/PhysicalDriveConfigurations
/----------------------------------------------------------------------------*/
#define_VOLUMES
1
/*Numberofvolumes(logicaldrives)tobeused.*/
_MAX_SS
512
/*512,1024,2048or4096*/
512字节每扇区
_MULTI_PARTITION
Singlepartitionor1:
Multiplepartition*/
只有一个分区
_USE_ERASE
Enable*/
/*Toenablesectorerasefeature,set_USE_ERASEto1.*/
/SystemConfigurations
#define_WORD_ACCESS
/*0or1*/
Byte-by-byteaccess.
/*IncludeaheaderfileheretodefinesyncobjecttypesontheO/S*/
/*#include<
windows.h>
<
ucos_ii.h.h>
semphr.h>
orohters.*/
#define_FS_REENTRANT
同步选项
#define_FS_TIMEOUT
1000
/*Timeoutperiodinunitoftimeticks*/
_SYNC_t
HANDLE
/*O/Sdependenttypeofsyncobject.e.g.HANDLE,OS_EVENT*,IDandetc..*/
_FS_SHARE
Disableor>
=1:
共享选项
如上已经配置成了一个最小的fat文件系统。
Diskio.h:
底层驱动头文件,就一些状态宏的定义和底层驱动函数的申明,看源码一目了然。
实现相应的diskio.c。
根据我的配置:
只需要根据不同的存储介质实现相应的disk_initialize,disk_status,disk_read三个函数就够了,
我在这里实现上s3c2440上的SD卡驱动:
DSTATUSdisk_initialize(BYTEnDisk)
{
return1;
}
DSTATUSdisk_status(BYTEnDisk)
DRESULTdisk_read(BYTEnDisk,BYTE*b,DWORDc,BYTEd)
return
0;
编译报错
get_fattime没实现:
DWORDget_fattime(void)
return0;
转自博客,供大家相互交流!
FATFS文件系统剖析2:
分析下ff.h和ff.c两个文件。
先来分析ff.h中定义的几个结构体:
typedefstruct{
BYTE
fs_type;
//
系统类型,为0时系统没有被挂载
drv;
物理磁盘驱动号
csize;
每簇的扇区数目,
簇是文件数据分配的基本单位
n_fats;
文件分配表的数目,一般为两个(一个备份fat表)
//Fatfs文件系统应该是:
引导扇区,文件分配表2个,根目录区,和数据区
wflag;
文件活动窗体是否改动标志,为1要回写
fsi_flag;
文件信息回写标志
WORD
id;
文件系统加载id号
n_rootdir;
//根目录区目录项数目(针对FAT12/16,FAT32不使用)
#if_MAX_SS!
=512
ssize;
每扇区多少字节
#endif
#if_FS_REENTRANT
sobj;
//允许重入,则定义同步对象
#if!
_FS_READONLY
DWORD
last_clust;
//最新分配的簇
free_clust;
//空闲簇
fsi_sector;
//文件信息扇区(仅用于FAT32)
#if_FS_RPATH
cdir;
//使用相对路径,文件系统的当前起始路径
0(root路径)
n_fatent;
//文件分配表占用的扇区
n_fatent=数据簇数目+2
fsize;
//每FAT表有多少个扇区
fatbase;
//文件分配表开始扇区
dirbase;
//如果是FAT32,根目录开始扇区需要首先得到
database;
//数据起始扇区
winsect;
//win中当前指定的扇区
win[_MAX_SS];
//扇区操作缓存
}FATFS;
FATFS*
fs;
//指向的文件系统
//自身文件系统挂载id号
即fs->
id
flag;
//文件状态
pad1;
//文件在簇里面扇区偏移
(0--fs->
csize)
fptr;
//文件当前读写指针位置,当文件打开时为0
//文件大小(按字节计算)
org_clust;
//文件起始簇(0whenfsize==0)
curr_clust;
文件当前操作簇
dsect;
//文件当前操作扇区
dir_sect;
//包含路径入口的扇区号
BYTE*
dir_ptr;
//目录入口指针
#if_USE_FASTSEEK
DWORD*
cltbl;
//指向查找映射表的簇(nullonfileopen)
#if_FS_SHARE
UINT
lockid;
//文件锁ID号(indexoffilesemaphoretable)
_FS_TINY
buf[_MAX_SS];
//文件读写缓存
}FIL;
//对应的文件系统
index;
//目前读写索引号
/*Currentread/writeindexnumber*/
sclust;
//目录表起始簇
(0:
Rootdir)
clust;
//目前处理的簇
sect;
//目前簇里对应的扇区
dir;
//指向当前在win[]中的短文件名入口项/*PointertothecurrentSFNentryinthewin[]
fn;
//指向短文件名
(in/out){file[8],ext[3],status[1]}
#if_USE_LFN
WCHAR*
lfn;
//指向长文件名缓冲
/*PointertotheLFNworkingbuffer*/
lfn_idx;
/*LastmatchedLFNindexnumber(0xFFFF:
NoLFN)*/
}DIR;
typedefstruct{
//文件目录表项
大小=4+2+2+1+13
/*Filesize*/
fdate;
/*Lastmodifieddate*/
ftime;
/*Lastmodifiedtime*/
fattrib;
/*Attribute*///文件属性
TCHAR
fname[13];
/*Shortfilename(8.3format)*/
#if_USE_LFN
//长文件名支持
TCHAR*
lfname;
/*PointertotheLFNbuffer*/
UINT
lfsize;
/*SizeofLFNbufferinTCHAR*/
}FILINFO;
结构是搞清楚了,但其里面的具体联系怎么也还收理不清楚。
只有看ff.c来疏通了!
里面东西还是蛮多的,咋一看,3000多行类(太多,在这里就根据我的配置,进行逐个分析吧),从头到尾,一个一个来。
首先是三个内存操作和以个字符查找处理函数,不说不解释。
然后是:
static
FRESULTmove_window(
FATFS*fs,
/*Filesystemobject*/
DWORDsector
/*Sectornumbertomakeappearanceinthefs->
win[]*/
)
/*Movetozeroonlywritesbackdirtywindow*/
该函数就是把指定扇区sector中的数据读到fs->
win[]里面
DWORDclust2sect(
/*!
=0:
Sectornumber,0:
Failed-invalidcluster#*/
DWORDclst
/*Cluster#tobeconverted*/
)
计算簇clst在对应文件系统fs里面的扇区号
DWORDget_fat(
/*0xFFFFFFFF:
Diskerror,1:
Internalerror,Else:
Clusterstatus*/
/*Cluster#togetthelinkinformation*/
获取簇clst在文件系统fs中FAT表里面fat入口
FRESULTdir_sdi(
DIR*dj,
/*Pointertodirectoryobject*/
WORDidx
/*Directoryindexnumber*/
根据根目录索引号idx获取相应的目录信息存储到dj结构里面
FRESULTdir_next(
/*FR_OK:
Succeeded,FR_NO_FILE:
Endoftable,FR_DENIED:
EOTandcouldnotstretch*/
intstretch
Donotstretchtable,1:
Stretchtableifneeded*/
获取当前目录项的索引值+1,对应的目录项信息
FRESULTdir_find(
DIR*dj
/*Pointertothedirectoryobjectlinkedtothefilename*/
在目录表中查找与dj->
fn相同文件名的目录项
FRESULTcreate_name(
/*Pointertothedirectoryobject*/
constTCHAR**path
/*Pointertopointertothesegmentinthepathstring*/
创建一个文件名为path指向的dj目录项
FRESULTfollow_path(
/*FR_OK(0):
successful,!
errorcode*/
/*Directoryobjecttoreturnlastdirectoryandfoundobject*/
constTCHAR*path
/*Full-pathstringtofindafileordirectory*/
获取文件路径path对应的目录项填入dj里面
BYTEcheck_fs(
TheFATBR,1:
ValidBRbutnotanFAT,2:
NotaBR,3:
Diskerror*/
DWORDsect
/*Sector#(lba)tocheckifitisanFATbootrecordornot*/
读取文件系统fs的一号扇区,进行MBR检查,文件系统类型区分
FRESULTchk_mounted(
anyerroroccurred*/
constTCHAR**path,
/*Pointertopointertothepathname(drivenumber)*/
FATFS**rfs,
/*Pointertopointertothefoundfilesystemobject*/
BYTEchk_wp
Checkmediawriteprotectionforwriteaccess*/
测试文件系统是否已挂在,如没有,就进行挂载,文件系统结构初始化
FRESULTvalidate(
Theobjectisvalid,!
Invalid*/
/*Pointertothefilesystemobject*/
WORDid
/*Memberidofthetargetobjecttobechecked*/
检测文件系统是否可用
如下是现配置好的文件系统引出的四个接口函数:
FRESULTf_mount(
//挂在一个逻辑的文件系统
BYTEvol,
/*Logicaldrivenumbertobemounted/unmounted*/
FATFS*fs
/*Pointertonewfilesystemobject(NULLforunmount)*/
系统挂载
FRESULTf_open(
FIL*fp,
/*Pointertotheblankfileobject*/
constTCHAR*path,
/*Pointertothefilename*/
BYTEmode
/*Accessmodeandfileopenmodeflags*/
文件打开,包括(真正的文件系统初始化,系统检测)
FRESULTf_read(
FIL*fp,
/*Pointertothefileobject*/
void*buff,
/*Pointertodatabuffer*/
UINTbtr,
/*Numberofbytestoread*/
UINT*br
/*Pointertonumberofbytesread*/
文件读
FRESULTf_close(
FIL