# FatFs Module Application Note

### Considerations on porting to various platform

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. However it handles the system portable FAT structures. You must take the endian into consideration. This setting is defined in ff.h (tff.h). It must be changed for your platform first or the compiler will abort with an error.
- 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 of the definitions between the integer.h and existing definitions is occured, you must resolve the confrict with care.

### Memory Usage (R0.06)

These are the memory usage on some target systems. The memory sizes are in unit of byte, D means number of logical drives and F means number of open files. All samples are optimezed in code size.

| AVR | H8/300H | PIC | MSP430 | TLCS-870/C | V850ES | SH2
--- | --- | --- | --- | --- | --- | --- | ---
Compiler | WinAVR(gcc) | CH38 | C30(gcc) | CL430 | CC870C | CA850 | SHC
_MCU_ENDIAN | 1 | 2 | 2 | 2 | 1 | 1 | 2
FatFs Code (Full, R/W) | 9280 | 9348 | 9387 |  |  | 6728 | 7538
FatFs Code (Minimum, R/W) | 5814 | 5798 | 5913 |  |  | 4094 | 4742
FatFs Code (Full, R/O) | 4402 | 4236 | 4371 |  |  | 3054 | 3474
FatFs Code (Minimum, R/O) | 3066 | 3158 | 3213 |  |  | 2172 | 2630
FatFs Work (Static) | D*2+2 | D*4+2 | D*2+2 |  |  | D*4+2 | D*4+2
FatFs Work (Dynamic) | D*554+F*544 | D*554+F*550 | D*554+F*544 |  |  | D*554+F*550 | D*554+F*550
Tiny-FatFs Code (Full, R/W) | 7628 | 7668 | 7560 | 7108 | 9501 | 5978 | 6640
Tiny-FatFs Code (Minimum, R/W) | 4684 | 4820 | 4698 | 4390 | 6322 | 3678 | 4236
Tiny-FatFs Code (Full, R/O) | 3634 | 3600 | 3618 | 3382 | 4554 | 2722 | 3072
Tiny-FatFs Code (Minimum, R/O) | 2524 | 2700 | 2601 | 2398 | 3390 | 1862 | 2300
Tiny-FatFs Wrok (Static) | 4 | 6 | 4 | 4 | 4 | 6 | 6
Tiny-FatFs Work (Dynamic) | 544+F*28 | 544+F*32 | 544+F*28 | 544+F*28 | 544+F*28 | 544+F*32 | 544+F*32

### FatFs vs. Tiny-FatFs

For most applications, such as portable audio and data logger, Tiny-FatFs is the best choice. However because the Tiny-FatFs does not support FAT32 in default, there is a limitation that can handle only tiny storage upto 2GB(4GB in FAT64). The FAT32 support can be added by `_USE_FAT32` option with an additional code size. The FatFs is suitable for fast multiple files access, and for multiple drive system.

Memory Size | FAT Type
--- | ---
<= 64MB | FAT12
128MB - 2GB | FAT16
>= 4GB | FAT32

Rignt table shows the correspondence between memory size and FAT type for SD memroy card and they are shipped with this format. The data area is justified to the erase block boundary and the memory card works with the best performance. For that reason, the memory card should not be reformated with PC. When cluster size or FAT type is changed, the write performance can be decreased.

### Performance effective file access

For good performance on reading/writing files on the small embedded system, application program should consider what process is done in the FatFs module. The file data on the disk is transferred by f_read function in these sequence.

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. On the FatFs, member buffer[] in the file object is used. On the Tiny-FatFs, member win[] in the file system object is used.

Tiny-FatFs processes all file data transfer and access to the FAT/directory with only one sector buffer, so that FAT sector cached into the buffer is lost and it must reloaded at every cluster boundary. FatFs has a FAT/directory buffer separated from file I/O buffer, the frequency of FAT accesses is only 1/341, 1/256 or 1/128 (when cluster is contiguous) compared to Tiny-FatFs. Thus the Tiny-FatFs is sacrificing its performance in compensation for very small memory footprint.

Figure 1 shows that partial sector data is transferred via the file I/O buffer. At long data transfer shown in Figure 2, middle of transfer data that aligned to sector boundary is transferred into memory directly. Figure 3 shows that entier transfer data is aligned to the sector boundary. In this case, file I/O buffer is not used. At the unbuffered transfer, maximum extent of sectors are read with disk_read function at a time but it never across cluster boundary even if it is contiguous.

Therefore taking effort to sector aligned read/write accesss eliminates memcpy and the read/write performance will be improved. Besides the effect, cached FAT sector is not flushed during read/write access on the Tiny-FatFs, so that it can achieve same performance as FatFs and its small memory footprint simultanesously.

### Critical section

When write operation to the FAT file system is interrupted due to any accidental failure, such as sudden blackout, incorrect disk removal and unrecoverable data error, the FAT structure can be destroyed. Following images shows the critical section on the FatFs module.

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 will 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.
- Efficiency of disk use gets worse due to lost chain.

Each case does not affect the files that not in write operation. 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 and using f_sync function properly.

### Problems and Ideas

- Abstraction of file object
  Currently the file object structure is held by application layer. This is not a problem for Tiny-FatFs, it consumes the task stack only 26 bytes per file. But FatFs requires 550 bytes per file. When managed the file objects in file handle, stack consumption at application module will able to be reduced. In this case, the work area for file objects is managed in FatFs module. This has a disadvantage that direct access to the file object structure cannot be used and additional file functions, such as feof and ftell, will be needed.
- Efficient sector buffer management
  The FatFs module has only one sector buffer per logical drive. There is an ineffciency on random file access with many files simultanesously. When additional memory for the sector buffer is available, the file access performance will able to be improved with an advanced cache mechanism.
- Long file name
  There is an extended feature to handle long file name (LFN) up to 255 characters, in addition to 8.3 format file name, on FAT file system. To support this, 512 byte string buffer for file name and UCS-2 - Shift_JIS mutual conversion table are required. Therefore memory consumption of code and work area will be increased drastically. The FatFs module does not support this feature. The LFN on the FAT file system is a patent of Microsoft. When support it on the commercial products, you have to be licensed.
- Porting to RTOS
  When use FatFs module from only one task, no consideration is needed. However when make access to a logical drive from two or more tasks simultanesously, any exclusion control will be required. The FatFs module is also ported to a free RTOS based on μITRON by TOPPERS Project.

These are the problems and ideas on current revision of FatFs module. However the main target of FatFs module is 8 bit microcontrollers. These extensions requires much resource and the FatFs will unable to be ported to the 8 bit system. This may be the most serious problem on future plan.

Return