FATFS模块应用笔记
如何港
基本考虑
该FATFS模块假设对便携性下列条件。
- ANSI C
的FATFS模块是用ANSI C编写(C89)中间件。没有平台依赖性,只要编译器符合ANSI C。 - 整数类型的大小
的FATFS模块假定为char的大小/短/长是8/16/32位和int是16位或32位。这些信件中定义integer.h。这会不会是在大多数编译器的一个问题。当与现有定义的任何冲突发生,你必须谨慎解决。
系统各组织
下面所示的依赖图是用FATFS模块的嵌入式系统的典型配置。
(一)如果用FATFS API的一个工作磁盘模块提供,没有额外的功能是必要的。(二)要附加不同的API,现有的磁盘驱动器,需要胶合功能翻译FATFS和驱动程序之间的API。
它的功能是必需的?
你需要提供所需的FATFS模块,没有别的只有低级别的磁盘I / O功能。如果目标工作磁盘模块已经存在,你需要写只胶功能,其附加到FATFS模块。如果没有,你需要的端口任何其他磁盘模块或从头开始写。大多数定义的函数并不总是必需的。例如,磁盘写入功能并不需要在只读配置。下表显示了功能需要依赖于配置选项。
功能 | 需要时: | 注 |
---|---|---|
disk_status disk_initialize disk_read |
总是 | 磁盘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!= _MIN_SS | |
disk_ioctl(CTRL_ERASE_SECTOR) | _USE_ERASE == 1 | |
ff_convert ff_wtoupper |
_USE_LFN> = 1 | Unicode支持功能。 可在选项/立方厘米*。c的。 |
ff_cre_syncobj ff_del_syncobj ff_req_grant ff_rel_grant |
_FS_REENTRANT == 1 | O / S相关的功能。 在选项/ syscall.c提供产品样本。 |
ff_mem_alloc ff_mem_free |
_USE_LFN == 3 |
范围
- 发子类型:FAT12,FAT16和FAT32。
- 打开文件的数目:无限,取决于可用的内存。
- 卷数:高达10。
- 文件大小:取决于FAT规格。(高达4G-1字节)
- 音量的大小:取决于FAT规格。(高达2T字节数为512字节/扇区)
- 簇的大小:取决于FAT规格。(高达64K字节512字节/扇区)
- 扇区大小:取决于FAT规格。(512 .. 4096字节)
内存使用
ARM7的 32位 | ARM7 拇指 | CM3 的Thumb-2 | AVR单片机 | H8/300H | PIC24 | RL78 | V850ES | SH-2A | RX600 | IA-32 | |
---|---|---|---|---|---|---|---|---|---|---|---|
编译器 | 海湾合作委员会 | 海湾合作委员会 | 海湾合作委员会 | 海湾合作委员会 | CH38 | C30 | CC78K0R | CA850 | SHC | RXC | VC6 |
_WORD_ACCESS | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
文字(全,读/写) | 10675 | 7171 | 6617 | 13355 | 10940 | 11722 | 13262 | 8113 | 9048 | 6032 | 7952 |
文本(最小值,读/写) | 6727 | 4631 | 4331 | 8569 | 7262 | 7720 | 9088 | 5287 | 5800 | 3948 | 5183 |
文字(全中,R / O) | 4731 | 3147 | 2889 | 6235 | 5170 | 5497 | 6482 | 3833 | 3972 | 2862 | 3719 |
文本(最小值,R / O) | 3559 | 2485 | 2295 | 4575 | 4064 | 4240 | 5019 | 2993 | 3104 | 2214 | 2889 |
BSS | V * 4 + 2 | V * 4 + 2 | V * 4 + 2 | V * 2 + 2 | V * 4 + 2 | V * 2 + 2 | V * 2 + 2 | V * 4 + 2 | V * 4 + 2 | V * 4 + 2 | V * 4 + 2 |
工作区 (_FS_TINY == 0) |
V * 560 + F * 550 |
V * 560 + F * 550 |
V * 560 + F * 550 |
V * 560 + F * 544 |
V * 560 + F * 550 |
V * 560 + F * 544 |
V * 560 + F * 544 |
V * 560 + F * 544 |
V * 560 + F * 550 |
V * 560 + F * 550 |
V * 560 + F * 550 |
工作区 (_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表示打开的文件数。所有样品均optimezed代码大小。
FATFS R0.10a选项: _FS_READONLY 0(读/写)或1(R / O) _FS_MINIMIZE 0(全功能)或3(最小化功能) _USE_STRFUNC 0(禁用字符串函数) _USE_MKFS 0(禁用f_mkfs功能) _USE_FORWARD 0(禁用f_forward功能) _USE_FASTSEEK 0(禁用快速查找功能) _CODE_PAGE 932(日语Shift-JIS) _USE_LFN 0(禁用LFN功能) _MAX_SS 512(固定扇区大小) _FS_RPATH 0(禁用相对路径功能) _FS_LABEL 0(禁用卷标功能) _VOLUMES V(要使用的逻辑驱动器的数量) _MULTI_PARTITION 0(每个驱动器的单分区) _FS_REENTRANT 0(禁用线程安全) _FS_LOCK 0(禁用文件锁定控制)
模块尺寸缩小
Follwing表显示了哪些API函数是由该模块尺寸缩减的配置选项中移除。
功能 | _FS_MINIMIZE | _FS_READONLY | _USE_STRFUNC | _FS_RPATH | _FS_LABEL | _USE_MKFS | _USE_FORWARD | _MULTI_PARTITION | |||||||||||
0 | 1 | 2 | 3 | 0 | 1 | 0 | 1/2 | 0 | 1 | 2 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | |
f_mount | |||||||||||||||||||
f_open | |||||||||||||||||||
f_close | |||||||||||||||||||
f_read | |||||||||||||||||||
f_write | x | ||||||||||||||||||
f_sync | x | ||||||||||||||||||
f_lseek | x | ||||||||||||||||||
f_opendir | x | x | |||||||||||||||||
f_closedir | 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_chdir | x | ||||||||||||||||||
f_chdrive | x | ||||||||||||||||||
f_getcwd | x | x | |||||||||||||||||
f_getlabel | x | ||||||||||||||||||
f_setlabel | x | x | |||||||||||||||||
f_forward | x | ||||||||||||||||||
f_mkfs | x | x | |||||||||||||||||
f_fdisk | x | x | x | ||||||||||||||||
f_putc | x | x | |||||||||||||||||
f_puts | x | x | |||||||||||||||||
f_printf | x | x | |||||||||||||||||
f_gets | x |
长文件名
该FATFS模块已开始在0.07版本,支持长文件名 (LFN)。这两个不同的文件名 的文件中,SFN与LFN,是透明的文件功能,除了f_readdir功能。要启用LFN功能,设置_USE_LFN为1,2或3,和一个Unicode代码转换功能添加ff_convert()和ff_wtoupper()到项目中。该LFN功能requiers除了一定的工作缓冲区。缓冲区的大小可以通过以下方式配置_MAX_LFN对应于可用存储器的大小。长文件名 的规模将可达255个字符,这样_MAX_LFN应设置为255的全功能LFN操作。如果工作缓冲区的大小不足以给定的文件名 ,该文件函数将失败,FR_INVALID_NAME。当使用重入特性的LFN特征,_USE_LFN必须设置为2或3。在这种情况下,文件函数分配堆栈或堆的工作缓存器。工作缓存器占用(_MAX_LFN + 1)* 2个字节。
代码页 | 程序大小 |
---|---|
SBCS | +3.7 K表 |
932(按Shift-JIS) | +62 K表 |
936(GBK) | +177 K表 |
949(韩文) | 139 K表 |
950(大五码) | +111 K表 |
当LFN功能启用时,该模块的尺寸将增加取决于所选择的代码页。右表显示有多少个字节时,LFN功能启用了一些代码页增加。特别是,在CJK区域,字符数万正在使用。不幸的是,它需要一个庞大的OEM Unicode双向转换表,并且模块的大小将显着增加其显示在表中。其结果是,与那些代码页将无法实施大多数8位微控制器LFN功能的FATFS。
需要注意的是FAT文件系统上的LFN功能是微软公司的专利。这是不是这样的,但是FAT32 FAT32大多数司机都与LFN功能。FATFS可以通过配置选项SWICH的LFN功能关闭。当使能在商业产品LFN功能,可能需要从Microsoft的许可取决于最终的目的地。
统一的API
默认情况下,FATFS使用ANSI / OEM代码下LFN配置的API集。FATFS也可以切换字符编码为Unicode的API(_LFN_UNICODE)。这意味着FATFS支持真LFN功能。欲了解更多信息,请参阅在描述文件名 。
重入
文件操作到不同的音量始终是可重入的,并可以同时工作。文件操作到相同体积是不可重入,但它也可以被配置为线程安全与_FS_REENTRANT选项。在这种情况下,还取决于操作系统同步对象的控制功能,ff_cre_syncobj(),ff_del_syncobj(),ff_req_grant()和ff_rel_grant()必须被添加到项目中。
当一个文件函数被调用,而该卷正在被任何其他任务使用,文件的功能被挂起,直到该任务留给文件的功能。如果等待时间超过了规定的期限_TIMEOUT,文件功能将中止与FR_TIMEOUT。超时功能可能不被一些实时操作系统的支持。
有一个例外f_mount(),f_mkfs(),f_fdisk()函数。这些功能是不可重入到同一个卷或相应的物理驱动器。当使用这些功能时,所有其他任务必须卸载卷,避免访问卷。
请注意,本节描述了重入的FATFS模块本身也是低水平的磁盘I / O层将需要重入的。
复制文件访问
FATFS模块不支持重复打开一个文件的读/写冲突控制。重复的开放只允许在每个开放方法到一个文件中读取模式。重复的打开与一个或多个写模式到一个文件总是被禁止,并且还公开文件不能被重命名和删除。违反这些规则可能会导致数据colluption。
文件锁控制,也可以通过提供_FS_LOCK选项。该值定义为同时管理打开的对象的数量。在这种情况下,如果任何打开,重命名或删除违反了上述文件shareing规则尝试,该文件中的函数将失败,FR_LOCKED。如果打开的文件和子目录数得到大于_FS_LOCK,open函数将失败FR_TOO_MANY_OPEN_FILES。
性能有效文件访问
为了获得良好的读取表现为小的嵌入式系统上的/写入文件,应用程序程序员应该考虑什么过程在FATFS模块来完成。卷上的文件数据传输由以下顺序f_read()函数。
图1。部门错过对齐的读(短)
图2。部门错过对齐的读(长)
图3。界对齐的读
文件I / O缓冲区是一个扇区缓冲区读取/写入的扇区的部分数据。该部门的缓冲区要么是文件私营部门缓冲区中的每个文件对象或文件系统中的对象共享扇区缓冲区。缓冲器配置选项_FS_TINY determins哪个扇区缓冲器是用于文件数据的传输。当微小的缓冲液(1)被选中,数据存储消耗减少512个字节的文件对象。在这种情况下,FATFS模块只使用一个扇区缓冲区中的文件数据传输和FAT /目录访问文件系统对象。微小的缓冲器配置的缺点是:缓存中的扇区缓冲器中的FAT的数据将通过文件的数据传输丢失,则必须在每个簇的边界被重新加载。但是这将是适合于大多数应用程序从不俗的性能和低内存消耗率的观点。
图1显示了一个局部的扇区,扇区不对齐的文件的一部分,通过文件I / O缓冲器传送。对图2中所示的长数据传输,覆盖一个或多个扇区的数据传输中被传输到应用程序缓冲区直接。图3表明,ENTIER传输数据的情况下是相一致的扇区边界。在这种情况下,不使用文件I / O缓冲区。在直接传输,读取扇区的最大程度上与disk_read()函数在一个时间,但多个部门的转移从来没有在集群边界,即使它是连续的。
因此采取努力扇区对齐的读/写是Accesss避免了缓冲的数据传输和读/写性能将得到改善。另外的效果,缓存的FAT数据不会被在微小的配置文件的数据传输刷新,以便它可以实现相同的性能,与小的内存占用非微小的配置。
对闪存介质考虑
为了最大限度地提高闪存的介质,诸如SDC和CFC的写入性能,就必须考虑其characteristitcs进行控制。
采用多发,扇区写
吞吐量闪速存储器介质的写入变成最坏在单个扇区写入和它增加正比于每一个写事务的扇区数。这种效应更appers在更快速总线时钟,它的比例往往成为量约大于10。写事务的数量也影响到介质的寿命。因此,应用程序应该写在大数据块中的数据成为可能。理想的块大小为2个字节簇大小或功率和字节偏移量应该是对齐到块。当然,应用程序和媒体之间的所有图层都必须支持多扇区写功能,但是大多数的开源磁盘驱动程序的缺乏它。不拆一个多扇区写入请求到单个扇区写或写吞吐量变得很差。需要注意的是FATFS模块和它的采样磁盘驱动程序supprt多个部门的读/写功能。
强制记忆擦除
当删除一个文件f_remove()函数,通过该文件所占用的簇的数据上都标有FAT'自由'。但是包含该文件的数据的数据扇区不施加任何处理,以便将文件数据占用左侧闪存阵列作为“活块'的一部分。如果文件的数据被强制删除的删除文件,对快闪记忆体可用块数将有所增加。这可能会跳过内部块擦除操作,以对下一个写入的数据块。作为结果的写入性能可能被改进。要启用该功能,设置_USE_ERASE为1。请注意,这是与闪存介质的内部过程的期望的功能。它可能并不总是有效的,f_remove()函数将需要时间来删除一个大文件。大多数应用程序并不需要这个功能。
关键的第
如果一个写操作FAT卷因任何意外故障,如突然停电,不正确的磁盘删除和不可恢复的磁盘错误而中断,该卷上的FAT结构可以被打破。下图显示了FATFS模块的关键部分。
在红色部分的中断可能会导致交联,这样一来,被改变的对象可能会丢失。如果在黄色部分中断时发生,存在一个或多个可能在下面列出。
- 被重写的文件数据已展开。
- 被追加的文件返回初始状态。
- 创建新的文件不见了。
- 创建为新的或覆盖的遗体,但没有内容的文件。
- 磁盘利用效率变得更糟,由于丢失的簇。
每一种情况下不会影响在写入模式下没有打开的文件。为了尽量减少数据丢失的风险,关键部分可以通过最小化该文件在写入模式打开时,或使用最小化f_sync()函数,如图5。
延长使用FATFS API
这些是长时间使用FATFS的API的示例。新项目将被添加,每当一个有用的代码被发现。
关于FATFS许可证
这是包含在源代码FATFS授权文件的副本。
/ * ------------------------------------------------ ---------------------------- / / FATFS - FAT文件系统模块R0.10a(C)CHAN 2014 / ------------------------------------------------- ---------------------------- / / FATFS模块为小型嵌入式系统的通用FAT文件系统模块。 /这是一个开放的教育,科研和商业的免费软件 /根据以下trems的许可证策略的发展。 / /版权所有(C)2014年,陈,保留所有权利。 / / *该FATFS模块是一个免费的软件,并没有保修。 / *使用上没有限制。您可以使用,修改和重新发布它 /个人,非营利性或商业性产品根据您的责任。 / *源代码的再分发必须保留以上版权声明。 / / ------------------------------------------------- ---------------------------- /
因此FATFS许可是BSD-风格许可证之一,但有一个显著的特征。因为FATFS是嵌入式的项目,再分发的二进制形式,如嵌入式代码,十六进制文件和二进制库的情况下,未指定,以增加其实用性。分布的文档需要不包括有关FATFS和它的授权文件,并且它也可能。这等同于在BSD 1 - 第许可证。当然FATFS是基于GNU GPL的项目兼容。当重新分配FATFS有任何修改,授权,也可以改为GNU GPL或BSD-风格许可证。