更多资料见 酷学玩首页:http://www.q-sharewe.com
FATFS 浅谈
刚开始看到 FATFS 时,一头雾水,不知道从何下手,网上也搜了很多
资料,要么高深莫测,要么简单地一笔代过.
断断续续地摸索了一段时间,算是对文件系统有了初步的认识,整
理一下思路,将自己的学习过程,及学习心得写出来与大家分享, 文笔
有限,力求简洁易懂,希望对初学者有所帮助,不足之处请指正.
笔者用的是酷学玩 summer V1.3 的开发板,64M 的 microSD 卡(已
格式化为 FAT32 格式),底层驱动是 yuanyin 移植的,如果你用的不是
酷学玩 stm32 的板子,那也没关系,网上有很多移植的例程,可以参照着
尝试移植;或者根据酷学玩的例程修改也可.
本文主要介绍 FATFS 的 API 函数,仅针对初学者入门,高手请拍
砖.
例程中用到的全局变量定义如下:
FATFS fs; // Work area (file system object) for logical drive
FIL fsrc, fdst; // file objects
FRESULT res; // FatFs function common result code
UINT br, bw; // File R/W count
更多资料见 酷学玩首页:http://www.q-sharewe.com
一
一一
一.
..
.注册工作区域
注册工作区域注册工作区域
注册工作区域
FRESULT f_mount (
BYTE
Drive
, /* Logical drive number */
FATFS*
FileSystemObject
/* Pointer to the work area */
);
函数说明:
1. 此函数的作用就是在磁盘里注册一个缓冲区域,用来存储 FAT32 文件系统的一些相关信
息.
2. 参数说明:
a) Drive : 盘符
b) *FileSystemObject : 指向缓冲区域的指针
3. 对磁盘进行操作之前,这个函数是不可少的
例程 : f_mount(0 , &fs);
二
二二
二.
..
.打开文件夹
打开文件夹打开文件夹
打开文件夹
FRESULT f_opendir (
DIR*
DirObject
, /* Pointer to the blank directory object
structure */
const TCHAR*
DirName
/* Pointer to the directory name */
)
函数说明:
1. 此函数可以打开一个已存在的文件夹
2. 参数说明:
a) *DirObject : 指向一个空白的结构体,用来存储要打开的文件夹信息
b) *DirName : 指向该文件夹名称的指针
三
三三
三.
..
.读取文件夹
读取文件夹读取文件夹
读取文件夹
FRESULT f_readdir (
DIR*
DirObject
, /* Pointer to the open directory object */
FILINFO*
FileInfo
/* Pointer to the file information structure */
);
函数说明:
1. 此函数按照顺序读取文件夹内文件
2. 参数说明:
a) *DirObject : 指向读取的文件夹的信息结构体的指针
b) *FileInfo : 指向文件信息结构体,用来存储读取到的文件的信息
3. 重复调用此函数可读取文件夹内所有文件
4. 当所有文件读取结束,函数返回一个空字符串到 f_name[] 中
5. 如果一个空指针赋给 *FileInfo ,将返回从第一个文件开始读取.
更多资料见 酷学玩首页:http://www.q-sharewe.com
例程:这段程序先打开文件夹 folde/move ,然后查找其中的存档文件,并通过串口输出
读取的文件名
if (f_opendir(&dirs, "folder/move") == FR_OK) //打开文件夹
{
while (f_readdir(&dirs, &finfo) == FR_OK) //按照顺序读文件夹
{
if(!finfo.fname[0]) break; //如果文件名为 0,结束
{
if(finfo.fattrib == AM_ARC) //判断文件属性
Debug("文件名:%s\r\n",finfo.fname);
}
}
}
串口输出如下:
在 PC 上查看 SD 卡:
可以看到,程序输出了后面三个文件的名称,对文件夹没作处理,因为在程序里
对文件属性进行了判断:
if(finfo.fattrib == AM_ARC),意思是只对存档文件进行处理;
至于什么是存档文件,以下是在百度知道搜到的结果:
视窗系统中文件属性有四种类型,我来告诉你这四种类型是什么意思:
只读-表示该文件不能被修改
隐藏 -表示该文件在系统中是隐藏的,在默认情况下用户不能看见这些文件。
系统 - 表示该文件是操作系统的一部分。
存档- 表示该文件在上次备份前已经修改过了,一些备份软件在备份系统后会把这些文件默
认的设为存档属性。
存档属性在一般文件管理中意义不大,但是对于频繁的文件批量管理很有帮助。
更多资料见 酷学玩首页:http://www.q-sharewe.com
四
四四
四.
..
.打开
打开打开
打开\
\\
\新建一个文件
新建一个文件新建一个文件
新建一个文件:
::
:
FRESULT f_open (
FIL*
FileObject
, /* Pointer to the blank file object structure
*/
const TCHAR*
FileName
, /* Pointer to the file neme */
BYTE
ModeFlags
/* Mode flags */
);
函数说明:
1. 此函数可以打开,或新建一个文件
2. 参数说明
a) *FileObject : 指向一个用来存储文件对象的空结构体的指针
b) *FileName : 指向文件名的指针
c)
ModeFlags : 打 开 方 式 , 可 以 是 以 下 一 种 或 几 种 的 组 合 (
默 认 方 式 是
FA_OPEN_EXISTING)
Value
ValueValue
Value
Description
DescriptionDescription
Description
FA_READ 读模式,(读写模式可同时生效)
FA_WRITE 写模式,(读写模式可同时生效)
FA_OPEN_EXISTING
默认打开方式
FA_OPEN_ALWAYS
打开文件,如果文件不存在,则创建一个新文件;
用此种方式,可以用 f_lseek 在文件后追加数据
FA_CREATE_NEW 新建文件,如果文件已存在,则新建失败
FA_CREATE_ALWAYS
新建文件,如果文件已存在,覆盖旧文件
五
五五
五.
..
.读取文件
读取文件读取文件
读取文件:
::
:
FRESULT f_read (
FIL*
FileObject
, /* Pointer to the file object structure */
void*
Buffer
, /* Pointer to the buffer to store read data */
UINT
ByteToRead
, /* Number of bytes to read */
UINT*
ByteRead
/* Pointer to the variable to return number of bytes
read */
);
函数说明:
1. 这个函数可以读取文件的内容
2. 参数说明:
a) *FileObject : 指向文件对象结构体的指针
b) *Buffer : 指向存储读取到的数据的缓冲的指针
c) ByteToRead : 准备读取的字节数
d) *ByteRead :
i. 它的作用就是用来检测文件的末尾,就是下面例程中的这一句:
if (res || br < sizeof(buffer)) break;
ii. 每次 f_read 执行完后,*ByteRead 值等于本次读取到的字节数,若*ByteRead
<ByteToRead,即本次读取到的字节小于准备读取的字节,说明读指针已到达
文件末尾.
更多资料见 酷学玩首页:http://www.q-sharewe.com
例程:此处参考酷学玩例程,以读取的方式打开文件,然后将文件内容通过串口输出。
res = f_open(&fsrc, "news/news.txt", FA_READ);
if(!res)
{
Debug("open news/news.txt : %d\r\n",res);
br=1;
a=0;
Debug("文件内容:");
for (;;)
{
for(a=0; a<512; a++) buffer[a]=0;
res = f_read(&fsrc, buffer, sizeof(buffer), &br);
Debug("%s\r\n",buffer);
if (res || br < sizeof(buffer)) break; // error or eof
}
}
f_close(&fsrc); //
不论是打开,还是新建文件,一定记得关闭
运行后串口输出结果:
下面是在PC中查看: