STM32stm32+sdio+fatfs文件系统源码分析文档格式.docx
《STM32stm32+sdio+fatfs文件系统源码分析文档格式.docx》由会员分享,可在线阅读,更多相关《STM32stm32+sdio+fatfs文件系统源码分析文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
CHAR;
/*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.
OEMcodepage什么意思不大明白。
/
936
-SimplifiedChineseGBK(DBCS,OEM,Windows)跟据这个中国应该是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_TIMEOUT
1000/*TimeoutperiodinunitoftimeticksoftheOS*/
#define_SYNC_t
HANDLE/*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
#define_DS1S0x40
#define_DS1E0x7E
#define_DS2S0x80
#define_DS2E0xFE
接下来很大一部分都是与语言相关的因素,略过。
/*Charactercodesupportmacros*/三个宏判断是否大写、小写、数字。
#defineIsUpper(c)(((c)>
='
A'
)&
&
((c)<
Z'
))
#defineIsLower(c)(((c)>
a'
z'
#defineIsDigit(c)(((c)>
0'
9'
#if_DF1S
/*DBCSconfiguration*/双字节编码相关的设定,暂时不理会它。
#if_MULTI_PARTITION
/*Multiplepartitionconfiguration*/
//该变量定义为1时,支持一个磁盘的多个分区。
typedefstruct_PARTITION{
BYTEpd;
/*Physicaldrive#*/
BYTEpt;
/*Partition#(0-3)*/
}PARTITION;
Extern
const
PARTITIONDrives[];
//如果支持分区,则声明变量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字节。
#define
SS(fs)
512U
#if_LFN_UNICODE&
_USE_LFN
typedefWCHARXCHAR;
/*Unicode*/XCHAR是文件名的码型所用。
#else
typedefcharXCHAR;
/*SBCS,DBCS*/
#endif
typedefstruct_FATFS_{
BYTE
fs_type;
/*FATsubtype*/
drive;
/*对应实际驱动号01---*/
csize;
/*每个簇的扇区数目*/
先查一下簇的含义:
应该是文件数据分配的基本单位。
n_fats;
/*文件分配表的数目*/
FAT文件系统依次应该是:
引导扇区、文件分配表两个、根目录区和数据区。
wflag;
/*win[]dirtyflag(1:
mustbewrittenback)*/
//文件是否改动的标志,为1时要回写。
WORD
id;
/*FilesystemmountID文件系统加载ID*/
n_rootdir;
/*根目录区目录项的数目*/
#if_FS_REENTRANT
_SYNC_t
sobj;
/*允许重入,则定义同步对象*/
#if_MAX_SS!
=512
s_size;
/*Sectorsize*/
#if!
_FS_READONLY
//文件为可写
fsi_flag;
/*fsinfodirtyflag(1:
//文件需要回写的标志
DWORD
last_clust;
/*Lastallocatedcluster*/
free_clust;
/*Numberoffreeclusters*/
fsi_sector;
/*fsinfosector*/
#if_FS_RPATH
cdir;
/*使用相对路径,则要存储文件系统当前目录
sects_fat;
/*文件分配表占用的扇区
max_clust;
/*最大簇数
fatbase;
/*文件分配表开始扇区
dirbase;
/*
如果是FAT32,根目录开始扇区需要首先得到。
database;
/*数据区开始扇区
winsect;
/*Currentsectorappearinginthewin[]*/
//目前的扇区在win[]里面,这个win[]数组暂时还不知道含义。
win[_MAX_SS];
/*DiskaccesswindowforDirectory/FAT*/
//这是一个win[512]数组,存储着一个扇区,好像作为扇区缓冲使用。
}FATFS;
typedefstruct_DIR_{
FATFS*fs;
/*Pointertotheownerfilesystemobject*/指向相应文件系统对象。
/*文件系统加载ID*/
index;
/*Currentread/writeindexnumber*/目前读写索引代码
sclust;
/*Tablestartcluster(0:
Statictable)*/文件数据区开始簇
clust;
/*Currentcluster*/目前处理的簇
sect;
/*Currentsector*/目前簇里对应的扇区
BYTE*
dir;
/*PointertothecurrentSFNentryinthewin[]*/
fn;
/*PointertotheSFN(in/out){file[8],ext[3],status[1]}*/
#if_USE_LFN
WCHAR*
lfn;
/*PointertotheLFNworkingbuffer*/指向长文件名缓冲。
lfn_idx;
/*LastmatchedLFNindexnumber(0xFFFF:
NoLFN)*/
}DIR;
typedefstruct_FIL_{
/*Pointertotheownerfilesystemobject*/
/*OwnerfilesystemmountID*/
flag;
/*Filestatusflags*/文件状态标志
csect;
/*Sectoraddressinthecluster*/扇区偏移
fptr;
/*FileR/Wpointer*/读写指针
fsize;
/*Filesize*/
org_clust;
/*Filestartcluster*/文件开始簇
curr_clust;
/*Currentcluster*/当前簇
dsect;
/*Currentdatasector*/文件当前扇区
_FS_READONLY
dir_sect;
/*Sectorcontainingthedirectoryentry*/该文件目录项对应所在的扇区
dir_ptr;
/*Pontertothedirectoryentryinthewindow*/
_FS_TINY
buf[_MAX_SS];
/*FileR/Wbuffer*/文件读写缓冲
}FIL;
/*Filestatusstructure*/
typedefstruct_FILINFO_{
fdate;
/*Lastmodifieddate*/
ftime;
/*Lastmodifiedtime*/
fattrib;
/*Attribute*/
charfname[13];
/*Shortfilename(8.3format)*/
XCHAR*
lfname;
/*PointertotheLFNbuffer*/
int
lfsize;
/*SizeofLFNbuffer[chrs]*/
}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*,constXCHAR*);
打开目录,返回目录对象
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*);
删除目录中的一个文件
FRESULT
f_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)?
#if_FS_REENTRANT
//如果定义了重入,则需要实现以下四个函数
BOOLff_cre_syncobj(BYTE,_SYNC