目  录 
1.1 
1.2 
1.3 
第 1 章  FatFs 使用说明................................................................................................1 
简介...........................................................................................................................1 
特性...........................................................................................................................1 
应用...........................................................................................................................1 
FatFs 软件包中相关文件.................................................................................2 
1.3.1 
FatFs 应用范围.................................................................................................2 
1.3.2 
FatFs 配置.........................................................................................................2 
1.3.3 
FatFs API 函数选择..........................................................................................4 
1.3.4 
1.3.5  路径名格式.......................................................................................................5 
1.3.6  关于长文件名...................................................................................................6 
1.3.7  重入...................................................................................................................7 
1.3.8  执行有效的文件访问.......................................................................................7 
1.3.9  临界区...............................................................................................................8 
1.3.10 
FatFs 的其它特性和新进展.............................................................................8 
1.3.11  程序移植...........................................................................................................9 
FatFs 软件包提供的 API 函数.......................................................................17 
1.3.12 
 
1.1  简介 
第1章 FatFs 使用说明 
随着信息技术的发展,当今社会的信息量越来越大,以往由单片机构成的系统简单地对
存储媒介按地址、按字节的读/写已经不能满足人们实际应用的需要,于是利用文件系统对
存储媒介进行管理成了今后单片机系统的一个发展方向。目前常用的文件系统主要有微软的
FATl2、FATl6、FAT32、NTFS 以及 Linux 系统下的 EXT2 和 EXT3 等。由于微软 Windows
的广泛应用,在当前的消费类电子产品中,用得最多的还是 FAT 文件系统,如 U 盘、MP3、
MP4 和数码相机等,所以找到一款容易移植和使用、占用硬件资源相对较小而功能又强大
的 FAT 开源文件系统,对于单片机系统设计者来说是很重要的。 
FatFs Module 是一种完全免费开源的 FAT 文件系统模块,专门为小型的嵌入式系统而
设计。它完全用标准 C 语言编写,且完全独立于 I/O 层,可以移植到 8051、PIC、AVR、SH、
Z80、H8 和 ARM 等系列单片机上且只需做简单的修改。它支持 FATl2、FATl6 和 FAT32,
支持多个存储媒介,有独立的缓冲区,可以对多个文件进行读/写。 
FatFs Module 有个简化版本 Tiny-FatFs,它跟完全版 FatFs 不同之处主要有两点: 
(1)  占用内存更少,只要 1 KB RAM; 
(2)  1 次仅支持 1 个存储介质。 
完全版 FatFs 和 Tiny-FatFs 的用法一样,仅仅是包含不同的头文件,本文主要以完全版
讲解 FatFs 的使用。 
1.2  特性 
  Windows 兼容的 FAT 文件系统; 
  平台无关,容易移植; 
  代码量小; 
  多种配置选项: 
  支持多卷(物理驱动器或分区); 
  多个 ANSI/OEM 代码页包括 DBCS; 
  支持长文件名,ANSI/OEM 或 Unicode; 
  支持 RTOS; 
  支持多种扇区大小; 
  只读、最小化的 API 和 I/O 缓冲区等。 
1.3  应用 
FatFs Module 一开始就是为了能在不同的单片机上使用而设计的,所以具有良好的层次
结构,如图 1.1 所示。 
图 1.1    FatFs 模块层次结构图 
 
 
1
 
最顶层是应用层,使用者无需理会 FatFs Module 的内部结构和复杂的 FAT 协议,只需
要调用 FatFs Module 提供给用户的一系列应用接口函数,如 f_open,f_read,f_write 和 f_close
等,就可以像在 PC 上读/写文件那样简单。 
中间层 FatFs Module 实现了 FAT 文件读/写协议。FatFs Module 的完全版提供的是 ff.c、
ff.h,简化版 Tiny-FatFs 提供的是 tff.c、tff.h。除非有必要,使用者一般不用修改,使用时将
需要版本的头文件直接包含进去即可。 
需要使用者编写移植代码的是 FatFs Module 提供的底层接口,它包括存储媒介读/写
接口 Disk I/O 和供给文件创建修改时间的实时时钟。 
本文讲解时移植硬件平台为 ZLG 公司的 SmartCortexM3-1700 和普通 U 盘。LPC1768
是一款 32 位 Cortex-M3 内核的单片机,具有多达 64 KB 的 SRAM、512 KB 的内部 Flash 和
丰富的外设。软件平台是 Keil 集成开发环境。 
1.3.1  FatFs 软件包中相关文件 
1.  平台无关 
ffconf.h        FatFs 模块配置文件 
ff.h                FatFs 和应用模块公用的包含文件 
ff.c                FatFs  模块 
diskio.h        FatFs and disk I/O 模块公用的包含文件 
integer.h      数据类型定义 
option            可选的外部功能 
2.  平台相关(不属于 FatFs 需要由用户提供) 
diskio.c        FatFs 与 disk I/O  模块接口层文件 
1.3.2  FatFs 应用范围 
  支持 FAT12、FAT16 和 FAT32; 
  可打开的文件:无限制,依赖于有效的存储器; 
  支持最多 10 个卷; 
  文件大小:与 FAT 类型有关(upto 4G-1 bytes); 
  卷大小:与 FAT 类型有关(upto 2T bytes on 512 bytes/sector); 
  簇大小:与 FAT 类型有关(upto 64K bytes on 512 bytes/sector); 
  扇区大小:与 FAT 类型有关(upto 4K bytes)。 
FatFs 模块在移植时需先注意以下两点: 
  ANSI C 
FatFs 模块是用 ANSI C 编写的中间件,只要编译器遵循 ANSI C,它都是平台无关的。 
  整型大小 
FatFs 假定 char/short/long 的长度为 8/16/32 位,而 int 为 16 位或 32 位,这些相应的定
义位于 integer.h 文件。这在大多数的编译器上都不会是问题,但是当与预定义的内容发生冲
突时,需要用户注意。 
1.3.3  FatFs 配置 
文件系统的配置项都在 ffconf.h 文件之中。 
(1)  _FS_TINY  :这个选项在 R0.07 版本之中开始出现,在之前的版本都是以独立的 C
 
2
 
 
文件出现,现在通过一个宏来修改使用起来更方便; 
(2)  _FS_MINIMIZE、_FS_READONLY、_USE_STRFUNC、_USE_MKFS、
_USE_FORWARD 这些宏是用来对文件系统进行裁剪的,下面的 1.3.4 小节中有详
细介绍; 
(3)  _CODE_PAGE  :本选项用于设置语言码的类型,对应的字库可以在网上下载,其
选项如下: 
  932 - Japanese Shift-JIS (DBCS, OEM, Windows) 
  936 - Simplified Chinese GBK (DBCS, OEM, Windows) 
  949 - Korean (DBCS, OEM, Windows) 
  950 - Traditional Chinese Big5 (DBCS, OEM, Windows) 
  1250 - Central Europe (Windows) 
  1251 - Cyrillic (Windows) 
  1252 - Latin 1 (Windows) 
  1253 - Greek (Windows) 
  1254 - Turkish (Windows) 
  1255 - Hebrew (Windows) 
  1256 - Arabic (Windows) 
  1257 - Baltic (Windows) 
  1258 - Vietnam (OEM, Windows) 
  437 - U.S. (OEM) 
  720 - Arabic (OEM) 
  737 - Greek (OEM) 
  775 - Baltic (OEM) 
  850 - Multilingual Latin 1 (OEM) 
  858 - Multilingual Latin 1 + Euro (OEM) 
  852 - Latin 2 (OEM) 
  855 - Cyrillic (OEM) 
  866 - Russian (OEM) 
  857 - Turkish (OEM) 
  862 - Hebrew (OEM) 
  874 - Thai (OEM, Windows) 
  ASCII only (Valid for non LFN cfg.) 
(4)  _USE_LFN  :取值为 0~3,主要用于长文件名的支持及缓冲区的动态分配: 
  0:不支持长文件名; 
  1:支持长文件名存储的静态分配,一般是存储在 BSS 段; 
  2:支持长文件名存储的动态分配,存储在栈上; 
  3:支持长文件名存储的动态分配,存储在堆上。 
(5)  _MAX_LFN  :可存储长文件的最大长度,其值一般为(12~255),但是缓冲区一
般占(_MAX_LFN + 1) * 2 bytes; 
(6)  _LFN_UNICODE  :为 1 时才支持 unicode 码; 
(7)  _FS_RPATH  :R0.08a 版本改动配置项,取值范围 0~2: 
  0:去除相对路径支持和函数; 
  1:开启相对路径并且开启 f_chdrive()和 f_chdir()两个函数; 
  2:在 1 的基础上添加 f_getcwd()函数。 
3
 
(8)  _VOLUMES  :支持的逻辑设备数目; 
(9)  _MAX_SS  :扇区缓冲的最大值,其值一般为 512; 
(10) _MULTI_PARTITION:定义为 1 时,支持磁盘多个分区; 
(11) _USE_ERASE  :R0.08a 新加入的配置项,设置为 1 时,支持扇区擦除; 
(12) _WORD_ACCESS  :如果定义为 1,则可以使用 word 访问; 
(13) _FS_REENTRANT  :定义为 1 时,文件系统支持重入,但是需要加上跟操作系统
信号量相关的几个函数,函数在 syscall.c 文件中; 
(14) _FS_SHARE  :文件支持的共享数目。 
FatFs 只要求提供 FatFs 模块所必需的底层磁盘 I/O 函数,如果存在一个可工作的目标磁
盘模块,你仅需将编写的新函数附加到 FatFs 模块上,如果没有,则需要提供其它磁盘模块
或者从头编写底层驱动。FatFs 中所有定义的函数并不总是必需的,例如,在只读配置模式
下,磁盘写函数是不需要的。表 1.1 显示了 FatFs 的函数需要依赖于配置选项。 
表 1.1    函数依赖配置选项 
函数 
要求 
注意事项 
disk_initialize 
disk_status 
disk_read 
disk_write 
disk_ioctl (CTRL_SYNC) 
disk_ioctl 
(GET_SECTOR_COUNT) 
disk_ioctl (GET_SECTOR_SIZE) 
disk_ioctl (GET_BLOCK_SIZE) 
disk_ioctl 
(CTRL_ERASE_SECTOR) 
get_fattime 
ff_convert 
ff_wtoupper 
ff_cre_syncobj 
ff_del_syncobj 
ff_req_grant 
ff_rel_grant 
ff_mem_alloc 
ff_mem_free 
1.3.4  FatFs API 函数选择 
Always 
Always 
Always 
_FS_READONLY == 0 
_FS_READONLY == 0 
_USE_MKFS == 1 
_MAX_SS >= 1024 
_USE_MKFS == 1 
_USE_ERASE == 1 
_FS_READONLY == 0 
_USE_LFN >= 1 
_USE_LFN >= 1 
_FS_REENTRANT == 1 
_FS_REENTRANT == 1 
_FS_REENTRANT == 1 
_FS_REENTRANT == 1 
_USE_LFN == 3 
_USE_LFN == 3 
磁盘 I/O 函数 
Unicode  支持函数 
有效文件位于 option/cc*.c. 
操作系统依赖函数 
有效文件位于 option/sysca ll.c. 
表 1.2 显示了通过配置选项对 API 函数进行选择(剪裁)以减小模块代码大小。 
 
 
 
 
4
 
功能 
f_mount 
f_open 
f_close 
f_read 
f_write 
f_sync 
f_lseek 
f_opendir 
f_readdir 
f_stat 
f_getfree 
f_truncate 
f_unlink 
f_mkdir 
f_chmod 
f_utime 
f_rename 
f_chdir 
f_chdrive 
f_getcwd 
f_mkfs 
f_forward 
f_putc 
f_puts 
f_printf 
f_gets 
表 1.2    API 函数选择 
_FS_MINIMIZE 
0  1  2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x
 
x
 
x  x
x  x
x  x
x  x
x  x
x  x
x  x
x  x
 
 
 
 
 
 
 
 
 
3 
 
 
 
 
 
 
x 
x 
x 
x 
x 
x 
x 
x 
x 
x 
x 
 
 
 
 
 
 
 
 
 
_FS_READONLY 
1 
0 
 
 
 
 
 
 
 
 
x 
 
x 
 
 
 
 
 
 
 
 
 
x 
 
x 
 
x 
 
x 
 
x 
 
x 
 
x 
 
 
 
 
 
 
 
x 
 
 
 
x 
 
x 
 
x 
 
 
 
_USE_STRFUNC 
1 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x 
x 
x 
x 
_FS_RPATH 
0
2
1
x
x
x
x
_USE_MKFS 
1 
0 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x 
 
 
 
 
 
 
 
 
 
 
 
_USE_FORWARD
1 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x 
 
 
 
 
1.3.5  路径名格式 
FatFs 模块上使用的路径名格式类似于 DOS/Windows 下的文件名,格式如下: 
"[drive#:][/]directory/file" 
FatFs 模块支持长文件名(LFN)和 DOS 8.3 文件名(SFN)。当使能 LFN 特性时  (_USE 
_LFN > 0),可以使用长文件名,子目录用‘\’或者‘/’隔开,这与 DOS/Windows API 函
数接口是相同的方式,不同的是逻辑驱动器用数字带一个冒号来指定的。当一个驱动器号被
忽略时,默认为驱动器 0 或者当前驱动器。控制字符(\0~\x1F)被认为是路径名的末尾。
首位或中间嵌入的空格是合法的,当配置为 LFN 时被看作是名字的一部分,配置为非 LFN
时被视为路径名的末尾。空格和点号被忽略。 
默认配置下(_FS_RPATH == 0),FatFs 没有一个像操作系统面向文件系统的当前目录
的概念。卷上的所有对象总是以根目录下的完整路径名来指定,不允许点目录名。标题分隔
符’/’被忽略,它可以存在或省略,默然的驱动器号为 0。 
 
5
 
当使能相对路径时(_FS_RPATH == 1),如果存在标题分隔符,指定的路径是指相对
于根目录,如果没有标题分隔符,指定目录是指相对于用 f_chdir 函数设置的当前目录,路
径名中允许使用点名称。默认的驱动器是用 f_chdrive 函数设定的当前驱动器。 
表 1.3    路径名格式 
_FS_RPATH == 0 
_FS_RPATH == 1 
驱动器 0 根目录 
驱动器 0 根目录 
驱动器 2 根目录 
驱动器 2 根目录 
路径名 
file.txt  驱动器 0 根目录下的一个文件 当前驱动器当前目录下的一个文件 
/file.txt  驱动器 0 根目录下的一个文件 当前驱动器根目录下的一个文件 
 
/ 
2: 
2:/ 
2:file.txt 驱动器 2 根目录下的一个文件 驱动器 2 当前目录下的一个文件 
../file.txt 文件名非法 
. 
文件名非法 
.. 
文件名非法 
dir1/..  文件名非法 
/.. 
文件名非法 
上级目录下的一个文件 
此目录 
当前目录的上级目录 
当前目录 
根目录() 
当前驱动器当前目录 
当前驱动器根目录 
驱动器 2 当前目录 
驱动器 2 根目录 
1.3.6  关于长文件名 
FatFs 从 0.07 版本开始支持长文件名(LFN)。在调用文件函数时,一个文件的两个文
件名(SFN 与 LFN)是通用的,除了 f_readdir 函数。支持长文件特性将需要一个额外的工
作缓冲区,此缓冲区的大小可以通过设置_MAX_LFN 来以可用的内存大小相符。因为长文
件名可长达 255 个字符,因此_MAX_LFN 应该设置为 255 来支持全特性的 LFN 选项。当工
作缓冲区的大小容不下给出的文件名时文件函数就会因为 FR_INVALID_NAME 而调用失
败。 
表 1.4    ARM7 上的 LFN 配置 
编码页 
程序大小
SBCS(单字节字符集) +3.7K 
932(日文  Shift-JIS) 
+62K 
936(简体中文  GBK) +177K 
949(韩文  Korean) 
+139K 
950(繁体中文  Big5) 
+111K 
当使能 LFN,模块增加的大小由编码页(Code Page)类型决定,表 1.4 显示了 LFN 禁
用与使用某些编码来使能时模块的不同大小。日语、中文与韩国语拥有成千上万的字词,因
需要一个巨大的 OEM-Unicode 双向转换表,模块的大小将大大的增大,如表 1.4 所示。 
注:FAT 文件系统的 LFN 特性是微软公司的专利。当在商用产品上使用时,根据最终目的的不同可
能需要获得微软的许可证。 
 
6
 
1.3.7  重入 
对不同卷的文件操作总是可以同时地工作,而与重入设置无关。而对于同一个卷的重入
访问可以通过使能_FS_REENTRANT 选项。此时,在 ff.c 中的与平台相关的锁定函数必须
为每个 RTOS 重新编写。如果一个文件函数调用时其访问的卷正被另一个线程使用,则此
访问将阻塞直到该卷解锁。如果等待时间超过了_TIMEOUT 毫秒,则函数将因 FR_TIMEOUT
而终止。某些 RTOS 可能不支持超时操作。 
f_mount 与 f_mkfs 函数是个例外,这些函数对于同一个卷不会重入。当使用这些函数时,
其它线程必须关闭此卷中相应的文件,避免对此卷的访问。 
注意此部分描述的是 FatFs 自身的重入,与底层磁盘 I/O 的重入无关。 
1.3.8  执行有效的文件访问 
为了在小型的嵌入式系统中得到优秀的读写效率,应用程序程序员需要可考虑 FatFs 究
竟做了什么。磁盘中的数据是通过下面的方式来被 f_read 函数传送。 
图 1.2    读非对齐扇区(短型) 
图 1.3    读非对齐扇区(长型) 
 
 
 
图 1.4    读对齐扇区 
文件 I/O 缓冲区(file I/O buffer)表示一个将被读/写数据的扇区的缓冲区。扇区缓冲区
可以是每个文件对象私有的,或者是文件系统共享的,缓冲区配置选项_FS_TINY 决定在文
件数据传输中使用哪种扇区缓冲区。当选择小缓冲区(1),数据内存的使用量将降低到每
个文件对象 512 字节。在这种情况下,FatFs 只使用一个扇区缓冲区来进行文件数据传输以
及 FAT/目录访问。配置为小缓冲区的缺点是:每次文件数据传输时 FAT 数据缓冲都会丢失
而必须从一个簇的边界开始重新载入数据。不过从其体面的表现与少内存消耗这方面来考
虑,这对于多数的应用也是合适的。 
 
7