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的许可
未完待续.....