FatFsモジュールは移植性に関して次の点を前提としています。
ポータブル・オーディオやデータ・ロガーなど、よくある用途ではTiny-FatFsで十分です。しかし、Tiny-FatFsはデフォルトではFAT32に対応していないので、使用できるディスクは2GB(FAT64で4GB)までという制約があります。_USE_FAT32オプションでFAT32がサポートされますが、コード・サイズが膨らみます。
フル機能のFatFsは、複数ファイルを高速アクセスする場合や、複数ドライブの対応が必要な場合に有効です。
| メモリ容量 | FATタイプ |
|---|---|
| <= 64MB | FAT12 |
| 128MB〜2GB | FAT16 |
| >= 4GB | FAT32 |
右の表にメモリ・カードの容量と規定のFATタイプ(SDメモリの場合)を示します。出荷時はこれらのFATタイプでフォーマットされていて、最大のパフォーマンスが出るようにデータ領域の境界が調整されています。したがって、PCでフォーマットするなどして規定と違うフォーマットになると書き込み性能が大幅に低下する場合があるので注意が必要です。
資源の限られた組み込みシステムで効率よくアクセスするためには、ファイル・アクセスの仕組みをある程度意識した使用が求められます。FatFsモジュールでは、ディスク上のファイル・データは f_read()内で次のような手順で読み出されます。
ここでファイルI/Oバッファとは、データ・セクタの一部を読み書きするための1セクタ長のバッファで、FatFsではそのファイル・オブジェクト内の、Tiny-FatFsではワークエリア内のバッファのことを指しています。
Tiny-FatFsでは、全てのデータ転送とFATやディレクトリへのアクセスをただ一つのセクタ・バッファで行っているため、データ転送によりFATのキャッシュが失われ、クラスタ境界を通過するたびにFATセクタを読み直す必要があります。FatFsの場合は、データ用バッファはFAT用とは別なので、FATセクタを読む頻度はTiny-FatFsの 1/341, 1/256 または 1/128で済みます(クラスタが連続している場合)。つまり、Tiny-FatFsは性能低下の代償を払ってRAM使用量を削減しているわけです。
転送領域のうちセクタ全体を含む部分は(図2)のようにファイルI/Oバッファを介さず、ディスクとの間で直接転送されます。完全なセクタ・アライメント・アクセスの場合(図3)は、ファイルI/Oバッファは全く使用されません。直接転送では、可能ならdisk_read()に複数セクタを指定して最大限のマルチ・セクタ転送が行われます。ただし、クラスタ境界をまたぐときは、たとえセクタが連続していたとしても転送は分割されます。
このように、極力セクタ・アライメント・アクセスになるように配慮すれば、無駄なデータ転送が減って性能が向上します。さらに、Tiny-FatFsではFATのキャッシュが生きるようになり、FatFsと同じ性能と省メモリ特性が同時に得られます。
ディスク上のFAT構造を操作している途中で、停電、不正なメディアの取り外し、回復不能なデータエラー等の障害が発生すると、更新が中途半端な状態で中断され、その結果としてFAT構造が破壊される可能性があります。次にFatFsモジュールにおけるクリチカル・セクションと、その間の障害により起きうるエラーの状態を示します。
赤で示したセクションを実行中に障害が発生した場合、クロスリンクが発生して操作対象のファイル・ディレクトリが失われる可能性があります。黄色で示したセクションを実行中に障害が発生した場合、つぎのうちいずれかまたは複数の結果が生じる可能性が考えられます。
いずれも書き込み中でないファイルには影響はありません。これらのクリチカル・セクションは、ファイルを書き込みモードで開いている時間を最小限にするか、f_sync()を適宜使用することで図5のように最小化することができます。
そして、これらの機能拡張を行うとそれだけ多くのリソースが要求されるようになり、このプロジェクトが対象としている8/16ビット・マイコンのシステムに載せられなくなってしまうという問題もあります(これが一番の問題かも知れません)。