stm32sdiofatfs文件系统源码分析.docx

上传人:b****8 文档编号:27705631 上传时间:2023-07-04 格式:DOCX 页数:16 大小:24.10KB
下载 相关 举报
stm32sdiofatfs文件系统源码分析.docx_第1页
第1页 / 共16页
stm32sdiofatfs文件系统源码分析.docx_第2页
第2页 / 共16页
stm32sdiofatfs文件系统源码分析.docx_第3页
第3页 / 共16页
stm32sdiofatfs文件系统源码分析.docx_第4页
第4页 / 共16页
stm32sdiofatfs文件系统源码分析.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

stm32sdiofatfs文件系统源码分析.docx

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

stm32sdiofatfs文件系统源码分析.docx

stm32sdiofatfs文件系统源码分析

、概述

1、目的

在移植之前,先将源代码大概的阅读一遍,主要是了解文件系统的结构、

各个函数的功能和接口、与移植相关的代码等等。

2、准备工作

在官方网站下载了0.07c版本的源代码,利用记事本进行阅读。

二、源代码的结构

1、源代码组成

源代码压缩包解压后,共两个文件夹,doc是说明,src里就是代码。

src文件夹里共五个文件和一个文件夹。

文件夹是option,还有OOreadme.txt、

diskio.c、diskio.h、ff.c、ff.h、integer.h。

对比网上的文章,版本已经不同了,已经没有所谓的tff.c和tff.h了,估计现在都采用条件编译解决这个问题了,当然文件更少,可能编译选项可能越复杂。

2、00readme.txt的说明

LowleveldiskI/OmoduleisnotincludedinthisarchivebecausetheFatFs

moduleisonlyagenericfilesystemlayerandnotdependonanyspecific

storagedevice.YouhavetoprovidealowleveldiskI/Omodulethatwritten

tocontrolyourstoragedevice.主要是说不包含底层10代码,这是个通用文

件系统可以在各种介质上使用。

我们移植时针对具体存储设备提供底层代码。

接下来做了版权声明-可以自由使用和传播。

然后对版本的变迁做了说明。

3、源代码阅读次序

先读integer.h,了解所用的数据类型,然后是ff.h,了解文件系统所用的数据结构和各种函数声明,然后是diskio.h,了解与介质相关的数据结构和操作函数。

再把ff.c和diskio.c两个文件所实现的函数大致扫描一遍。

最后根据用户应用层程序调用函数的次序仔细阅读相关代码。

三、源代码阅读

1、integer.h头文件

这个文件主要是类型声明。

以下是部分代码。

typedefintINT;

typedefunsignedintUINT;

typedefsignedcharCHAR;/*Thesetypesmustbe8-bitinteger*/

都是用typedef做类型定义。

移植时可以修改这部分代码,特别是某些定义与你所在工程的类型定义有冲突的时候。

2、ff.h头文件

以下是部分代码的分析

#include“intege使用integer.h的类型定义

#ifndef_FATFS

#define_FATFS0x007版本号007c,0.07c

#define_WORD_ACCESS0如//果定义为1,则可以使用word访问。

中间有一些看着说明很容易弄清楚意思。

这里就不例举了。

#define_CODE_PAGE936

/*The_CODE_PAGEspecifiestheOEMcodepagetobeusedonthetargetsystem.

/936-SimplifiedChineseGBK(DBCS,OEM,WindoW跟据这个中国应该是936.

打开option文件夹看一下。

打开CC936.C文件,里面有一个很大的数组staticconstWCHARuni2oem[。

根据英文说明,这个数组用于unicode码和OEM码之间的相互转换。

接下来又有两个函数ff_convert()和ff_wtoupper()具体执行码型转换和将字符转换为大写。

XX一下:

看OEM码什么意思。

unicode是一种双字节字符编码,无论中文还是英文,或者其他语言统一到

2个字节。

与现有的任何编码(

ASCII,GB等)都不兼容。

WindowsNT(2000的内核即使用该编码,所有数据进入内核前转换成UNICODE退

出内核后在转换成版本相关的编码(通常称为OEM,在简体中文版下即为GB).(XX所得)继续往下阅读。

#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_DF1S0x81#define_DF1E0xFE#defineDS1S0x40#define_DS1E0x7E#defineDS2S0x80#define_DS2E0xFE

小写、数字。

暂时不理会它。

接下来很大一部分都是与语言相关的因素,略过。

#defineIsUpper(c)(((c)>=

'A')&&((c)<=

'Z'))

#defineIsLower(c)(((c)>=

'a')&&((c)<=

'z'))

#defineIsDigit(c)(((c)>=

'0,)&&((c)v二

'9,

/*Charactercodesupportmacros*/三个宏判断是否大写、

))

#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*/XCHA是文件名的码型所用。

#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!

=512

WORDs_size;/*Sectorsize*/

#endif

#if!

FSREADONLY文件为可写

BYTEfsi_flag;/*fsinfodirtyflag(1:

mustbewrittenback)*/

//文件需要回写的标志

DWORDlast_clust;/*Lastallocatedcluster*/

DWORDfree_clust;/*Numberoffreeclusters*/

DWORDfsi_sector;/*fsinfosector*/

#endif

#if_FS_RPATH

DWORDcdir;/*使用相对路径,则要存储文件系统当前目录

#endif

DWORDsects_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_LFN

WCHAR*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;/*Currentcluster*/当前簇

DWORDdsect;/*Currentdatasector*/文件当前扇区

#if!

_FS_READONLY

DWORDdir_sect;/*Sectorcontainingthedirectoryentry*/该文件目录项对应所在的扇区BYTE*dir_ptr;/*Pontertothedirectoryentryinthewindow*/

#endif

#if!

_FS_TINY

BYTEbuf[_MAX_SS];/*FileR/Wbuffer*/文件读写缓冲

#endif

}FIL;

/*Filestatusstructure*/

typedefstruct_FILINFO_{

DWORDfsize;/*Filesize*/

WORDfdate;/*Lastmodifieddate*/

WORDftime;/*Lastmodifiedtime*/

BYTEfattrib;/*Attribute*/

charfname[13];/*Shortfilename(8.3format)*/

#if_USE_LFN

XCHAR*lfname;/*PointertotheLFNbuffer*/

intlfsize;/*SizeofLFNbuffer[chrs]*/

#endif

}FILINFO这个结构主要描述文件的状态信息,包括文件名13个字符

8+.+3+\0)、属性、修改时间等。

接下来是函数的定义,先大概浏览一遍。

FRESULTf_mount(BYTE,FATFS*加儼文件系统,BYTE参数是ID,后一个是文件系统定义。

FRESULTf_open(FIL*,constXCHAR*,BYTE打开文件,第一个参数是文件信

息结构,第二个参数是文件名,第三是文件打开模式

FRESULTf_read(FIL*,void*,UINT,UINT*)文件读取函数,参数1为文件对象(文件打开函数中得到),参数2为文件读取缓冲区,参数3为读取的字节数,参数4意义不清晰,等读到源代码就清楚了。

FRESULTf_write(FIL*,constvoid*,UINT,UINT*);写文件,参数跟读差不多

FRESULTf_lseek(FIL*,DWORD)移动文件的读写指针,参数2应该是移动的数目。

FRESULTf_close(FIL*);/*Closeanopenfileobject*/

FRESULTf_opendir(DIR*,constXCHAF打开目录,返回目录对象

FRESULTf_readdir(DIR*,FILINFO读取目录,获得文件信息

FRESULTf_stat(constXCHAR*,FILINFO*);/*Getfilestatus*/

FRESULTf_getfree(constXCHAR*,DWORD*,FATFS**);/*Getnumberoffreeclustersonthedrive*/

FRESULTf_truncate(FIL*);/*Truncatefile*/

FRESULTf_sync(FIL*);/*Flushcacheddataofawritingfile将*/缓冲区数据写

回文件

FRESULTf_unlink(constXCHAR删除目录中的一个文件

FRESULTf_mkdir(constXCHAR*);/*Createanewdirectory*/

FRESULTf_chmod(constXCHAR*,BYTE,BYTE);/*Changeattriburteofthefile/dir*/

FRESULTf_utime(constXCHAR*,constFILINFO*);/*Changetimestampofthefile/dir*/FRESULTf_rename(constXCHAR*,constXCHAR*);/*Rename/Moveafileordirectory*/FRESULTf_forward(FIL*,UINT(*)(constBYTE*,UINT),UINT,UINT*);/*Forwarddatatothestream*/这个函数还要提供一个回调函数。

FRESULTf_mkfs(BYTE,BYTE,WORD);/*Createafilesystemonthedrive*/

FRESULTf_chdir(constXCHAR*);/*Changecurrentdirectory改*/变当前目录

FRESULTf_chdrive(BYTE);/*Changecurrentdrive*/

应该说基本能明白这些函数用于干什么。

#if_USE_STRFUNC

intf_putc(int,FIL*);/*Putacharactertothefile*/

intf_puts(constchar*,FIL*);/*Putastringtothefile*/

intf—printf(FIL*,constchar*,…);/*Putaformattedstringtothefile*/char*

f_gets(char*,int,FIL*);/*Getastringfromthefile*/

#definef_eof(fp)(((fp)->fptr==(fp)->fsize)?

1:

0)

#definef_error(fp)(((fp)->flag&FA__ERROR)?

1:

0)

#if_FS_REENTRAN■如果定义了重入,则需要实现以下四个函数

BOOLff_cre_syncobj(BYTE,_SYNCJ创建同步对象

BOOLff_del_syncobj(_SYNCJ);除同步对象

BOOLff_req_grant(_SYNC_t);f请同步对象

voidff_rel_grant(_SYNC_t)释放同步对象。

#endif

3、diskio.h文件

typedefBYTEDSTATUS;

typedefDRESULT;/首先定义了两个变量,各个函数都有用至叽

BOOLassign_drives(intargc,char*argv[]);/这/个函数不知道干吗

DSTATUSdisk_initialize(BYTE);磁盘初始化

DSTATUSdisk_status(BYTE)获取磁盘状态

DRESULTdisk_read(BYTE,BYTE*,DWORD,BYTE);

#if_READONLY==0

DRESULTdisk_write(BYTE,constBYTE*,DWORD,BYTE);

#endif

DRESULTdisk_ioctl(BYTE,BYTE,void*磁盘控制

接下来还有一些常数的定义,具体用到时在看。

4、diskio.c的结构

DSTATUSdisk_initialize(BYTEdrv/*Physicaldrivenmuber(0..)*/)

DSTATUSstat;

intresult;

switch(drv){

caseATA:

result=ATA_disk_initialize();

//translatethereslutcodehere

returnstat;

caseMMC:

result=MMC_disk_initialize();

//translatethereslutcodehere

returnstat;

caseUSB:

result=USB_disk_initialize();

//translatethereslutcodehere

returnstat;

returnSTA_NOINIT;

函数基本都像这样,drv表示磁盘的类型。

没有实现,用户必须实现这部分

代码。

5、ff.e文件简单浏览

#inelude“ff.h”/*FatFseonfigurationsandtdioenesla*r/a

#inelude“diskio.h”/*DeelarationsoflowleveldiskI/Ofunetions*/

#defineENTER_FF(fs){if(!

loek_fs(fs))returnFR_TIMEOUT;}获//取文件系统同步对象,不成功返回超时,成功,继续执行。

#defineLEAVE_FF(fs,res){unloek_fs(fs,res);returnres;}释//放文件系统同步对象。

StaticFATFS*FatFs[_DRIVES]定义一个文件系统对象指针数组,当然一般我们也就用到一个元素。

StatieWORDLfnBuf[_MAX_LFN+1];/这/个是与长文件名支持相关的。

#defineNAMEBUF(sp,lp)BYTEsp[12];WCHAR

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

当前位置:首页 > 党团工作 > 党团建设

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

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