FATFS文件系统剖析全.docx

上传人:b****8 文档编号:9694376 上传时间:2023-02-05 格式:DOCX 页数:11 大小:20.27KB
下载 相关 举报
FATFS文件系统剖析全.docx_第1页
第1页 / 共11页
FATFS文件系统剖析全.docx_第2页
第2页 / 共11页
FATFS文件系统剖析全.docx_第3页
第3页 / 共11页
FATFS文件系统剖析全.docx_第4页
第4页 / 共11页
FATFS文件系统剖析全.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

FATFS文件系统剖析全.docx

《FATFS文件系统剖析全.docx》由会员分享,可在线阅读,更多相关《FATFS文件系统剖析全.docx(11页珍藏版)》请在冰豆网上搜索。

FATFS文件系统剖析全.docx

FATFS文件系统剖析全

FATFS文件系统剖析1:

FAT16:

数据按照其不同的特点和作用大致可分为5部分:

MBR区、DBR区、FAT区、DIR区和DATA区,相比fat12多了DBR区

    Mainbootrecord:

MBR(0--1bdh)       磁盘参数存放

                                DPT(1beh--1fdh)  磁盘分区表

                                55,aa                    分区结束标志

   DBR(DosBootRecord)是操作系统引导记录区的意思

   FAT区(有两个,一个备份):

对于fat16,每一个fat项16位,所以可寻址的簇项数为65535(2的16次方)。

而其每簇大小不超 过32k,所以其每个分区最大容量为2G。

fat32,每一个fat项32位,可寻址簇数目为2的32次方。

   DIR区(根目录区):

紧接着第二FAT表(即备份的FAT表)之后,记录着根目录下每个文件(目录)的起始单元,文件的属性等。

定位文件位置时,操作系统根据DIR中的起始单元,结合FAT表就可以知道文件在硬盘中的具体位置和大小了。

   DATA区:

实际文件内容存放区。

FAT32:

   暂时放在这里,不讨论!

Fatfs:

嵌入式fat文件系统,支持fat16,fat32。

      包含有ff.h,diskio.h,integer.h,ffconf.h四个头文件以及ff.c文件系统实现。

当然要实现具体的应用移植,自己要根据diskio.h实现其diskio。

c底层驱动。

          diskio.h:

  底层驱动头文件

          ff.h       :

 文件系统实现头文件,定义有文件系统所需的数据结构

          ff.c        :

 文件系统的具体实现

如下开始逐个文件加以分析:

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是功能实现最小

             #define _USE_STRFUNC  0 /*0:

Disableor1/2:

Enable*/ 是否使用字符串文件接口,为0,不使用

             #define _USE_MKFS         0/*0:

Disableor1:

Enable*/  制作文件系统,这个功能实现是还要_FS_READONLY=0

              #define _USE_FORWARD 0  /*0:

Disableor1:

Enable*/  f_forwardfunction  实现还需_FS_TINY =1                  

              #define _USE_FASTSEEK 0   /*0:

Disableor1:

Enable*/  快速查找功能               

             #define_CODE_PAGE      936   //  936 -SimplifiedChineseGBK(DBCS,OEM,Windows)

    

             #define _USE_LFN    0       /*0to3*/   0:

不使用长文件名

             #define _MAX_LFN    255   /*MaximumLFNlengthtohandle(12to255)*/

             #define _LFN_UNICODE  0  /*0:

ANSI/OEMor1:

Unicode*/

 

            #define_FS_RPATH   0  /*0to2*/不使用相对路径

/*---------------------------------------------------------------------------/

/PhysicalDriveConfigurations

/----------------------------------------------------------------------------*/

        #define_VOLUMES  1             

        /*Numberofvolumes(logicaldrives)tobeused.*/

        #define _MAX_SS     512  /*512,1024,2048or4096*/  512字节每扇区

         #define _MULTI_PARTITION     0 /*0:

Singlepartitionor1:

Multiplepartition*/  只有一个分区

        #define _USE_ERASE   0 /*0:

Disableor1:

Enable*/

         /*Toenablesectorerasefeature,set_USE_ERASEto1.*/

/*---------------------------------------------------------------------------/

/SystemConfigurations

/----------------------------------------------------------------------------*/

          #define_WORD_ACCESS 0 /*0or1*/  0:

Byte-by-byteaccess.

/*IncludeaheaderfileheretodefinesyncobjecttypesontheO/S*/

/*#include,,orohters.*/          

          #define_FS_REENTRANT   0  /*0:

Disableor1:

Enable*/  同步选项

          #define_FS_TIMEOUT       1000 /*Timeoutperiodinunitoftimeticks*/

          #define _SYNC_t                HANDLE /*O/Sdependenttypeofsyncobject.e.g.HANDLE,OS_EVENT*,IDandetc..*/

          #define _FS_SHARE       0 /*0:

Disableor>=1:

Enable*/ 共享选项

      如上已经配置成了一个最小的fat文件系统。

Diskio.h:

底层驱动头文件,就一些状态宏的定义和底层驱动函数的申明,看源码一目了然。

    实现相应的diskio.c。

      根据我的配置:

只需要根据不同的存储介质实现相应的disk_initialize,disk_status,disk_read三个函数就够了,

我在这里实现上s3c2440上的SD卡驱动:

DSTATUSdisk_initialize(BYTEnDisk) 

{

 return1;

}

DSTATUSdisk_status(BYTEnDisk) 

{

 return1;

}

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时系统没有被挂载

 BYTE drv;         // 物理磁盘驱动号

 BYTE csize;      // 每簇的扇区数目, 簇是文件数据分配的基本单位   

 BYTE n_fats;    // 文件分配表的数目,一般为两个(一个备份fat表)     

         //Fatfs文件系统应该是:

引导扇区,文件分配表2个,根目录区,和数据区

     

 BYTE wflag;     // 文件活动窗体是否改动标志,为1要回写 

 BYTE fsi_flag;  // 文件信息回写标志 

 WORD id;        // 文件系统加载id号 

 WORD n_rootdir;    //根目录区目录项数目(针对FAT12/16,FAT32不使用) 

#if_MAX_SS!

=512

 WORD ssize;    // 每扇区多少字节

#endif

#if_FS_REENTRANT

 _SYNC_t sobj;  //允许重入,则定义同步对象 

#endif

#if!

_FS_READONLY

 DWORD last_clust; //最新分配的簇  

 DWORD free_clust; //空闲簇

 DWORD fsi_sector;  //文件信息扇区(仅用于FAT32)

#endif

#if_FS_RPATH

 DWORD cdir;  //使用相对路径,文件系统的当前起始路径 0(root路径)

#endif

 DWORD n_fatent; //文件分配表占用的扇区    n_fatent=数据簇数目+2

 DWORD fsize;      //每FAT表有多少个扇区      

 DWORD fatbase; //文件分配表开始扇区    

 DWORD dirbase; //如果是FAT32,根目录开始扇区需要首先得到 

 DWORD database; //数据起始扇区    

 DWORD winsect;   //win中当前指定的扇区

 BYTE win[_MAX_SS];  //扇区操作缓存

}FATFS;

typedefstruct{

 FATFS* fs;   //指向的文件系统 

 WORD id;    //自身文件系统挂载id号 即fs->id

 BYTE flag;    //文件状态 

 BYTE pad1;  //文件在簇里面扇区偏移 (0--fs->csize)

 DWORD fptr; //文件当前读写指针位置,当文件打开时为0 

 DWORD fsize; //文件大小(按字节计算)

 DWORD org_clust;  //文件起始簇(0whenfsize==0) 

 DWORD curr_clust;  // 文件当前操作簇

 DWORD dsect;   //文件当前操作扇区

#if!

_FS_READONLY

 DWORD dir_sect;  //包含路径入口的扇区号 

 BYTE* dir_ptr;      //目录入口指针

#endif

#if_USE_FASTSEEK

 DWORD* cltbl;     //指向查找映射表的簇(nullonfileopen)

#endif

#if_FS_SHARE

 UINT lockid;        //文件锁ID号(indexoffilesemaphoretable)

#endif

#if!

_FS_TINY

 BYTE buf[_MAX_SS];  //文件读写缓存

#endif

}FIL;

 

typedefstruct{

 FATFS* fs;        //对应的文件系统  

 WORD id;          //自身文件系统挂载id号 即fs->id

 WORD index;    //目前读写索引号  /*Currentread/writeindexnumber*/

 DWORD sclust; //目录表起始簇  (0:

Rootdir) 

 DWORD clust;   //目前处理的簇   

 DWORD sect;    //目前簇里对应的扇区

 BYTE* dir;   //指向当前在win[]中的短文件名入口项/*PointertothecurrentSFNentryinthewin[] 

 BYTE* fn;   //指向短文件名 (in/out){file[8],ext[3],status[1]}

#if_USE_LFN

 WCHAR* lfn;    //指向长文件名缓冲  /*PointertotheLFNworkingbuffer*/

 WORD lfn_idx;  /*LastmatchedLFNindexnumber(0xFFFF:

NoLFN)*/

#endif

}DIR;

 

typedefstruct{  //文件目录表项 大小=4+2+2+1+13

 DWORD fsize;   /*Filesize*/            

 WORD fdate;    /*Lastmodifieddate*/

 WORD ftime;     /*Lastmodifiedtime*/

 BYTE fattrib;      /*Attribute*///文件属性

 TCHAR fname[13];  /*Shortfilename(8.3format)*/

#if_USE_LFN   //长文件名支持

 TCHAR* lfname;   /*PointertotheLFNbuffer*/

 UINT lfsize;          /*SizeofLFNbufferinTCHAR*/

#endif

}FILINFO;

 

结构是搞清楚了,但其里面的具体联系怎么也还收理不清楚。

只有看ff.c来疏通了!

  里面东西还是蛮多的,咋一看,3000多行类(太多,在这里就根据我的配置,进行逐个分析吧),从头到尾,一个一个来。

 首先是三个内存操作和以个字符查找处理函数,不说不解释。

 然后是:

static

FRESULTmove_window(

 FATFS*fs,  /*Filesystemobject*/

 DWORDsector /*Sectornumbertomakeappearanceinthefs->win[]*/

)     /*Movetozeroonlywritesbackdirtywindow*/

该函数就是把指定扇区sector中的数据读到fs->win[]里面

 

DWORDclust2sect( /*!

=0:

Sectornumber,0:

Failed-invalidcluster#*/

 FATFS*fs,  /*Filesystemobject*/

 DWORDclst  /*Cluster#tobeconverted*/

计算簇clst在对应文件系统fs里面的扇区号

 

DWORDget_fat( /*0xFFFFFFFF:

Diskerror,1:

Internalerror,Else:

Clusterstatus*/

 FATFS*fs, /*Filesystemobject*/

 DWORDclst /*Cluster#togetthelinkinformation*/

 获取簇clst在文件系统fs中FAT表里面fat入口

 

static

FRESULTdir_sdi(

 DIR*dj,  /*Pointertodirectoryobject*/

 WORDidx  /*Directoryindexnumber*/

根据根目录索引号idx获取相应的目录信息存储到dj结构里面

 

static

FRESULTdir_next( /*FR_OK:

Succeeded,FR_NO_FILE:

Endoftable,FR_DENIED:

EOTandcouldnotstretch*/

 DIR*dj,  /*Pointertodirectoryobject*/

 intstretch  /*0:

Donotstretchtable,1:

Stretchtableifneeded*/

获取当前目录项的索引值+1,对应的目录项信息

 

static

FRESULTdir_find(

 DIR*dj   /*Pointertothedirectoryobjectlinkedtothefilename*/

在目录表中查找与dj->fn相同文件名的目录项

 

static

FRESULTcreate_name(

 DIR*dj,   /*Pointertothedirectoryobject*/

 constTCHAR**path /*Pointertopointertothesegmentinthepathstring*/

创建一个文件名为path指向的dj目录项

 

static

FRESULTfollow_path( /*FR_OK(0):

successful,!

=0:

errorcode*/

 DIR*dj,   /*Directoryobjecttoreturnlastdirectoryandfoundobject*/

 constTCHAR*path /*Full-pathstringtofindafileordirectory*/

获取文件路径path对应的目录项填入dj里面

 

static

BYTEcheck_fs( /*0:

TheFATBR,1:

ValidBRbutnotanFAT,2:

NotaBR,3:

Diskerror*/

 FATFS*fs, /*Filesystemobject*/

 DWORDsect /*Sector#(lba)tocheckifitisanFATbootrecordornot*/

读取文件系统fs的一号扇区,进行MBR检查,文件系统类型区分

 

static

FRESULTchk_mounted( /*FR_OK(0):

successful,!

=0:

anyerroroccurred*/

 constTCHAR**path, /*Pointertopointertothepathname(drivenumber)*/

 FATFS**rfs,  /*Pointertopointertothefoundfilesystemobject*/

 BYTEchk_wp   /*!

=0:

Checkmediawriteprotectionforwriteaccess*/

测试文件系统是否已挂在,如没有,就进行挂载,文件系统结构初始化

 

static

FRESULTvalidate( /*FR_OK(0):

Theobjectisvalid,!

=0:

Invalid*/

 FATFS*fs,  /*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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1