FatFS/doc/ja/appnote.html
savelij13 3d65978d31 fatfs v0.04 Feb 04, 2007:
- Supported multiple drive system.
- Changed some APIs for multiple drive system.
- Added f_mkfs().
2025-09-11 09:03:34 +03:00

109 lines
8.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFsモジュール アプリケーション・ノート</title>
</head>
<body>
<h1>FatFsモジュール アプリケーション・ノート (for R0.04)</h1>
<hr>
<div class="para">
<h3>移植の際に配慮すべきこと</h3>
<p>FatFsモジュールは移植性に関して次の点を前提としています。</p>
<ul>
<li>処理系はANSI C準拠であること。<br>
FatFsモジュールはANSI C準拠で記述されているので、ANSI C準拠のコンパイラなら特に処理系依存な点はありません。ただし、FATというシステム間でポータブルな構造体を操作するため、プロセッサのエンディアンの違いは意識する必要があります。これは ff.h(tff.h) で定義されているので、最初にこれを適切に設定します(忘れている場合はエラーを出す)。</li>
<li>char/short/long のサイズは、それぞれ 8/16/32ビットであること。<br>
整数の型とサイズに関してはまっとうなコンパイラなら問題ないと思います。integer.h内の typedefと既存の定義が衝突した場合は矛盾がないように注意しなければなりません。</li>
</ul>
</div>
<div class="para">
<h3>FatFs vs. Tiny-FatFs</h3>
<p>ポータブル・オーディオやデータ・ロガーなど、よくある用途ではTiny-FatFsで十分です。しかし、Tiny-FatFsはデフォルトではFAT32に対応していないので、使用できるディスクは2GB(FAT64で4GB)までという制約があります。<tt>_USE_FAT32</tt>オプションでFAT32がサポートされますが、コード・サイズが膨らみます。</p>
<p>フル機能のFatFsは、複数ファイルを高速アクセスする場合や、複数ドライブの対応が必要な場合に有効です。</p>
<div class="rset">
<table class="lst2">
<tr><th>メモリ容量</th><th>FATタイプ</th></tr>
<tr><td>&lt;= 64MB</td><td>FAT12</td></tr>
<tr><td>128MB2GB</td><td>FAT16</td></tr>
<tr><td>&gt;= 4GB</td><td>FAT32</td></tr>
</table>
</div>
<p>右の表にメモリ・カードの容量と規定のFATタイプ(SDメモリの場合)を示します。出荷時はこれらのFATタイプでフォーマットされていて、最大のパフォーマンスが出るようにデータ領域の境界が調整されています。したがって、PCでフォーマットするなどして規定と違うフォーマットになると書き込み性能が大幅に低下する場合があるので注意が必要です。</p>
</div>
<div class="para">
<h3>効率の良いファイル・アクセスの方法</h3>
<p>資源の限られた組み込みシステムで効率よくアクセスするためには、ファイル・アクセスの仕組みをある程度意識した使用が求められます。FatFsモジュールでは、ディスク上のファイル・データは f_read()内で次のような手順で読み出されます。</p>
<div class="lset">図1. セクタ・ミスアライメント・リード<br>
<img src="../img/f1.png" width="490" height="73" alt="fig.1">
</div>
<br class="clr">
<div class="lset">図2. セクタ・ミスアライメント・リード<br>
<img src="../img/f2.png" width="490" height="140" alt="fig.2">
</div>
<br class="clr">
<div class="lset">図3. セクタ・アライメント・リード<br>
<img src="../img/f3.png" width="490" height="119" alt="fig.3">
</div>
<br class="clr">
<p>ここでファイルI/Oバッファとは、データ・セクタの一部を読み書きするための1セクタ長のバッファで、FatFsではそのファイル・オブジェクト内の、Tiny-FatFsではワークエリア内のバッファのことを指しています。</p>
<p>Tiny-FatFsでは、全てのデータ転送とFATやディレクトリへのアクセスをただ一つのセクタ・バッファで行っているため、データ転送によりFATのキャッシュが失われ、クラスタ境界を通過するたびにFATセクタを読み直す必要があります。FatFsの場合は、データ用バッファはFAT用とは別なので、FATセクタを読む頻度はTiny-FatFsの 1/341, 1/256 または 1/128で済みます(クラスタが連続している場合)。つまり、Tiny-FatFsは性能低下の代償を払ってRAM使用量を削減しているわけです。</p>
<p>転送領域のうちセクタ全体を含む部分は(図2)のようにファイルI/Oバッファを介さず、ディスクとの間で直接転送されます。完全なセクタ・アライメント・アクセスの場合(図3)は、ファイルI/Oバッファは全く使用されません。直接転送では、可能ならdisk_read()に複数セクタを指定して最大限のマルチ・セクタ転送が行われます。ただし、クラスタ境界をまたぐときは、たとえセクタが連続していたとしても転送は分割されます。</p>
<p>このように、極力セクタ・アライメント・アクセスになるように配慮すれば、無駄なデータ転送が減って性能が向上します。さらに、Tiny-FatFsではFATのキャッシュが生きるようになり、FatFsと同じ性能と省メモリ特性が同時に得られます。</p>
</div>
<div class="para">
<h3>クリチカル・セクション</h3>
<p>ディスク上のFAT構造を操作している途中で、停電、不正なメディアの取り外し、回復不能なデータエラー等の障害が発生すると、更新が中途半端な状態で中断され、その結果としてFAT構造が破壊される可能性があります。次にFatFsモジュールにおけるクリチカル・セクションと、その間の障害により起きうるエラーの状態を示します。</p>
<div class="lset">
図4. 長いクリチカル・セクション<br>
<img src="../img/f4.png" width="320" height="470" alt="fig.4">
</div>
<div class="lset">
図5. 短くしたクリチカル・セクション<br>
<img src="../img/f5.png" width="320" height="470" alt="fig.5">
</div>
<br class="clr">
<p>赤で示したセクションを実行中に障害が発生した場合、クロスリンクが発生して操作対象のファイル・ディレクトリが失われる可能性があります。黄色で示したセクションを実行中に障害が発生した場合、つぎのうちいずれかまたは複数の結果が生じる可能性が考えられます。</p>
<ul>
<li>書き換え中のファイルのデータ構造が破壊される。</li>
<li>追記中のファイルがオープン前の状態に戻る。</li>
<li>新規に作成されたファイルが消える。</li>
<li>新規に作成されたファイルの長さがゼロになって残る。</li>
<li>上書きで作成されたファイルの長さがゼロになって残る。</li>
<li>上書きで作成されたファイルが作成前の状態に戻る。</li>
<li>ロストチェーンの発生によりディスクの利用効率が悪化する。</li>
</ul>
<p>いずれも書き込み中でないファイルには影響はありません。これらのクリチカル・セクションは、ファイルを書き込みモードで開いている時間を最小限にするか、f_sync()を適宜使用することで図5のように最小化することができます。</p>
</div>
<div class="para">
<h3>現リビジョンの問題点とその改善案</h3>
<ul>
<li>ファイル・オブジェクトの抽象化<br>
現在はファイル・オブジェクトの実体をアプリケーション側で管理しているので、アプリケーション・モジュールでのスタック消費量が多くなります(Tiny-FatFsでは問題にはならない)。これをハンドルで管理するなどより抽象化すればアプリケーション・モジュールでのスタック消費量を減らせます。この場合、FatFs内でファイル・オブジェクトの領域を静的に確保しておくか、malloc()することになります。ただし、このようにするとファイル・オブジェクトを直接参照できなくなり、feofやftellなどムダな関数が新たに必要になります。</li>
<li>セクタ・バッファ管理の改善<br>
現在はセクタ・バッファを固定して使用しているため、無駄なディスクアクセスが多く効率が悪い。メモリの潤沢なシステムでは、複数のセクタ・バッファを使用してディスク・キャッシュを構成すれば性能を向上させることができます。</li>
<li>FSInfoへの対応<br>
FAT32ではその膨大なクラスタ数のため、ファイル新規作成や空きスペース取得時のクラスタ・サーチにかなりの時間を要します。このため、最終割り当てクラスタ番号や残りクラスタ数がFSInfoセクタに記録されていて、延々とクラスタ・サーチするのを避けられるようになっています。現在はFSInfoに未対応なので、空きスペース取得時や、ディスク使用量が多い状態でのファイル作成(作成後の最初の書き込み)処理時間は問題になるレベルです。</li>
<li>長いファイル名への対応<br>
FATの拡張仕様では従来の8.3形式ファイル名に加え、255文字までの長いファイル名を扱えるようになっていますが、現リビジョンでは未対応で8.3形式しか使用できません。これに対応するには、ファイル名だけでも500バイト以上のバッファが必要になったり、UCS-2とShift_JISの相互変換(巨大な変換テーブル)が必要となるなど、メモリの消費が爆発的に増えてしまいます。なお、長いファイル名の機能はMicrosoft社の特許になっているため、これを製品に使うにはライセンス契約が必要です。</li>
<li>RTOSへの対応<br>
FatFsモジュールを使用するタスクを一つに限るなら特に意識する必要はありませんが、複数のタスクから使用するには、何らかの排他制御が必要になってきます。FatFsモジュールのRTOSへの対応作業は、<a href="http://www.toppers.jp/">TOPPERSプロジェクト</a>で行われています。</li>
</ul>
<br>
<p>そして、これらの機能拡張を行うとそれだけ多くのリソースが要求されるようになり、このプロジェクトが対象としている8/16ビット・マイコンのシステムに載せられなくなってしまうという問題もあります(これが一番の問題かも知れません)。</p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>