272 lines
27 KiB
HTML
272 lines
27 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
||
|
<link rel="up" title="FatFs" href="../00index_e.html">
|
||
|
<link rel="alternate" hreflang="ja" title="Japanese" href="../ja/appnote.html">
|
||
|
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
|
||
|
<title>FatFs Module Application Note</title>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<h1>FatFs Module Application Note</h1>
|
||
|
<ol class="toc">
|
||
|
<li><a href="#port">How to Port</a></li>
|
||
|
<li><a href="#limits">Limits</a></li>
|
||
|
<li><a href="#memory">Memory Usage</a></li>
|
||
|
<li><a href="#reduce">Module Size Reduction</a></li>
|
||
|
<li><a href="#lfn">Long File Name</a></li>
|
||
|
<li><a href="#unicode">Unicode API</a></li>
|
||
|
<li><a href="#reentrant">Re-entrancy</a></li>
|
||
|
<li><a href="#dup">Duplicated File Access</a></li>
|
||
|
<li><a href="#fs1">Performance Effective File Access</a></li>
|
||
|
<li><a href="#fs2">Considerations on Flash Memory Media</a></li>
|
||
|
<li><a href="#critical">Critical Section</a></li>
|
||
|
<li><a href="#fs3">Extended Use of APIs</a></li>
|
||
|
<li><a href="#license">About FatFs License</a></li>
|
||
|
</ol>
|
||
|
<hr>
|
||
|
|
||
|
<div class="para" id="port">
|
||
|
<h3>How to Port</h3>
|
||
|
|
||
|
<h4>Basic considerations</h4>
|
||
|
<p>The FatFs module is assuming following conditions on portability.</p>
|
||
|
<ul>
|
||
|
<li>ANSI C<br>
|
||
|
The FatFs module is a middleware written in ANSI C (C89). There is no platform dependence, so long as the compiler is in compliance with ANSI C.</li>
|
||
|
<li>Size of integer types<br>
|
||
|
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 <tt>integer.h</tt>. This will not be a problem on most compilers. When any conflict with existing definitions is occured, you must resolve it with care.</li>
|
||
|
</ul>
|
||
|
|
||
|
<h4>System organizations</h4>
|
||
|
<p>The dependency diagram shown below is a typical configuration of the embedded system with FatFs module.</p>
|
||
|
<p><img src="../img/modules.png" width="580" height="280" alt="dependency diagram"></p>
|
||
|
|
||
|
<h4>Which function is required?</h4>
|
||
|
<p>You need to provide only low level disk I/O functions that required by FatFs module and nothing else. If a working disk module for the target is already existing, you need to write only glue functions to attach it to the FatFs module. If not, you need to port any other disk module or write it from scratch. Most of defined functions are not that always required. For example, disk write function is not required in read-only configuration. Following table shows which function is required depends on configuration options.</p>
|
||
|
<table class="lst2">
|
||
|
<tr><th>Function</th><th>Required when:</th><th>Note</th></tr>
|
||
|
<tr><td>disk_initialize<br>disk_status<br>disk_read</td><td>Always</td><td rowspan="5">Disk I/O functions.<br>Samples available in ffsample.zip.<br>There are many implementations on the web.</td></tr>
|
||
|
<tr><td>disk_write<br>get_fattime<br>disk_ioctl (CTRL_SYNC)</td><td>_FS_READONLY == 0</td></tr>
|
||
|
<tr><td>disk_ioctl (GET_SECTOR_COUNT)<br>disk_ioctl (GET_BLOCK_SIZE)</td><td>_USE_MKFS == 1</td></tr>
|
||
|
<tr><td>disk_ioctl (GET_SECTOR_SIZE)</td><td>_MAX_SS > 512</td></tr>
|
||
|
<tr><td>disk_ioctl (CTRL_ERASE_SECTOR)</td><td>_USE_ERASE == 1</td></tr>
|
||
|
<tr><td>ff_convert<br>ff_wtoupper</td><td>_USE_LFN >= 1</td><td>Unicode support functions.<br>Available in option/cc*.c.</td></tr>
|
||
|
<tr><td>ff_cre_syncobj<br>ff_del_syncobj<br>ff_req_grant<br>ff_rel_grant</td><td>_FS_REENTRANT == 1</td><td rowspan="2">O/S dependent functions.<br>Samples available in option/syscall.c.</td></tr>
|
||
|
<tr><td>ff_mem_alloc<br>ff_mem_free</td><td>_USE_LFN == 3</td></tr>
|
||
|
</table>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="limits">
|
||
|
<h3>Limits</h3>
|
||
|
<ul>
|
||
|
<li>FAT sub-types: FAT12, FAT16 and FAT32.</li>
|
||
|
<li>Number of open files: Unlimited, depends on available memory.</li>
|
||
|
<li>Number of volumes: Upto 10.</li>
|
||
|
<li>File size: Depends on FAT specs. (upto 4G-1 bytes)</li>
|
||
|
<li>Volume size: Depends on FAT specs. (upto 2T bytes at 512 bytes/sector)</li>
|
||
|
<li>Cluster size: Depends on FAT specs. (upto 64K bytes at 512 bytes/sector)</li>
|
||
|
<li>Sector size: Depends on FAT specs. (upto 4K bytes)</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="memory">
|
||
|
<h3>Memory Usage</h3>
|
||
|
<table class="lst2">
|
||
|
<tr><th></th><th>ARM7<small><br>32bit</small></th><th>ARM7<small><br>Thumb</small></th><th>CM3<small><br>Thumb-2</small></th><th>AVR</th><th>H8/300H</th><th>PIC24</th><th>RL78</th><th>V850ES</th><th>SH-2A</th><th>RX600</th><th>IA-32</th></tr>
|
||
|
<tr><td>Compiler</td><td>GCC</td><td>GCC</td><td>GCC</td><td>GCC</td><td>CH38</td><td>C30</td><td>CC78K0R</td><td>CA850</td><td>SHC</td><td>RXC</td><td>VC6</td></tr>
|
||
|
<tr><td>_WORD_ACCESS</td><td>0</td><td>0</td><td>0</td><td>1</td><td>0</td><td>0</td><td>0</td><td>1</td><td>0</td><td>1</td><td>1</td></tr>
|
||
|
<!-- *ARM *Thumb *CM3 *AVR *H8 *PIC24 *RL78 *V850ES *SH-2A *RX600 *IA-32 -->
|
||
|
<tr class="lst3"><td>text (Full, R/W)</td><td>10591</td><td>7119</td><td>6565</td><td>13240</td><td>10864</td><td>11619</td><td>13192</td><td>8031</td><td>8960</td><td>5977</td><td>7856</td></tr>
|
||
|
<tr> <td>text (Min, R/W)</td> <td>6671</td><td>4595</td><td>4293</td> <td>8512</td> <td>7232</td> <td>7674</td> <td>9033</td><td>5235</td><td>5768</td><td>3923</td><td>5129</td></tr>
|
||
|
<tr> <td>text (Full, R/O)</td> <td>4695</td><td>3121</td><td>2861</td> <td>6218</td> <td>5162</td> <td>5466</td> <td>6418</td><td>3799</td><td>3964</td><td>2847</td><td>3687</td></tr>
|
||
|
<tr> <td>text (Min, R/O)</td> <td>3523</td><td>2463</td><td>2275</td> <td>4558</td> <td>4058</td> <td>4212</td> <td>4948</td><td>2959</td><td>3096</td><td>2199</td><td>2857</td></tr>
|
||
|
<tr> <td>bss</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*2 + 2</td><td>V*4 + 2</td><td>V*2 + 2</td><td>V*2 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td></tr>
|
||
|
<tr> <td>Work area<br>(_FS_TINY == 0)</td><td>V*560 +<br>F*550</td><td>V*560 +<br>F*550</td><td>V*560 +<br>F*550</td><td>V*560 +<br>F*544</td><td>V*560 +<br>F*550</td><td>V*560 +<br>F*544</td><td>V*560 +<br>F*544</td><td>V*560 +<br>F*544</td><td>V*560 +<br>F*550</td><td>V*560 +<br>F*550</td><td>V*560 +<br>F*550</td></tr>
|
||
|
<tr><td>Work area<br>(_FS_TINY == 1)</td><td>V*560 +<br>F*36</td><td>V*560 +<br>F*36</td><td>V*560 +<br>F*36</td><td>V*560 +<br>F*32</td><td>V*560 +<br>F*36</td><td>V*560 +<br>F*32</td><td>V*560 +<br>F*32</td><td>V*560 +<br>F*36</td><td>V*560 +<br>F*36</td><td>V*560 +<br>F*36</td><td>V*560 +<br>F*36</td></tr>
|
||
|
</table>
|
||
|
<p>These are the memory usage on some target systems with following condition. The memory sizes are in unit of byte, <em>V</em> denotes number of volumes and <em>F</em> denotes number of open files. All samples are optimezed in code size.</p>
|
||
|
<pre>
|
||
|
FatFs R0.10 options:
|
||
|
_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 feature)
|
||
|
_FS_LABEL 0 (Disable volume label functions)
|
||
|
_VOLUMES V (Number of logical drives to be used)
|
||
|
_MULTI_PARTITION 0 (Single partition per drive)
|
||
|
_FS_REENTRANT 0 (Disable reentrancy)
|
||
|
_FS_LOCK 0 (Disable file lock control)
|
||
|
</pre>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="reduce">
|
||
|
<h3>Module Size Reduction</h3>
|
||
|
<p>Follwing table shows which API function is removed by configuration options for the module size reduction.</p>
|
||
|
<table class="lst2">
|
||
|
<tr><td rowspan="2">Function</td><td colspan="4">_FS_MINIMIZE</td><td colspan="2">_FS_READONLY</td><td colspan="2">_USE_STRFUNC</td><td colspan="3">_FS_RPATH</td><td colspan="2">_FS_LABEL</td><td colspan="2">_USE_MKFS</td><td colspan="2">_USE_FORWARD</td><td colspan="2">_MULTI_PARTITION</td></tr>
|
||
|
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>0</td><td>1</td><td>0 </td><td>1/2</td><td>0</td><td>1</td><td>2</td><td>0</td><td>1</td><td>0</td><td>1</td><td>0</td><td>1</td><td>0</td><td>1</td></tr>
|
||
|
<tr class="lst3"><td>f_mount</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_open</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_close</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_read</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_write</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_sync</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_lseek</td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_opendir</td><td></td><td></td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_closedir</td><td></td><td></td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_readdir</td><td></td><td></td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_stat</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_getfree</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_truncate</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_unlink</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_mkdir</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_chmod</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_utime</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_rename</td><td></td><td>x</td><td>x</td><td>x</td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_chdir</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_chdrive</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_getcwd</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_getlabel</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_setlabel</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_forward</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_mkfs</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_fdisk</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td>x</td><td></td></tr>
|
||
|
<tr><td>f_putc</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_puts</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_printf</td><td></td><td></td><td></td><td></td><td></td><td>x</td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
<tr><td>f_gets</td><td></td><td></td><td></td><td></td><td></td><td></td><td>x</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||
|
</table>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="lfn">
|
||
|
<h3>Long File Name</h3>
|
||
|
<p>The FatFs module has started to support long file name (LFN) at 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. To enable LFN feature, set <tt>_USE_LFN</tt> to 1, 2 or 3, and add a Unicode code conversion function <tt>ff_convert()</tt> and <tt>ff_wtoupper()</tt> to the project. The LFN feature requiers a certain working buffer in addition. The buffer size can be configured by <tt>_MAX_LFN</tt> corresponding to the available memory size. The size of long file name will reach up to 255 characters, so that the <tt>_MAX_LFN</tt> should be set to 255 for full featured LFN operation. If the size of working buffer is insufficient for the given file name, the file function fails with <tt>FR_INVALID_NAME</tt>. When enable the LFN feature with re-entrant feature, <tt>_USE_LFN</tt> must be set to 2 or 3. In this case, the file function allocates the working buffer on the stack or heap. The working buffer occupies <tt>(_MAX_LFN + 1) * 2</tt> bytes.</p>
|
||
|
<table class="lst2 rset">
|
||
|
<caption>LFN cfg on ARM7TDMI</caption>
|
||
|
<tr><th>Code page</th><th>Program size</th></tr>
|
||
|
<tr><td>SBCS</td><td>+3.7K</td></tr>
|
||
|
<tr><td>932(Shift-JIS)</td><td>+62K</td></tr>
|
||
|
<tr><td>936(GBK)</td><td>+177K</td></tr>
|
||
|
<tr><td>949(Korean)</td><td>+139K</td></tr>
|
||
|
<tr><td>950(Big5)</td><td>+111K</td></tr>
|
||
|
</table>
|
||
|
<p>When the LFN feature is enabled, the module size will be increased depends on the selected code page. Right table shows how many bytes increased when LFN feature is enabled with some code pages. Especially, in the CJK region, tens of thousands of characters are being used. 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 feature with those code pages will not able to be implemented to most 8-bit microcontrollers.</p>
|
||
|
<p>Note that the LFN feature on the FAT file system is a patent of Microsoft Corporation. This is not the case on FAT32 but most FAT32 drivers come with the LFN feature. FatFs can swich the LFN feature off by configuration option. When enable LFN feature on the commercial products, a license from Microsoft may be required depends on the final destination.</p>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="unicode">
|
||
|
<h3>Unicode API</h3>
|
||
|
<p>By default, FatFs uses ANSI/OEM code set on the API under LFN configuration. FatFs can also switch the character encoding to Unicode on the API (<tt>_LFN_UNICODE</tt>). This means the FatFs supports the True-LFN feature. For more information, refer to the description in the <a href="filename.html">file name</a>.</p>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="reentrant">
|
||
|
<h3>Re-entrancy</h3>
|
||
|
<p>The file operations to the different volume is always re-entrant and can work simultaneously. The file operations to the same volume is not re-entrant but it can also be configured to thread-safe with <tt>_FS_REENTRANT</tt> option. In this case, also the OS dependent synchronization object control functions, <tt>ff_cre_syncobj(), ff_del_syncobj(), ff_req_grant() and ff_rel_grant()</tt> must be added to the project.</p>
|
||
|
<p>When a file function is called while the volume is in use by any other task, the file function is suspended until that task leaves file function. If wait time exceeded a period defined by <tt>_TIMEOUT</tt>, the file function will abort with <tt>FR_TIMEOUT</tt>. The timeout feature might not be supported by some RTOS.</p>
|
||
|
<p>There is an exception for <tt>f_mount(), f_mkfs(), f_fdisk()</tt> function. These functions are not re-entrant to the same volume or corresponding physical drive. When use these functions, all other tasks must unmount the volume and avoid to access the volume.</p>
|
||
|
<p>Note that this section describes on the re-entrancy of the FatFs module itself but also the low level disk I/O layer will need to be re-entrant.</p>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="dup">
|
||
|
<h3>Duplicated File Access</h3>
|
||
|
<p>FatFs module does not support the shareing controls of duplicated file access in default. It is permitted when open method to a file is only read mode. The duplicated open in write mode to a file is always prohibited and open file must not be renamed, deleted, or the FAT structure on the volume can be collapted.</p>
|
||
|
<p>The file shareing control can also be available when <tt>_FS_LOCK</tt> is set to 1 or grater. The value specifies the number of files to manage simultaneously. In this case, if any open, rename or remove that violating the file shareing rule that described above is attempted, the file function will fail with <tt>FR_LOCKED</tt>. If number of open objects gets larger than <tt>_FS_LOCK</tt>, the <tt>f_open()/f_opendir()</tt> function will fail with <tt>FR_TOO_MANY_OPEN_FILES</tt>.</p>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="fs1">
|
||
|
<h3>Performance Effective File Access</h3>
|
||
|
<p>For good performance to read/write files on the small embedded system, application programmer should consider what process is done in the FatFs module. The file data on the volume is transferred in following sequence by <tt>f_read()</tt> function.</p>
|
||
|
<p>Figure 1. Sector miss-aligned read (short)<br>
|
||
|
<img src="../img/f1.png" width="490" height="110" alt="">
|
||
|
</p>
|
||
|
<p>Figure 2. Sector miss-aligned read (long)<br>
|
||
|
<img src="../img/f2.png" width="490" height="140" alt="">
|
||
|
</p>
|
||
|
<p>Figure 3. Sector aligned read<br>
|
||
|
<img src="../img/f3.png" width="490" height="119" alt="">
|
||
|
</p>
|
||
|
<p>The file I/O buffer is 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 in the file system object. The buffer configuration option <tt>_FS_TINY</tt> 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 in 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.</p>
|
||
|
<p>Figure 1 shows that a partial sector, sector mis-aligned part of the file, 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 the 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 <tt>disk_read()</tt> function at a time but the multiple sector transfer never across the cluster boundary even if it is contiguous.</p>
|
||
|
<p>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 at the tiny configuration, so that it can achieve same performance as non-tiny configuration with small memory footprint.</p>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="fs2">
|
||
|
<h3>Considerations on Flash Memory Media</h3>
|
||
|
<p>To maximize the write performance of flash memory media, such as SDC and CFC, it must be controlled in consideration of its characteristitcs.</p>
|
||
|
<h4>Using Mutiple-Sector Write</h4>
|
||
|
<div class="rset">
|
||
|
Figure 6. Comparison between Multiple/Single Sector Write<br>
|
||
|
<img src="../img/f6.png" width="630" height="148" alt="fig.6">
|
||
|
</div>
|
||
|
<p>The write throughput of the flash memory media becomes the worst at single sector write and it increases proportional to the number of sectors per a write transaction. This effect more appers at more fast bus clock and its ratio often becomes grater than ten. The number of write transaction also affects the life time of the media. Therefore the application program should write the data in large block as possible. The ideal block size is cluster size or power of 2 bytes and the byte offset should be aligned to the block. Of course all layers between the application and the media must support multiple sector write feature, however most of open-source disk drivers lack it. Do not split a multiple sector write request into single sector writes or the write throughput gets poor. Note that FatFs module and its sample disk drivers supprt multiple sector read/write feature.</p>
|
||
|
<h4>Forcing Memory Erase</h4>
|
||
|
<p>When remove a file with <tt>f_remove()</tt> function, the data clusters occupied by the file are marked 'free' on the FAT. But the data sectors containing the file data are not that applied any process, so that the file data left occupies a part of the flash memory array as 'live block'. If the file data is forced erased on removing the file, the number of free blocks on the flash memory will be increased. This may skip internal block erase operation to the data block on next write. As the result the write performance might be improved. To enable this feature, set <tt>_USE_ERASE</tt> to 1. Note that this is a feature with expectation of internal process of the flash memory media. It may not always effective and <tt>f_remove()</tt> function will take a time to remove a large file. Most applications will not need this feature.</p>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="critical">
|
||
|
<h3>Critical Section</h3>
|
||
|
<p>If a write operation to the FAT volume is interrupted due to any accidental failure, such as sudden blackout, incorrect disk removal and unrecoverable disk error, the FAT structure on the volume can be collapted. Following images shows the critical section of the FatFs module.</p>
|
||
|
<div class="lset">
|
||
|
Figure 4. Long critical section<br>
|
||
|
<img src="../img/f4.png" width="320" height="436" alt="fig.4">
|
||
|
</div>
|
||
|
<div class="lset">
|
||
|
Figure 5. Minimized critical section<br>
|
||
|
<img src="../img/f5.png" width="320" height="436" alt="fig.5">
|
||
|
</div>
|
||
|
<br class="clr">
|
||
|
<p>An interruption in the red section can cause a cross link; as a result, the object being changed can be lost. If an interruption in the yellow section is occured, there is one or more possibility listed below.</p>
|
||
|
<ul>
|
||
|
<li>The file data being rewrited is collapted.</li>
|
||
|
<li>The file being appended returns initial state.</li>
|
||
|
<li>The file created as new is gone.</li>
|
||
|
<li>The file created as new or overwritten remains but no content.</li>
|
||
|
<li>Efficiency of disk use gets worse due to lost clusters.</li>
|
||
|
</ul>
|
||
|
<p>Each case does not affect the files that not opened in write mode. To minimize risk of data loss, the critical section can be minimized by minimizing the time that file is opened in write mode or using <tt>f_sync()</tt> function as shown in Figure 5.</p>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="fs3">
|
||
|
<h3>Extended Use of APIs</h3>
|
||
|
<p>These are examples of extended use of FatFs APIs. New item will be added whenever a useful code is found.</p>
|
||
|
<ol>
|
||
|
<li><a href="../img/app1.c">Open or create a file for append</a></li>
|
||
|
<li><a href="../img/app2.c">Empty a directory</a></li>
|
||
|
<li><a href="../img/app3.c">Allocate contiguous area to the file</a></li>
|
||
|
</ol>
|
||
|
</div>
|
||
|
|
||
|
<div class="para" id="license">
|
||
|
<h3>About FatFs License</h3>
|
||
|
<p>This is a copy of the FatFs license document that included in the source codes.</p>
|
||
|
<pre>/*----------------------------------------------------------------------------/
|
||
|
/ FatFs - FAT file system module R0.10 (C)ChaN, 2013
|
||
|
/-----------------------------------------------------------------------------/
|
||
|
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||
|
/ This is a free software that opened for education, research and commercial
|
||
|
/ developments under license policy of following trems.
|
||
|
/
|
||
|
/ Copyright (C) 2013, ChaN, all right reserved.
|
||
|
/
|
||
|
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||
|
/ * No restriction on use. You can use, modify and redistribute it for
|
||
|
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||
|
/ * Redistributions of source code must retain the above copyright notice.
|
||
|
/
|
||
|
/-----------------------------------------------------------------------------/</pre>
|
||
|
<p>Therefore FatFs license is one of the BSD-style license but there is a significant feature. Because FatFs is for embedded projects, the conditions for redistributions in binary form, such as embedded code, hex file and binary library, are not specified to increase its usability. The documentation of the distributions need not include about FatFs and its license document, and it may also. This is equivalent to the BSD 1-Clause License. Of course FatFs is compatible with the projects under GNU GPL. When redistribute the FatFs with any modification, the license can also be changed to GNU GPL or BSD-style license.</p>
|
||
|
</div>
|
||
|
|
||
|
<p class="foot"><a href="../00index_e.html">Return</a></p>
|
||
|
</body>
|
||
|
</html>
|