移植到不同平台的考虑事项
The FatFs module is assuming following terms on portability.
- ANSI C
- The FatFs module is a middleware that written in ANSI C. There is no platform dependence, so long as the compiler is in compliance with ANSI C.
- FatFs模块是用ANSI C编写的中间件,只要编译器遵循ANSI C,它都是平台无关的。
- Size of integer types
- The FatFs module assumes that size of char/short/long are 8/16/32-bit and int is 16 or 32 bit. These correspondence are defined in integer.h. This will not be a problem on most compilers. When any conflict with existing definitions is occured, you must resolve it with care.
- FatFs假定char/short/long的长度为8/16/32位,而int为16位或32位,这些相应的定义位于integer.h文件。这在大多数的编译器上都不会是问题,但是当与预定义的内容发生冲突时,你必须小心地解决。
内存使用(R0.07)
AVR | H8/300H | PIC | TLCS-870/C | V850ES | SH2 | ARM7TDMI | IA-32 | |
---|---|---|---|---|---|---|---|---|
编译器 | gcc(WinAVR) | CH38 | gcc(C30) | CC870C | CA850 | SHC | gcc(WinARM) | MSC |
_WORD_ACCESS | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
ROM (Full, R/W) | 11136 | 10356 | 10838 | 15167 | 7682 | 8654 | 10628 | 7232 |
ROM (Min, R/W) | 7072 | 6696 | 7007 | 9800 | 4634 | 5570 | 6564 | 4647 |
ROM (Full, R/O) | 5218 | 4626 | 4949 | 6786 | 3528 | 3826 | 4676 | 3267 |
ROM (Min, R/O) | 3626 | 3418 | 3536 | 4941 | 2558 | 2874 | 3272 | 2397 |
RAM (Static) | D*2 + 2 | D*4 + 2 | D*2 + 2 | D*2 + 2 | D*4 + 2 | D*4 + 2 | D*4 + 2 | D*4 + 2 |
RAM (Dynamic) (_FS_TINY == 0) | D*560 + F*544 | D*560 + F*550 | D*560 + F*544 | D*560 + F*550 | D*560 + F*550 | D*560 + F*550 | D*560 + F*550 | |
RAM (Dynamic) (_FS_TINY == 1) | D*560 + F*32 | D*560 + F*36 | D*560 + F*32 | D*560 + F*32 | D*560 + F*36 | D*560 + F*36 | D*560 + F*36 | D*560 + F*36 |
These are the memory usage on some target systems with following condition. The memory sizes are in unit of byte, D means number of volumes and F means number of open files. All samples are optimezed in code size.
这是在以下情形时一些目标系统的内存用量,内存大小以字节计算,D代表卷数量,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)
_CODE_PAGE 932 (Japanese Shift-JIS)
_USE_LFN 0 (Disable LFN)
_MULTI_PARTITION 0 (Single partition)
_EXCLUDE_LIB 0 (Use string.h)
_FS_REENTRANT 0 (Disable reentrancy)
减小模块大小
Follwing table shows which function is removed by configuration options for the module size reduction.
下面的表显示了通过设置配置选项哪些函数将会移除,进而减小模块大小
Function | _FS_MINIMIZE | _FS_READONLY | _USE_STRFUNC | _USE_MKFS | _USE_FORWARD | ||
1 | 2 | 3 | 1 | 0 | 0 | 0 | |
f_mount | |||||||
f_open | |||||||
f_close | |||||||
f_read | |||||||
f_write | x | ||||||
f_sync | 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_mkfs | x | x | |||||
f_forward | x | ||||||
f_putc | x | x | |||||
f_puts | x | x | |||||
f_printf | x | x | |||||
f_gets | x |
长文件名
The FatFs module supports long file name (LFN) from revision 0.07. The two different file names, SFN and LFN, of a file is transparent in the file functions except for f_readdir function. The LFN feature requiers a certain working buffer in addition. The buffer size can be configured by _MAX_LFN corresponding to the available memory size. The size of long file name will reach up to 255 characters, so that the _MAX_LFN should be set to 255 for full featured LFN operation. When the size of working buffer is insufficient for the given file name, the file function will fail with FR_INVALID_NAME.
FatFs从0.07版本开始支持长文件名(LFN)。在调用文件函数时,一个文件的两个文件名(SFN与LFN)是通用的,除了 f_readdir函数。支持长文件特性将需要一个额外的工作缓冲区,此缓冲区的大小可以通过设置_MAX_LFN来以可用的内存大小相符。因为长文件名 长达255个字符,因此_MAX_LFN应该设置为255来支持全特性的LFN选项。当工作缓冲区的大小容不下给出的文件名时文件函数就会因为 FR_INVALID_NAME而调用失败。
LFN cfg on ARM7DMI Code page ROM size [bytes]
SBCS +4719
932(Shift-JIS) +63755
936(GBK) +178943
949(Korean) +141003
950(Big5) +112631
When LFN is enabled, the module size will be increased depends on the selected code page. Right table shows the difference in module size between the conditions that LFN is disabled and enabled on some code pages. We are the Japanese, Chinese and Korean have tens of thousands of characters. Unfortunately, it requires a huge OEM-Unicode bidirectional conversion table and the module size will be drastically increased that shown in the table. As the result, the FatFs with LFN enabled will not able to be implemented to most 8-bit microcontrollers including AVR. This is the reason why I had not been interested in implementing the LFN feature for a long time :-)
当使能LFN,模块增加的大小由编码页类型决定,右边的表显示了LFN禁用与使用某些编码来使能时模块的不同大小。日语、中文与韩国语拥 有成千上万的字词,而不幸的是,将需要一个巨大的OEM-Unicode 双向转换表,模块的大小将大大的增大,如表所示。因此,使能LFN的FatFs将不能在包括AVR在内的大多数8位微控制器上使用。这也是为什么我长期以 来对实现LFN特性不感兴趣:-).
Note that the LFN feature on the FAT file system is a patent of Microsoft Corporation. When enable it on the commercial products, a license from Microsoft may be required depends on the final destination.
请注意:FAT文件系统的LFN特性是微软公司的专利。当在商用产品上使用时,根据最终目的的不同可能需要获得微软的许可证。
重入
The file operations to the different volume can always work simultaneously independent of re-entrancy setting. The re-entrancy to the same volume can be enabled with _FS_REENTRANT option. In this case, also the platform dependent lock out function in the ff.c must be re-written for each RTOS. When a file function is called while the volume is in use by any other thread, the access is blocked until the volume is unlocked. If wait time exceeded _TIMEOUT milliseconds, the function will abort with FR_TIMEOUT. The timeout might not be supported on some RTOS.
对不同卷的文件操作总是可以同时地工作,而与重入设置无关。而对于同一个卷的重入访问可以通过使能_FS_REENTRANT选项。此 时,在ff.c中的与平台相关的锁定函数必须为每个RTOS重新编写。如果一个文件函数调用时其访问的卷正被另一个线程使用,则此访问将阻塞直到该卷解 锁。如果等待时间超过了_TIMEOUT毫秒,则函数将因FR_TIMEOUT而终止。某些RTOS可能不支持超时操作。
There is an exception on f_mount and f_mkfs function. These functions are not re-entrant to the same volume. When use these functions, other thread must close the corresponding file on the volume and avoid to access the volume.
f_mount 与 f_mkfs 函数是例外,这些函数对于同一个卷不会重入。当使用这些函数时,其他线程必须关闭此卷中相应的文件,避免对此卷的访问。
Note that this section describes on the re-entrancy of the FatFs module itself. There is no assumtion on the re-entrancy of low level disk I/O module.
注意此部分描述的是FatFs自身的重入,与底层磁盘I/O的重入无关。
执行有效的文件访问
For good performance on reading/writing files on the small embedded system, application programmer should consider what process is done in the FatFs module. The file data on the disk is transferred in following sequence by f_read function.
为了在小型的嵌入式系统中得到优秀的读写效率,应用程序程序员需要可考虑FatFs究竟做了什么。磁盘中的数据是通过下面的方式来被f_read函数传送。
Figure 1. Sector miss-aligned read (short)
Figure 2. Sector miss-aligned read (long)
Figure 3. Sector aligned read
The file I/O buffer means a sector buffer to read/write a partial data on the sector. The sector buffer is either file private sector buffer on each file object or shared sector buffer on the file system object. The buffer configuration option _FS_TINY determins which sector buffer is used for the file data transfer. When tiny buffer (1) is selected, data memory consumption is reduced 512 bytes each file object. In this case, FatFs module uses only a sector buffer on the file system object for file data transfer and FAT/directory access. The disadvantage of the tiny buffer configuration is: the FAT data cached in the sector buffer will be lost by file data transfer and it must be reloaded at every cluster boundary. However it will be suitable for most application from view point of the decent performance and low memory comsumption.
文件I/O缓冲区(file I/O buffer)表示一个将被读/写数据的扇区的缓冲区。扇区缓冲区可以是每个文件对象私有的,或者是文件系统共享的,缓冲区配置选项_FS_TINY决定 在文件数据传输中使用哪种扇区缓冲区。当选择小缓冲区(1),数据内存的使用量将降低到每个文件对象512字节。在这种情况下,FatFS只使用一个扇区 缓冲区来进行文件数据传输以及FAT/目录访问。配置为小缓冲区的缺点是:每次文件数据传输时FAT数据缓冲都会丢失而必须从一个簇的边界开始重新载入数 据。不过从其体面的表现与少内存消耗这方面来考虑,这对于多数的应用也是合适的。
Figure 1 shows that partial sector data is transferred via the file I/O buffer. On long data transfer shown in Figure 2, middle of transfer data that covers one or more sector is transferred to application buffer directly. Figure 3 shows that the case of entier transfer data is aligned to the sector boundary. In this case, file I/O buffer is not used. On the direct transfer, the maximum extent of sectors are read with disk_read function at a time but the multi sector transfer never across the cluster boundary even if it is contiguous.
图表1显示扇区局部的数据通过文件I/O缓冲区来传输,图表2显示的长数据传输,中间的一或多个扇区的数据直接传输到应用程序缓冲区。图 表3显示的是在以扇区对齐的整块数据传输的情况下,不使用文件I/O缓冲区。在直接传输时disk_read函数一次会最大程度的读取更多的扇区,但是多 扇区传输不会跨越簇边界,就算它们是相邻的。
Therefore taking effort to sector aligned read/write accesss avoids buffered data transfer and the read/write performance will be improved. Besides the effect, cached FAT data will not be flushed by file data transfer on the tiny configuration so that it can achieve same performance as non tiny configuration with small memory footprint.
因此使用扇区对齐的方式来进行读写访问可以避免缓冲区数据传输,并且读写效率将被提升。除了效率以外,在tiny配置的情况下FAT快速缓存数据在文件数据传输时不会刷新,所以可以用小内存消耗来达到非tiny配置相同的性能。
临界段
When write operation to the FAT file system is interrupted due to any accidental failure, such as sudden blackout, incorrect disk removal and unrecoverable disk error, the FAT structure can be collapted. Following images shows the critical section on the FatFs module.
当对FAT文件系统的写操作由于默写意外而中断,如突然断电,不正确的磁盘移除或不可恢复的磁盘错误,FAT结构可以被毁坏。下面的图片显示了FatFs的临界段。
Figure 4. Long critical section | Figure 5. Minimized critical section |
An interruption in the red section can cause a cross link; as a result, the file/directory being changed may be lost. There is one or more possibility listed below when an interruption in the yellow section is occured.
红色区域的中断会导致一个交叉链接,结果,正在修改的文件/目录可能会丢失。而黄色区域中断可能导致的效果在下面列出:
- File data being rewrited is collapted. 正在重写的文件数据被毁坏
- A file being appended returns initial state. 正在添加内容的文件回到初始状态
- A file created as new is gone. 丢失新建的文件
- A file created as new or in overwritten remains with length of zero. 一个新建或覆盖的文件保持长度为0
- Efficiency of disk use gets worse due to lost chain. 因为丢失关联,磁盘的使用效率变坏。
Each case does not affect the files that not in write mode open. To minimize risk of data loss, the critical section can be minimized like shown in Figure 5 by minimizing the time that file is opened in write mode or using f_sync function properly.
在文件不是用写模式打开时,这些情况不会发生。为了最小化磁盘数据的丢失,临界段可以像图表5显示的那样最小化,通过最小化文件处于写模式打开的时间或者适当的使用f_sync函数。
文章评论(0条评论)
登录后参与讨论