您好,欢迎访问三七文档
fatfs文件系统源码分析一、概述1、目的在移植之前,先将源代码大概的阅读一遍,主要是了解文件系统的结构、各个函数的功能和接口、与移植相关的代码等等。2、准备工作在官方网站下载了0.07c版本的源代码,利用记事本进行阅读。二、源代码的结构1、源代码组成源代码压缩包解压后,共两个文件夹,doc是说明,src里就是代码。src文件夹里共五个文件和一个文件夹。文件夹是option,还有00readme.txt、diskio.c、diskio.h、ff.c、ff.h、integer.h。对比网上的文章,版本已经不同了,已经没有所谓的tff.c和tff.h了,估计现在都采用条件编译解决这个问题了,当然文件更少,可能编译选项可能越复杂。2、00readme.txt的说明LowleveldiskI/OmoduleisnotincludedinthisarchivebecausetheFatFsmoduleisonlyagenericfilesystemlayerandnotdependonanyspecificstoragedevice.YouhavetoprovidealowleveldiskI/Omodulethatwrittentocontrolyourstoragedevice.主要是说不包含底层IO代码,这是个通用文件系统可以在各种介质上使用。我们移植时针对具体存储设备提供底层代码。接下来做了版权声明-可以自由使用和传播。然后对版本的变迁做了说明。3、源代码阅读次序先读integer.h,了解所用的数据类型,然后是ff.h,了解文件系统所用的数据结构和各种函数声明,然后是diskio.h,了解与介质相关的数据结构和操作函数。再把ff.c和diskio.c两个文件所实现的函数大致扫描一遍。最后根据用户应用层程序调用函数的次序仔细阅读相关代码。三、源代码阅读1、integer.h头文件这个文件主要是类型声明。以下是部分代码。typedefintINT;typedefunsignedintUINT;typedefsignedcharCHAR;/*Thesetypesmustbe8-bitinteger*/都是用typedef做类型定义。移植时可以修改这部分代码,特别是某些定义与你所在工程的类型定义有冲突的时候。2、ff.h头文件以下是部分代码的分析#include“integer.h”使用integer.h的类型定义#ifndef_FATFS#define_FATFS0x007C版本号007c,0.07c#define_WORD_ACCESS0//如果定义为1,则可以使用word访问。中间有一些看着说明很容易弄清楚意思。这里就不例举了。#define_CODE_PAGE936/*The_CODE_PAGEspecifiestheOEMcodepagetobeusedonthetargetsystem./936–SimplifiedChineseGBK(DBCS,OEM,Windows)跟据这个中国应该是936.打开option文件夹看一下。打开cc936.c文件,里面有一个很大的数组staticconstWCHARuni2oem[]。根据英文说明,这个数组用于unicode码和OEM码之间的相互转换。接下来又有两个函数ff_convert()和ff_wtoupper()具体执行码型转换和将字符转换为大写。百度一下:看OEM码什么意思。unicode是一种双字节字符编码,无论中文还是英文,或者其他语言统一到2个字节。与现有的任何编码(ASCII,GB等)都不兼容。WindowsNT(2000)的内核即使用该编码,所有数据进入内核前转换成UNICODE,退出内核后在转换成版本相关的编码(通常称为OEM,在简体中文版下即为GB).(百度所得)继续往下阅读。#define_USE_LFN1//这个估计是长文件名支持了,以前的0.06版本好像是不支持。#define_MAX_LFN255//最长支持255个双字节字符。#define_FS_RPATH0//是否文件相对路径选项。/*When_FS_RPATHissetto1,relativepathfeatureisenabledandf_chdir,/f_chdrivefunctionareavailable.//有些函数会受影响。/Notethatoutputofthef_readdirfnctionisaffectedbythisoption.*/#define_FS_REENTRANT0//如果要支持文件系统可重入,必须加入几个函数。#define_TIMEOUT1000/*TimeoutperiodinunitoftimeticksoftheOS*/#define_SYNC_tHANDLE/*TypeofsyncobjectusedontheOS.e.g.HANDLE,OS_EVENT*,IDandetc..*//*TomaketheFatFsmodulere-entrant,set_FS_REENTRANTto1andadduser/providedsynchronizationhandlers,ff_req_grant,ff_rel_grant,ff_del_syncobj/andff_cre_syncobjfunctiontotheproject.*/#elif_CODE_PAGE==936/*SimplifiedChineseGBK*/#define_DF1S0×81#define_DF1E0xFE#define_DS1S0×40#define_DS1E0x7E#define_DS2S0×80#define_DS2E0xFE接下来很大一部分都是与语言相关的因素,略过。/*Charactercodesupportmacros*/三个宏判断是否大写、小写、数字。#defineIsUpper(c)(((c)=’A')&&((c)=’Z'))#defineIsLower(c)(((c)=’a')&&((c)=’z'))#defineIsDigit(c)(((c)=’0′)&&((c)=’9′))#if_DF1S/*DBCSconfiguration*/双字节编码相关的设定,暂时不理会它。#if_MULTI_PARTITION/*Multiplepartitionconfiguration*///该变量定义为1时,支持一个磁盘的多个分区。typedefstruct_PARTITION{BYTEpd;/*Physicaldrive#*/BYTEpt;/*Partition#(0-3)*/}PARTITION;ExternconstPARTITIONDrives[];//如果支持分区,则声明变量Drivers#defineLD2PD(drv)(Drives[drv].pd)/*获得磁盘对应的物理磁盘#defineLD2PT(drv)(Drives[drv].pt)/*获得磁盘对应的分区#else/*Singlepartitionconfiguration*/#defineLD2PD(drv)(drv)/*Physicaldrive#isequaltothelogicaldrive#*/#defineLD2PT(drv)0/*Alwaysmountsthe1stpartition*/#if_MAX_SS==512//一般扇区长度取512字节。#defineSS(fs)512U#if_LFN_UNICODE&&_USE_LFNtypedefWCHARXCHAR;/*Unicode*/XCHAR是文件名的码型所用。#elsetypedefcharXCHAR;/*SBCS,DBCS*/#endiftypedefstruct_FATFS_{BYTEfs_type;/*FATsubtype*/BYTEdrive;/*对应实际驱动号01—*/BYTEcsize;/*每个簇的扇区数目*/先查一下簇的含义:应该是文件数据分配的基本单位。BYTEn_fats;/*文件分配表的数目*/FAT文件系统依次应该是:引导扇区、文件分配表两个、根目录区和数据区。BYTEwflag;/*win[]dirtyflag(1:mustbewrittenback)*///文件是否改动的标志,为1时要回写。WORDid;/*FilesystemmountID文件系统加载ID*/WORDn_rootdir;/*根目录区目录项的数目*/#if_FS_REENTRANT_SYNC_tsobj;/*允许重入,则定义同步对象*/#endif#if_MAX_SS!=512WORDs_size;/*Sectorsize*/#endif#if!_FS_READONLY//文件为可写BYTEfsi_flag;/*fsinfodirtyflag(1:mustbewrittenback)*///文件需要回写的标志DWORDlast_clust;/*Lastallocatedcluster*/DWORDfree_clust;/*Numberoffreeclusters*/DWORDfsi_sector;/*fsinfosector*/#endif#if_FS_RPATHDWORDcdir;/*使用相对路径,则要存储文件系统当前目录#endifDWORDsects_fat;/*文件分配表占用的扇区DWORDmax_clust;/*最大簇数DWORDfatbase;/*文件分配表开始扇区DWORDdirbase;/*如果是FAT32,根目录开始扇区需要首先得到。DWORDdatabase;/*数据区开始扇区DWORDwinsect;/*Currentsectorappearinginthewin[]*///目前的扇区在win[]里面,这个win[]数组暂时还不知道含义。BYTEwin[_MAX_SS];/*DiskaccesswindowforDirectory/FAT*///这是一个win[512]数组,存储着一个扇区,好像作为扇区缓冲使用。}FATFS;typedefstruct_DIR_{FATFS*fs;/*Pointertotheownerfilesystemobject*/指向相应文件系统对象。WORDid;/*文件系统加载ID*/WORDindex;/*Currentread/writeindexnumber*/目前读写索引代码DWORDsclust;/*Tablestartcluster(0:Statictable)*/文件数据区开始簇DWORDclust;/*Currentcluster*/目前处理的簇DWORDsect;/*Currentsector*/目前簇里对应的扇区BYTE*dir;/*PointertothecurrentSFNentryinthewin[]*/BYTE*fn;/*PointertotheSFN(in/out){file[8],ext[3],status[1]}*/#if_USE_LFNWCHAR*lfn;/*PointertotheLFNworkingbuffer*/指向长文件名缓冲。WORDlfn_idx;/*LastmatchedLFNindexnumber(0xFFFF:NoLFN)*/#endif}DIR;typedefstruct_FIL_{FATFS*fs;/*Pointertotheownerfilesystemobject*/WORDid;/*OwnerfilesystemmountID*/BYTEflag;/*Filestatusflags*/文件状态标志BYTEcsect;/*Sectoraddressinthecluster*/扇区偏移DWORDfptr;/*FileR/Wpointer*/读写指针DWORDfsize;/*Filesize*/DWORDorg_clust;/*Filestartcluster*/文件开始簇DWORDcurr_clust;/*Curr
本文标题:文件系统源码分析
链接地址:https://www.777doc.com/doc-3355605 .html