FATFS文件管理系统
一、FATFS简介
FATFS 是一个完全免费开源的 FAT 文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准 C 语言编写,所以具有良好的硬件平立性,可以移植到 8051、 PIC、 AVR、 SH、Z80、 H8、 ARM 等系列单片机上而只需做简单的修改。它支持 FATl2、 FATl6 和 FAT32,支持多个存储媒介;有的缓冲区,可以对多个文件进行读/写,并特别对 8 位单片机和 16 位单片机做了优化。
FATFS 的特点有:
代码量少、效率高
多种配置选项
支持多卷(物理驱动器或分区,最多 10 个卷)
多个 ANSI/OEM 代码页包括 DBCS
支持长文件名、 ANSI/OEM 或 Unicode
支持 RTOS
支持多种扇区大小
只读、最小化的 API 和 I/O 缓冲区等
二、FATFS层次结构图
最顶层是应用层,使用者无需理会 FATFS 的内部结构和复杂的 FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如 f_open, f_read, f_write 和 f_close 等,就可以像在 PC 上读/写文件那样简单。中间层 FATFS 模块, 实现了 FAT 文件读/写协议。 FATFS 模块提供的是 ff.c 和 ff.h。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。需要我们编写移植代码的是 FATFS 模块提供的底层接口,它包括存储媒介读/写接口(disk I/O) 和供给文件创建修改时间的实时时钟。
三、FATFS源码
1.源码下载
(1)在http://elm-chan.org/fsw/ff/00index_e.html下载FatFs源码R0.10b版本;
(2)打开压缩包,里面有doc和src两个文件夹,doc是对FatFs的一些介绍及更新说明,src为FatFs的源码;
2.FatFs源码介绍
(1)与硬件平台无关的文件
✧ffconf.h FATFS 模块配置文件
✧ff.h FATFS 和应用模块公用的包含文件
✧ff.c FATFS 模块
✧diskio.h FATFS 和 disk I/O 模块公用的包含文件
✧interger.h 数据类型定义
✧option 可选的外部功能(比如支持中文等)
(2) 与硬件平台相关的文件
✧diskio.c FATFS 和 disk I/O 模块接口层文件
(3) 移植时,重要的选项配置
✧_FS_TINY。这个选项在 R0.07 版本中开始出现,之前的版本都是以的 C 文件出现( FATFS 和 Tiny FATFS),有了这个选项之后,两者整合在一起了,使用起来更方便。我们使用 FATFS,所以把这个选项定义为 0 即可。
✧_FS_READONLY。这个用来配置是不是只读,本章我们需要读写都用,所以这里设置为 0 即可。
✧_USE_STRFUNC。这个用来设置是否支持字符串类操作,比如 f_putc, f_puts 等,本章我们需要用到,故设置这里为 1。
✧_USE_MKFS。这个用来定时是否使能格式化,本章需要用到,所以设置这里为 1。
✧_USE_FASTSEEK。这个用来使能快速定位,我们设置为 1,使能快速定位。
✧_USE_LABEL。这个用来设置是否支持磁盘盘符(磁盘名字)读取与设置。我们设置为 1,使能,就可以通过相关函数读取或者设置磁盘的名字了。
✧_CODE_PAGE。这个用于设置语言类型, 包括很多选项(见 FATFS 官网说明),我们这里设置为 936,即简体中文( GBK 码,需要 c936.c 文件支持,该文件在 option 文件夹)。
✧_USE_LFN。该选项用于设置是否支持长文件名(还需要_CODE_PAGE 支持),取值范围为 0~3。 0,表示不支持长文件名, 1~3 是支持长文件名,但是存储地方不一样,我们选择使用 3,通过 ff_memalloc 函数来动态分配长文件名的存储区域。
✧_VOLUMES。用于设置 FATFS 支持的逻辑设备数目,我们设置为 2,即支持 2 个设备。
✧_MAX_SS。扇区缓冲的最大值,一般设置为 512。
四、FATFS源码移植步骤
1.数据类型
在integer.h文件中配置数据类型,根据编译器类型配置,如VC中int2字节,在KeilMDK中int占4字节。Integer.h中的数据类型与MDK中相同,所见就不需要进行配置
2.配置FatFs
在ffconf.h中配置上面介绍的重要的选项配置和其他配置,重要的配置按照上面介绍的配置就可以了,其他配置保持默认;
3.函数编写
在diskio中编写底层驱动函数
∙disk_initialize - Initialize disk drive
∙disk_status - Get disk status
∙disk_read - Read sector(s)
∙disk_write - Write sector(s)
∙disk_ioctl - Control device dependent features
∙get_fattime - Get current time
首先需要定义存储器的号码,我们定义SD卡为0 SPI FLASH为1,还需根据不同存储器的类型来定义存储的sector和block,下面介绍必须的六种底层驱动函数
(1)disk_initialize
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber (0..) */
){
u8 res=0;
switch(pdrv)
{
case SD_CARD: res=SD_Init();//SD 卡初始化
break;
case EX_FLASH: //外部 flash
W25QXX_Init();
FLASH_SECTOR_COUNT=2048*12;
break;
default:
res=1;
}
if(res) return STA_NOINIT;
else return 0; //初始化成功
}
对SD卡和SPI FLASH存储进行初始化
(2)
disk_status
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber (0..) */
)
{
return 0;
}
返回0即可,用不到
(3)disk_read
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
UINT count /* Number of sectors to read (1..128) */
){
u8 res=0;
if (!count)return RES_PARERR;//count 不能等于 0,否则返回参数错误
switch(pdrv)
{
case SD_CARD: //SD 卡
res=SD_ReadDisk(buff,sector,count);
break;
case EX_FLASH: //外部 flash
for(;count>0;count--)
{
W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
if(res==0x00) return RES_OK;
else return RES_ERROR;
}
根据存储器类型,调用存储器相关的读取程序
(4)
disk_write
#if _USE_WRITE
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
UINT count /* Number of sectors to write (1..128) */
)
{
u8 res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
case SD_CARD://SD卡
res=SD_WriteDisk((u8*)buff,sector,count);
while(res)//写出错
{
SD_Init(); //重新初始化SD卡
res=SD_WriteDisk((u8*)buff,sector,count);
//printf("sd wr error:%d\\r\\n",res);
}
break;
case EX_FLASH://外部flash
for(;count>0;count--)
{
W25QXX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res == 0x00)return RES_OK;
else return RES_ERROR;
}
#endif
同disk_read函数相同,调用各存储器写入函数进行读写,API接口
(5)disk_ioctl
//其他表参数的获得
//drv:磁盘编号0~9
//ctrl:控制代码
//*buff:发送/接收缓冲区指针
#if _USE_IOCTL
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
if(pdrv==SD_CARD)//SD卡
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(DWORD*)buff = 512;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = SDCardInfo.CardBlockSize;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = SDCardInfo.CardCapacity/512;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}else if(pdrv==EX_FLASH) //外部FLASH
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = FLASH_SECTOR_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = FLASH_BLOCK_SIZE;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = FLASH_SECTOR_COUNT;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}else res=RES_ERROR;//其他的不支持
return res;
}
#endif
获得存储器信息,存储容量,sector block等
(6)get_fattime函数
没有用到,返回0即可
(7)memalloc 和memfree函数等在长文件名功能时会应用
五、FATFS主要API函数及类型结构体和全局变量的介绍
1.结构体
(1)FATFS结构体
FATFS 结构(文件系统对象)用来保存逻辑驱动器动态工作区域。这个结构由应用程序给定,使用 f_mount 函数注册/注销 FATFS 模块。 在执行 f_mount 或媒体发生变化后,访问第一个文件时 FATFS 被初始化。 其他应用程序不能改变结构的任何成员变量。
typedef struct {
BYTE fs_type; /* FAT sub-type (0:Not mounted) 0表示为挂载*/
BYTE drv; /* Physical drive number */ 物理地址 SD:0 FLASH1
BYTE csize; /* Sectors per cluster (1,2,4...128) */一个簇有多少扇区
BYTE n_fats; /* Number of FAT copies (1 or 2) */文件分配表数目
BYTE wflag; /* win[] flag (b0:dirty) */标记文件是否改写过
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */标记文件系统信
息是否改动过
WORD id; /* File system mount ID */文件系统挂载的ID
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */根目录
区入口,用于FAT12/16,
#if _MAX_SS != _MIN_SS 如果在ffconf中定义的不相等,定义的是一个
范围,在这里配置设置存储器sector大小
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
#endif
#if _FS_REENTRANT 如果可重入,定义同步对象
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY 如果为可读写
DWORD last_clust; /* Last allocated cluster */上一个被分配的簇
DWORD free_clust; /* Number of free clusters */空闲簇
#endif
#if _FS_RPATH 允许相对目录使使用,存储当前目录起始簇
DWORD cdir; /* Current directory start cluster (0:root) */
#endif
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */ FAT条目数量,等于簇+2
DWORD fsize; /* Sectors per FAT */每个FAT扇区数量
DWORD volbase; /* Volume start sector */卷起始扇区???
DWORD fatbase; /* FAT start sector */FAT起始扇区
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
根目录起始扇区
DWORD database; /* Data start sector */数据起始扇区
DWORD winsect; /* Current sector appearing in the win[] */当前缓冲区
存储的扇区号
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */单个扇区缓存
} FATFS;
(2)FIL结构体
FIL 结构(文件对象)用来保存打开文件的状态。它由 f_open 函数创建,由f_close函数废弃。除 cltbl 外,其成员不能被其他应用程序改变。注意:在 non-tiny 配置情况下,在结构体中定义了一个扇区缓冲区,因此 FIL 结构不能够被定义为自动变量。
typedef struct {
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */ 指向相关文件系统的指针
WORD id; /* Owner file system mount ID (**do not change order**) */所在文件系统的挂在编号,SD:0 FLASH:1
BYTE flag; /* Status flags */ 状态标志
BYTE err; /* Abort flag (error code) */错误标志
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
文件读写指针,打开文件时清零
DWORD fsize; /* File size */ 文件大小
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */ 文件起始簇
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */ fpter指向的文件所在的当前簇
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY 当前数据扇区
DWORD dir_sect; /* Sector number containing the directory entry */
含有目录的扇区数量
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
目录入口指针,(目录应该缓存在win[]中,猜测)
#endif
#if _USE_FASTSEEK 指向簇链接映射表的指针
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
#endif
#if _FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
#if !_FS_TINY 数据读写缓冲
BYTE buf[_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
(3)DIR 目录结构体
DIR 结构体被 f_opendir, f_readdir 函数用来读取工作区目录。其他应用程序不能改变其成员变量。
typedef struct {
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */ 文件系统指针
WORD id; /* Owner file system mount ID (**do not change order**) */ 文件系统挂在编号SD:0 FALSH:1
WORD index; /* Current read/write index number */
当前读写目录索引号
DWORD sclust; /* Table start cluster (0:Root dir) */
根目录表起始簇
DWORD clust; /* Current cluster */
当前簇,当前扇区
DWORD sect; /* Current sector */
当前短文件入口指针
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */文件指针 SFN short file name
#if _FS_LOCK
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
#endif
#if _USE_LFN 指向长文件名的指针缓冲
WCHAR* lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif 最后匹配的长文件名索引号
} DIR;
(4)FILINFO 文件Information结构体,存储文件的信息
typedef struct {
DWORD fsize; /* File size */ 文件大小
WORD fdate; /* Last modified date */最后更改日期
WORD ftime; /* Last modified time */最后更改时间
BYTE fattrib; /* Attribute */属性
TCHAR fname[13]; /* Short file name (8.3 format) */短文件名
#if _USE_LFN 指向长文件名的指针
TCHAR* lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
长文件名缓冲区大小
#endif
} FILINFO;
(5) FRESULT 配置状态结构体
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
2.FATFS文件系统API函数介绍
(1) f_mount
f_mount 函数,主要用来在 FatFS 模块中注册/注销工作区。
FRESULT f_mount(
BYTE Drive, /*逻辑驱动器号*/
FATFS* FileSystemObject /*工作区域指针*/
);
参数说明
Drive 注册/注销工作区域的逻辑驱动器号( 0~9)
FileSystemObject 被注册的工作区域(文件系统目标)指针。
函数返回值
FR_OK (0) 函数执行成功
FR_INVALID_DRIVE 指定的驱动器号非法
函数描述
f_mount 函数在 FatFS 模块中注册/注销一个工作区。在使用其他文件函数前工作区必须先使用这个函数给定每个卷。指定一个 NULL 到 FileSystemObject,注销一个工作区,然后工作区将被废弃。不管驱动器处于何种状态,此函数总是返回成功 。在此函数中不发生媒体访问。它只初始化给定的工作区域并且注册其地址到内部表。在 f_mount 函数执行或者媒体改变后,在第一次文件访问时执行卷安装过程。
(2) f_open()函数
创建一个将要访问的文件对象(参数可选打开文件)
FRESULT f_open (
FIL* FileObject, /* 空目标文件结构体指针*/
const TCHAR* FileName, /* 文件名指针 */
BYTE ModeFlags /* 文件打开模式标志 */
);
参数说明
FileObject 要创建的目标文件结构体指针。
FileName 指定创建或打开以空终止的字符串文件名指针
ModeFlags 指定访问或打开文件的模式类型。可以是以下标志的组合。
值 | 描述 |
FA_READ | 指定读访问对象。可以从文件读取数据。与 FA_WRITE 组合为读写访问。 |
FA_WRITE | 指定写访问对象。可以向文件写入数据。与 FA_READ组合为读写访问。 |
FA_OPEN_EXISTING | 打开文件。如果文件不存在,函数返回失败。(默认模式) |
FA_OPEN_ALWAYS | 如果存在打开文件。如果文件不存在,创建一个新文件。在使用此模式打开文件后,使用 f_lseek 函数,追加数据到文件。 |
FA_CREATE_NEW | 创建一个新文件。如果文件存在,函数执行失败,并返回FR_EXIST 值。 |
FA_CREATE_ALWAYS | 创建一个新文件。如果文件存在,将被删节和复写。 |
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH,FR_INVALID_NAME,FR_DENIED,FR_EXIST,FR_WRITE_PROTECTED,FR_INVALID_DRIVE,FR_NOT_ENABLED,FR_NO_FILESYSTEM,FR_TIMEOUT,FR_LOCKED,FR_NOT_ENOUGH_CORE,FR_TOO_MANY_OPEN_FILES
函数描述
在 f_open 函数执行成功后,文件对象开始有效。文件对象用于随后指定文件的读写函数。使用 f_close 函数来关闭打开的文件对象。如果更改的文件未被关闭,文件数据可能崩溃。在使用任何文件函数前,必须使用 f_mount 函数在逻辑驱动器上注册一个工作区(文件系统对象)。除 f_fdisk 函数外,所有的 API 函数需在完成此过程后工作。注意, 当_FS_READONLY == 1 时,模式标志FA_WRITE,FA_CREATE_ALWAYS,
FA_CREATE_NEW 和FA_OPEN_ALWAYS 不可用。
(3) f_close()函数
f_close 函数,此函数的功能是关闭一个打开的文件。
FRESULT f_close (
FIL* FileObject, /* 文件对象结构体指针*/
);
参数说明
FileObject 将要关闭的已打开文件指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT,
FR_TIMEOUT
函数描述
f_close 函数关闭一个打开的文件对象。如果有任何数据写入到了文件,文件的缓冲区信息被写回到磁盘。在 f_close 函数执行成功后,文件对象不再有效,并被丢弃。
(4) f_read()函数
FRESULT f_read (
FIL* FileObject, /*文件对象结构体指针*/
void* Buffer, /* 读取数据缓冲区指针 */
UINT ByteToRead, /* 读字节数 */
UINT* ByteRead /*读字节数变量指针 */
);
参数说明
FileObject 打开的文件对象指针
Buffer 存储读取数据缓冲区指针
ByteToRead 在 UINT 范围内,读取的字节数
ByteRead 返回读取字节数的无符号整型变量指针。这个值在函数调用后
有效,与函数执行结果无关。
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT,
FR_TIMEOUT
函数描述
文件对象的文件指针随着读取字节数的增加而增加。在函数执行成功后, *ByteRead应该是否检测到了文件结尾。 在*ByteRead < ByteToRead 情况下,意味着在读操作期间,读写指针到达了文件尾。
(5) f_write()函数
FRESULT f_write (
FIL* FileObject, /*文件对象结构体指针*/
const void* Buffer, /*写入数据缓冲区指针*/
UINT ByteToWrite, /* 写字节数 */
UINT* ByteWritten /*写字节数变量指针*/
);
参数说明
FileObject 打开的文件对象指针
Buffer 存储写入数据缓冲区指针
ByteToWrite 在 UINT 范围内, 写入的字节数
ByteWrite 返回写入字节数的无符号整型变量指针。这个值在函数调用后
有效,与函数执行结果无关。
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT,
FR_TIMEOUT
函数描述
文件对象的文件指针随着写入字节数的增加而增加。在函数执行成功后,
*ByteWrite 应该是否检测到了文件结尾。 当*ByteWrite < ByteToWrite 时,意味着在写操作期间卷满了。 当卷满或接近满时,函数可能会花费一些时间。
当_FS_READONLY == 0 时此函数可用。
(6) f_lseek函数
f_lseek 函数:移动指针
FRESULT f_lseek (
FIL* FileObject, /*文件对象结构体指针*/
DWORD Offset /* 文件偏移量(单位:字节)*/
);
参数说明
FileObject 打开的文件对象指针
Offset 相对文件开头的字节数
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT,
FR_TIMEOUT
函数描述
f_lseek 函数功能是移动一个打开文件的文件读写指针。偏移量可以被设定为唯一源自文件顶部。当一个超过文件大小的偏移量在写模式下被设置时,文件大小增加到偏移量大小但在扩展区域中的数据是不确定的。这适合快速创建一个大文件,快速的写文件。在 f_lseek 函数成功执行后,应该检查文件对象结构体成员变量 fptr,以确定读写指针是否被正确地移动。在 fptr 不是预期值的情况下,可能发生以下两种情况。. 文件结束。 指定的偏移量被到文件大小,因为该文件已在只读模式打开。. 磁盘满。卷上没有足够的空余空间来扩展文件大小。
当_USE_FASTSEEK 置 1 时使能快速搜索模式,并且文件对象结构体中成员 cltbl不为 NULL。此功能通过访问存储在用户定义表中的簇链接映射表(CLMT)实现了无文件分区表(FAT)快速后退/长搜索操作。 它也适用于 f_read/ f_write 函数。在此模式下,文件大小不能被 f_write/f_lseek 函数增加。在使用快速搜索功能前, CLMT 必须事先创建在用户定义的 DWORD 数组中。创建 CLMT,设置文件对象结构成员 cltbl 指向 DWORD 数组指针,在数组第一个条目中设置以条目 为单位的数组大小,并以参数 Offset = CREATE_LINKMAP 调用 f_lseek函数。 在函数成功执行后 CLMT 被创建,随后的 f_read/f_write/f_lseek 函数访问文件无需文件分区表。 如果函数执行失败返回 FR_NOT_ENOUGH_CORE,表明给定的数组大小不足以容下该文件,并且将需要的条目数返回到数组的第一个条目中。 需要的数组大小是(number of fragments + 1) * 2 条。例如,当文件分为 5 个片段时,CLMT 需要 12 个条目。此函数当_FS_MINIMIZE <= 2 时可用。
(7) f_truncate 函数
FRESULT f_truncate (
FIL* FileObject /*文件对象结构体指针*/
);
参数说明
FileObject 被截断的文件对象指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT,
FR_TIMEOUT
函数描述
f_truncate 函数截短文件大小到当前文件读写点处。如果文件读写点已经到达
文件结尾对此函数没有影响。
当_FS_READONLY == 0 and _FS_MINIMIZE == 0 时,此函数可用。
(8) f_sync 函数
FRESULT f_sync (
FIL* FileObject /*文件对象结构体指针 t */
);
参数说明
FileObject 被清除的文件对象指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT,
FR_TIMEOUT
函数描述
f_sync 函数执行了与 f_close 函数相同的过程,但其运行后保持文件打开状态,仍可以继续对文件进行读、写、搜索等操作。 这样比较适合长时间写模式打开文件的应用,例如数据日志记录应用。 在执行 f_sync 函数期间或者在 f_write 函数执行后立即运行 f_sync 函数可以把由于突然断电或者磁盘的意外移除造成数据丢失的风险降到最低。然而,由于在 f_close 函数执行中已经执行了 f_sync 相同的功能,所以在 f_close 函数之前执行 f_sync 函数没有任何优点。换言之,这两个函数之间的区别是文件对象是否失效。当_FS_READONLY == 0 时此函数可用。
(9) f_opendir 函数:打开目录、创建目录
FRESULT f_opendir (
DIR* DirObject, /* 目录对象结构体指针 */
const TCHAR* DirName /* 目录名指针 */
);
参数说明
DirObject 目录对象结构体指针
DirName 以空终止的字符串表示的要打开的目录名指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_PATH,
FR_INVALID_NAME, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM,
FR_TIMEOUT, FR_NOT_ENOUGH_CORE
函数描述
此函数打开一个已经存在目录并且为随后的调用创建一个目录对象。 目录对象结构体可以随时无任何手续被丢弃。当_FS_MINIMIZE <= 1 时,此函数可用
(10) f_readdir 函数
FRESULT f_readdir (
DIR* DirObject, /*目录对象结构体指针*/ (已打开)
FILINFO* FileInfo /*文件信息结构体指针 */(已存储)
);
参数说明
DirObject 打开的目录对象结构体指针
FileInfo 存储在读条目中的文件信息结构指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT,
FR_TIMEOUT, FR_NOT_ENOUGH_CORE
函数描述
f_readdir 函数按顺序读取目录条目 。反复调用 f_readdir 函数可以读取目录的所有条目。当已读完所有的目录条目 并且没有其他条目可读时,函数返回一个空字符串到成员变量 f_name[]中,并且不返回错误提示。 当 FileInfo 指向一个空指针,读取的目录对象将被倒回。当 LFN 被打开时,文件信息结构体中的 lfname 和 lfsize 必须在使用 f_readdir函数前初始化为有效值。 lfname 是一个返回长文件名的字符串缓冲区指针。 lfsize表示以 TCHAR 为单位的字符串缓冲区的大小。如果读缓冲区或 LFN 工作缓冲区容量不够存储 LFN 或者对象没有 LFN,将返回一个空字符串到 LFN 读缓冲区。 在没有对 Unicode API 配置的情况下, 如果LFN 包含任何不能转换成 OEM 码的字符, 将返回一个空字符串。 当 lfname 是NULL 时, LFN 没有任何返回。当对象没有 LFN 时,一些小写字母被包含到 SFN中。当相关的路径特征被使能( _FS_RPATH == 1) ,”.”和”..”不被过滤并且将出现在所读条目中。当_FS_MINIMIZE <= 1 时,此函数可用
(11) f_getfree 函数:获取驱动器(如,SD卡)的空白鏃数量
FRESULT f_getfree (
const TCHAR* Path, /* 逻辑驱动器号 */
DWORD* Clusters, /* 存储空白簇变量指针*/
FATFS** FileSystemObject /* 指向文件系统对象指针的指针*/
);
参数说明
Path 以空字符终止的字符串表示的逻辑驱动器指针
Clusters 存储空闲簇数量的 DWORD 类型变量指针
FileSystemObject 存储相应文件系统对象指针的指针
函数返回值
FR_OK,FR_DISK_ERR,FR_INT_ERR,FR_NOT_READY,FR_INVALID_OBJECT,FR_NOT_
ENABLED,FR_NO_FILESYSTEM, FR_TIMEOUT
函数描述
f_getfree 函数获取驱动器的空白簇数量。 FileSystemObject->csize 反映了每簇的扇区数量,因此以扇区为单位的空闲空间可以用这个成员来计算。 当 FSInfo 结构体与 FAT32 卷不同步, 函数返回的空闲簇数量可能不正确。当_FS_READONLY == 0 and _FS_MINIMIZE == 0 时,此函数可用。
(12) f_stat 函数
FRESULT f_stat (
const TCHAR* FileName, /* 文件或目录指针*/
FILINFO* FileInfo /* FILINFO 结构指针*/
);
参数说明
FileName 要获取信息的以空字符终止的字符串表示的文件或文件目录指针
FileInfo 存储信息的空 FILINFO 结构体指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH,
FR_INVALID_NAME, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM,
FR_TIMEOUT, FR_NOT_ENOUGH_CORE
函数描述
f_stat 函数用来获取文件或目录信息。对于更详细的信息,请参考 FILINFO 结
构体和 f_readdir 函数。 这个函数不支持最小化水平的> = 1。
(13) f_mkdir 函数
FRESULT f_mkdir (
const TCHAR* DirName /* 目录名指针 */
);
参数说明
DirName 以空字符结束的字符串表示的要创建的目录名指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_PATH, FR_INVALID_NAME,
FR_DENIED, FR_EXIST, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED,
FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE
函数描述
F_mkdir 函数用来创建一个文件夹或目录。
(14) f_unlink 函数
FRESULT f_unlink (
const TCHAR* FileName /*文件名指针 */
);
参数说明
FileName 以空字符终止的字符串表示的被移除对象名指针。
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH,
FR_INVALID_NAME, FR_DENIED, FR_EXIST, FR_WRITE_PROTECTED, FR_INVALID_DRIVE,FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_LOCKED,FR_NOT_ENOUGH_CORE
函数描述
如果移除对象的条件满足下列条款,函数将运行失败并返回错误。
. 对象必须没有只读属性( AM_RDO)否则函数将被拒绝并返回 FR_DENIED.
. 文件夹必须是空的并且不是当前文件夹否则函数将被拒绝并返回 FR_DENIED.
. 文件必须不是正被打开的文件否则 FAT 卷可能崩溃。当文件共享控制被打开, 函数可能会被拒绝并返回 FR_LOCKED.当_FS_READONLY == 0 and _FS_MINIMIZE == 0 时,此函数可用。
(15) f_chmod 函数:改变文件或文件夹的属性
FRESULT f_chmod (
const TCHAR* FileName, /* 文件或文件夹指针 */
BYTE Attribute, /* 属性标识 */
BYTE AttributeMask /* 属性掩码*/
);
参数说明
FileName 以空字符串终止的字符串表示的文件或文件夹指针。
Attribute 设置的属性下列标志的一个或多个组合。设置或者清除指定的属性。
属性 描述
AM_RDO 只读
AM_ARC 档案
AM_SYS 系统
AM_HID 隐藏
AttributeMask 属性掩码指定哪个属性被改变。指定的属性被设置或清除。
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH,
FR_INVALID_NAME, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED,
FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE
函数描述
f_chmod 函数用来改变文件或文件夹的属性 。
当_FS_READONLY == 0 and _FS_MINIMIZE == 0 时,此函数可用。
(16) f_utime 函数
FRESULT f_utime (
const TCHAR* FileName, /* 文件或文件夹路径指针 */
const FILINFO* TimeDate /* 设置的时间和日期*/
);
参数说明
FileName 以空字符串终止的字符串表示的文件或文件夹指针。
TimeDate 已有时间戳的文件信息结构体被设置成 fdate 和 ftime 指针。不用关心其他成员。
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH,
FR_INVALID_NAME, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED,
FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE
函数描述
f_utime 函数用来改变文件或者文件夹的时间戳。
当_FS_READONLY == 0 and _FS_MINIMIZE == 0 时,此函数可用。
(17) f_rename 函数
FRESULT f_rename (
const TCHAR* OldName, /*旧对象名指针 */
const TCHAR* NewName /* 新对象名指针*/
);
参数说明
OldName 以空字符串终止的字符串表示的改名旧对象指针。
NewName 以空字符串终止的字符串表示的改名新对象指针。
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH,
FR_INVALID_NAME, FR_DENIED, FR_EXIST, FR_WRITE_PROTECTED, FR_INVALID_DRIVE,FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_LOCKED,FR_NOT_ENOUGH_CORE
函数描述
重命名一个文件或文件夹并且可以移动它到其他文件夹。逻辑驱动器号由老名
字决定,新名字不必包含逻辑驱动器号。不要重命名正打开的对象。
当_FS_READONLY == 0 and _FS_MINIMIZE == 0 时,此函数可用。
(18) f_chdir 函数
FRESULT f_chdir (
const TCHAR* Path /* 路径名指针 */
);
参数说明
Path 以空字符串终止的字符串表示的欲去的目录指针。
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_PATH, FR_INVALID_NAME,
FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT,
FR_NOT_ENOUGH_CORE
函数描述
f_chdir 函数改变逻辑驱动器的当前目录。当驱动器自动安装时驱动器的当前目
录被初始化到根目录。 注意,当前目录被保留在每个文件系统对象中,它也会影响使用驱动器的其他任务。当_FS_RPATH >= 1 时,函数可用。
(19) f_chdrive 函数
FRESULT f_chdrive (
BYTE Drive /* 逻辑驱动器号 */
);
参数说明
Drive 指定作为当前驱动器的逻辑驱动器号。
函数返回值
FR_OK, FR_INVALID_DRIVE
函数描述
f_chdrive 函数用来改变当前驱动器。当前驱动器号的初始值为 0.注意,当前驱
动器保存在一个静态变量中,这会影响使用文件函数的其他任务。
当_FS_RPATH >= 1 时,函数可用。
.没有懂怎么用
(20) f_getcwd 函数
FRESULT f_getcwd (
TCHAR* Buffer, /* 缓冲区指针 */
UINT BufferLen /* 缓冲区长度 */
);
参数说明
Buffer 接收当前目录字符串缓冲区指针。
BufferLen 以 TCHAR 为单位的缓冲区大小
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NOT_ENABLED,
FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE
函数描述
f_getcwd 函数以全路径字符串检索当前驱动器的目录,包括驱动器号。
当_FS_RPATH == 2 时,函数可用。.
(21) f_forward 函数
FRESULT f_forward (
FIL* FileObject, /* 文件对象指针 */
UINT (*Func)(const BYTE*,UINT), /* 数据流函数 */
UINT ByteToFwd, /* 向前的字节数 */
UINT* ByteFwd /* 向前的字节号指针 */
);
参数说明
FileObject 文件对象指针
Func 用户数据流函数指针
ByteToFwd 在 UINT 范围内向前的字节数
ByteFwd 返回向前字节数 UINT 变量指针
函数返回值
FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT, FR_TIMEOUT
函数描述
f_forward 函数从文件读取数据并转发到无数据缓冲区输出流。由于不需要任何应用模块数据缓冲区,这比较适合小内存系统。文件对象的文件指针随着向前的字节数增加。在*ByteFwd < ByteToFwd 的情况下不会报错,这意味着请求的字节数不能被传输,这是因为到达了文件尾或者在数据传输期间流正忙。当_USE_FORWARD == 1 and _FS_TINY == 1 时,此函数可用。STM32F4不用
(22) f_mkfs 函数
FRESULT f_mkfs (
BYTE Drive, /* 逻辑驱动器号 */
BYTE PartitioningRule, /* 分区规则 */
UINT AllocSize /*位置单元大小 */
);
参数说明
Drive 要格式化的了逻辑驱动器号(0~9)
PartitioningRule 指定的分区规则, FDISK(0) 或者 SFD(1).在某些情况下,这个
参数被忽略。
AllocSize 强制位置单元(簇)大小以字节为单位。值必须是 2 的幂并
且在扇区大小与 128 倍扇区大小之间。当值为 0 时,簇的大
小由卷的大小决定。
函数返回值
FR_OK, FR_DISK_ERR, FR_NOT_READY, FR_WRITE_PROTECTED, FR_INVALID_DRIVE,
FR_NOT_ENABLED, FR_MKFS_ABORTED, FR_INVALID_PARAMETER
函数描述
f_mkfs 函数在逻辑驱动器上创建一个 FAT 卷。当 FDISK 被指定时,整个磁盘空间被创建为一个主分区然后在分区上创建 FAT 卷。当 SFD 被指定时, FAT 卷开始于物理驱动器的第一个扇区。如果逻辑驱动器具有多分区特征( _MULTI_PARTITION),被绑定到任何分区( 1-4), FAT 卷将被创建到指定分区上。在这种情况下,第二个参数 PartitioningRule被忽略。此时,在使用此函数前物理驱动器必须已用 f_fdisk 函数或其他分区工具分区。注意, FDISK 和 SFD 两个分区规则。 FDISK 格式通常用于硬盘、 MMC、 SDC 和CFC。它可以将一个物理驱动器划分为一个或多个分区使用一个 MBR 分区表。 SFD格式采用非分区方式。 FAT 卷开始于物理驱动器的第一个分区,而没有分区表。它被用于软盘、微驱动器、光盘和超级软盘等媒体。根据 Microsoft 发布的 FAT 说明, FAT 子类型 FAT12/FAT16/FAT32 由卷的簇数决定,并且别无其他。 因此,选择哪个 FAT 子类型决定于卷的大小和指定的簇大小。簇的大小影响文件系统的性能,簇越大性能越好。当_FS_READONLY == 0 and _USE_MKFS==1 时,此函数可用。
(23) f_fdisk 函数
FRESULT f_fdisk (
BYTE Drive, /* 物理驱动器号 */
const DWORD Partitions[], /* 分区大小*/
void* Work /* 工作区指针 */
);
参数说明
Drive 指定的待分区的物理驱动器
Partitions[] 分区映射表。必须具备四个条目,
Work 函数工作区指针。大小至少为_MAX_SS 字节。
函数返回值
FR_OK,FR_DISK_ERR,FR_NOT_READY,FR_WRITE_PROTECTED,FR_INVALID_PARAMETER
函数描述
f_fdisk 函数在物理磁盘的 MBR 中创建一个分区表。 分区规则采用通用的 FDISK格式,可以创建高达 4 个主分区。不支持扩展分区。 Partition[]制定了如何划分物理驱动器。第一项制定了第一个主分区的大小并且第四项制定了第四个主分区的大小。如果值小于或等于 100,表示逻辑分区占整个磁盘空间的百分比。如果值大于 100,表示分区大小一扇区为单位。当_FS_READONLY == 0 、 _USE_MKFS == 1 与_MULTI_PARTITION == 2 时,此函数可用。
(24) f_gets 函数
TCHAR* f_gets (
TCHAR* Str, /* 读缓冲区 */
int Size, /* 读缓冲区大小 */
FIL* FileObject /* 目标文件指针 */
);
参数说明
Str 存储读取字符串的读缓冲区指针
Size 以字符为单位的读缓冲区大小
FileObject 指向打开目标文件结构体的指针
函数返回值
当函数执行成功,返回 Str 内容。
函数描述
f_get 函数是 f_read 函数的封装函数。读操作直到一个’\\n’被存储、达到文件尾或缓冲区被填充了 size-1 个字符为止。读字符串以’\\0’终止。在没有读取字符串或在读操作期间发生错误, f_get()函数返回一个空指针。文件尾和错误状态可以使用宏 f_eof()和 f_error()检查。当 FatFs 配置为 Unicode API(_LFN_UNICODE == 1),文件以 UTF-8 编码读取并以UCS-2 方式保存到缓冲区。除非如此,文件每个字符一个字节的方式读取,没有任何代码转换。当_USE_STRFUNC 为 1 或 2 时,此函数可用。当_USE_STRFUN 设置为 2 时,文件中的’\\r’字符被去掉。
(25) f_putc 函数
int f_putc (
TCHAR Chr, /* 放置的字符 */
FIL* FileObject /* 目标文件指针 */
);
参数说明
Chr 放置的一个字符
FileObject 指向打开目标文件结构体的指针
函数返回值
当字符被成功写入时,函数返回改字符。由于磁盘满或者任意错误导致函数失
败,返回 EOF( -1)。当 FatFs 配置为 Unicode API(_LFN_UNICODE == 1),UCS-2 字符以 UTF-8 编码写入到文件。否则,以字节方式直接写入文件中。
函数描述f_put()函数是 f_write()函数的封装函数。当_FS_READONLY == 0 与 _USE_STRFUNC 为 1 或 2 时,此函数可用。当_USE_STRFUNC==2 时,’\\n’被转换为’\\r\\n’.
(26) f_puts 函数
int f_puts (
const TCHAR* Str, /* 字符串 */
FIL* FileObject /* 目标文件*/
);
参数说明
Str 要写入的以空字符串终止的字符串指针。
FileObject 指向打开目标文件结构体的指针
函数返回值
函数执行成功, 返回非负的写入字符数。由于磁盘满或者任意错误导致函数失
败,返回 EOF( -1)。当 FatFs 配置为 Unicode API(_LFN_UNICODE == 1),UCS-2 字符串以 UTF-8 编码写入到文件。否则,以字节流方式直接写入文件中。
函数描述
f_puts()函数是 f_put()函数的封装函数。
当_FS_READONLY == 0 与 _USE_STRFUNC 为 1 或 2 时,此函数可用。当
_USE_STRFUNC==2 时,’\\n’被转换为’\\r\\n’.
(27) f_printf 函数
int f_printf (
FIL* FileObject, /* 目标文件 */
const TCHAR* Format, /* 格式的字符串 */
...
);
参数说明
FileObject 指向打开目标文件结构体的指针
Format 以空字符结尾的格式化字符串指针
... 可选参数
函数返回值
函数执行成功,返回写入的字符数。由于磁盘满或者任意错误导致函数失败,
返回 EOF( -1)。
函数描述
f_printf()函数是 f_put()函数和 f_puts()函数的封装函数。格式控制指令时标准库
的子集,如下所示:
. 类型 c C s S d D u U x X b B
. 大小 l L
. 标志 0 -
当_FS_READONLY == 0 与 _USE_STRFUNC 为 1 或 2 时,此函数可用。当
_USE_STRFUNC==2 时,’\\n’被转换为’\\r\\n’.
当 FatFs 配置为 Unicode API(_LFN_UNICODE == 1),UCS-2 字符以 UTF-8 编码写入到文件。否则,以字节字符形式直接写入文件中。
(28) f_tell 函数
DWORD f_tell (
FIL* FileObject /* 目标文件 */
);
参数说明
FileObject 指向打开目标文件结构体的指针
函数返回值
返回当前文件的读写指针。
函数描述
在本版本( 0.99 f_tell 函数作为一个宏执行。
#define f_tell(fp) ((fp)->fptr)
(29) f_eof 函数
int f_eof (
FIL* FileObject /* 目标文件 */
);
参数说明
FileObject 指向打开目标文件结构体的指针
函数返回值
如果读写指针到达文件尾, f_eof 函数返回一个非零值;否则返回 0。
函数描述
在本版本( 0.99), f_eof 函数作为一个宏执行。
#define f_eof(fp) (((fp)->fptr) == ((fp)->fsize) ? 1 : 0)
(30) f_size 函数
DWORD f_size (
FIL* FileObject /*目标文件*/
);
参数说明
FileObject 指向打开目标文件结构体的指针
函数返回值
返回以字节为单位的文件大小。
函数描述
在本版本( 0.99), f_size 函数作为一个宏执行。
#define f_size(fp) ((fp)->fsize)
(31) f_error 函数
int f_error (
FIL* FileObject /*目标文件*/
);
参数说明
FileObject 指向打开目标文件结构体的指针
函数返回值
如果发生错误返回非零值;否则,返回零。
函数描述
在本版本( 0.99), f_error 函数作为一个宏执行。
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)