FatFs模块程序移植手册
1. 如何移植?
基本情况
FatFs模块假设有以下的移植条件
l ANSI C
FatFs模块是用ANSI C(89)书写的中间件。它不依赖于任何平台,只要编译器符合ANSI C就可以。
l Interger类型的大小
FatFs模块假设char/short/long类型的大小分别是8/16/32位并且int是16位或者32位。这些内容定义在integer.h文件中,这对于大多数编译器来说不成问题。当和现有定义发生任何冲突时,你必须要小心处理。
需要处理那些函数?
你只需要提供FatFs模块所需的低级别磁盘I/O函数。如果目标系统中已经存在一个磁盘模块在工作,你仅需要实现对应于FatFs模块的功能函数。否则的话,你需要移植一个磁盘模块并从头实现它。不是所有定义的函数都需要实现。比如,磁盘写入函数在只读模式下就不需要实现。下面的表格列出了根据配置选项哪些函数需要实现。
函数 |
什么时候需要实现 |
注意事项 |
disk_initialize disk_status disk_read |
Always |
磁盘I/O 函数。 Ffsample.zip中有示例。 网络上也有好多实现版本。 |
disk_write get_fattime disk_ioctl (CTRL_SYNC) |
_FS_READONLY == 0 |
|
disk_ioctl (GET_SECTOR_COUNT) disk_ioctl (GET_BLOCK_SIZE) |
_USE_MKFS == 1 |
|
disk_ioctl (GET_SECTOR_SIZE) |
_MAX_SS > 512 |
|
disk_ioctl (CTRL_ERASE_SECTOR) |
_USE_ERASE == 1 |
|
ff_convert ff_wtoupper |
_USE_LFN >= 1 |
支持Unicode函数。 |
ff_cre_syncobj ff_del_syncobj ff_req_grant ff_rel_grant |
_FS_REENTRANT == 1 |
系统依赖函数。 |
ff_mem_alloc ff_mem_free |
_USE_LFN == 3 |
2. 限制
l FAT子类型:FAT12、FAT16和FAT32。
l 打开文件的数量:无限制,由系统可利用的内存来决定。
l 卷的数量:最多10个。
l 文件大小:依赖于FAT规格。(1-4G字节)
l 卷大小:依赖于FAT规格。(512字节/扇区时最高2T)
l 簇大小:依赖于FAT规格。(512字节/扇区时最高64K)
l 扇区大小:依赖于FAT规格。(最高4K字节)
3. 内存使用情况
|
ARM7 32bit |
ARM7 Thumb |
Crotex-M3 Thumb-2 |
AVR |
H8/300H |
PIC24 |
RL78 |
V850ES |
SH-2A |
RX62N |
IA-32 |
Compiler |
GCC |
GCC |
GCC |
GCC |
CH38 |
C30 |
CC78K0R |
CA850 |
SHC |
RXC |
VC6 |
_WORD_ACCESS |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
Text (Full, R/W) |
10459 |
7201 |
6623 |
12646 |
10686 |
11466 |
12967 |
7732 |
8752 |
5747 |
7545 |
Text (Min, R/W) |
6503 |
4745 |
4297 |
8306 |
6986 |
7440 |
8745 |
4938 |
5576 |
3746 |
4923 |
Text (Full, R/O) |
4535 |
3181 |
2869 |
5960 |
4876 |
5286 |
6060 |
3554 |
3804 |
2659 |
3450 |
Text (Min, R/0) |
3303 |
2493 |
2171 |
4366 |
3770 |
3984 |
4604 |
3684 |
2940 |
2025 |
2664 |
Bss |
D*4 + 2 |
D*4 + 2 |
D*4 + 2 |
D*2 + 2 |
D*4 + 2 |
D*2 + 2 |
D*2 + 2 |
D*4 + 2 |
D*4 + 2 |
D*4 + 2 |
D*4 + 2 |
Work area (_FS_TINY == 0) |
V*560 + F*550 |
V*560 + F*550 |
V*560 + F*550 |
V*560 + F*554 |
V*560 + F*550 |
V*560 + F*554 |
V*560 + F*554 |
V*560 + F*554 |
V*560 + F*554 |
V*560 + F*550 |
V*560 + F*550 |
Work area (_FS_TINY == 1) |
V*560 + F*36 |
V*560 + F*36 |
V*560 + F*36 |
V*560 + F*32 |
V*560 + F*36 |
V*560 + F*32 |
V*560 + F*32 |
V*560 + F*36 |
V*560 + F*36 |
V*560 + F*36 |
V*560 + F*36 |
一些目标系统的内存使用情况有以下情况。内存大小以字节为单位。V代表挂载的卷的数量,F表示打开文件的数量。所有的示例都在代码大小上进行了优化。
_FS_READONLY 0 (R/W), 1 (R/O) _FS_MINIMIZE 0 (Full function), 3 (Minimized function) _USE_STRFUNC 0 (Disable string functions) _USE_MKFS 0 (Disable f_mkfs function) _USE_FORWARD 0 (Disable f_forward function) _USE_FASTSEEK 0 (Disable fast seek feature) _CODE_PAGE 932 (Japanese Shift-JIS) _USE_LFN 0 (Disable LFN) _MAX_SS 512 (Fixed sector size) _FS_RPATH 0 (Disable relative path) _VOLUMES D (Number of logical drives to be used) _MULTI_PARTITION 0 (Single partition per drive) _FS_REENTRANT 0 (Disable reentrancy) _FS_SHARE 0 (Disable shareing control)
4. 模块大小的减少
下表展示了根据配置选项可以移除的API函数,以减少模块大小。
Function |
_FS_MINIMIZE |
_FS_READONLY |
_USE_STRFUNC |
_FS_RPATH |
_USE_MKFS |
_USE_FORWARD |
_MULTI_PARTITION |
||||||||||
0 |
1 |
2 |
3 |
0 |
1 |
0 |
1/2 |
0 |
1 |
2 |
0 |
1 |
0 |
1 |
0/1 |
2 |
|
F_mout |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
F_open |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
F_close |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
F_read |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
F_write |
|
|
|
|
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_sysn |
|
|
|
|
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_lseek |
|
|
|
X |
|
|
|
|
|
|
|
|
|
|
|
|
|
F_opendir |
|
|
X |
X |
|
|
|
|
|
|
|
|
|
|
|
|
|
F_readdir |
|
|
X |
X |
|
|
|
|
|
|
|
|
|
|
|
|
|
F_stat |
|
X |
X |
X |
|
|
|
|
|
|
|
|
|
|
|
|
|
F_getfree |
|
X |
X |
X |
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_truncate |
|
X |
X |
X |
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_unlink |
|
X |
X |
X |
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_mkdir |
|
X |
X |
X |
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_chmod |
|
X |
X |
X |
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_utime |
|
X |
X |
X |
|
X |
|
|
|
|
|
|
|
|
|
|
|
f_rename |
|
X |
X |
x |
|
X |
|
|
|
|
|
|
|
|
|
|
|
F_chidir |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
|
|
F_chdrive |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
|
|
F_getcwd |
|
|
|
|
|
|
|
|
X |
x |
|
|
|
|
|
|
|
F_mkfs |
|
|
|
|
|
X |
|
|
|
|
|
X |
|
|
|
|
|
F_fdisk |
|
|
|
|
|
X |
|
|
|
|
|
X |
|
|
|
x |
|
F_forward |
|
|
|
|
|
|
|
|
|
|
|
|
|
x |
|
|
|
F_putc |
|
|
|
|
|
X |
x |
|
|
|
|
|
|
|
|
|
|
F_puts |
|
|
|
|
|
X |
X |
|
|
|
|
|
|
|
|
|
|
F_printf |
|
|
|
|
|
X |
X |
|
|
|
|
|
|
|
|
|
|
F_gets |
|
|
|
|
|
|
X |
|
|
|
|
|
|
|
|
|
|
5. 长文件名
FatFs模块开始从R0.07版本开始支持长文件名。短文件名和长文件名两者的对于文件的区别除了f_readdir函数以外是透明的。设置_USE_LFN为1,2或者3来使能长文件名并且添加ff_convert()和ff_wtoupper()函数到工程中来支持unicode。长文件名特性额外需要一个特定的工作缓冲区。这个缓冲区大小可以根据内存的大小由_MAX_LFN来配置。长文件名的大小可达255个字节,所以_MAX_LFN需要设置为255以支持长文件名所有的特性操作。如果对于给定的文件名,工作缓冲区的大小不足的话,文件函数会返回FR_INVALID_NAME的错误值。当需要设置长文件名的重入特性时,_USE_LFN需要设置为2或者3。这时,文件函数从栈或者堆中申请工作缓冲区。工作缓冲区占用(_MAX_LFN+1)*2个字节。
6. Unicode API
7. 重入
8. 重复的文件访问
9. 有效文件访问的性能
10. 闪存介质的注意事项
11. 临界区
12. FatFs的许可
未完待续.....