HOME > ソフテックだより > 第421号(2023年3月1日発行) 技術レポート「組み込みソフト向けFATファイルシステムについて」

「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。

ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ


ソフテックだより 第421号(2023年3月1日発行)
技術レポート

「組み込みソフト向けFATファイルシステムについて」

1. はじめに

近年、SDカードやUSBフラッシュドライブなどの持ち運び可能な外部ストレージにアクセス可能な電子機器が増えてきました。
昔は外部ストレージアクセスのI/Fを持っていない電子機器に対してデータの読み書きを行う場合、専用のアプリケーションを使用して専用のI/F(通信など)を経由してアクセスを行う必要がありましたが、外部ストレージアクセスのI/Fを持っていれば、外部ストレージ経由で機器間のファイルのやり取りを行うことができます。

機器間でファイルをやりとりする場合、共通のファイルシステム(記憶装置にデータを書き込む際の管理方式のこと)を使用する必要があり、FATファイルシステムが広く普及しています。FATは、シンプルな構造で各種OSと互換性があるため、様々なデバイスやプラットフォームで使用されています。

組み込みソフトでFAT形式のファイルを扱うには、FATファイルシステムのミドルウェアを組み込む必要があります。また、FATファイルシステムの他にも、使用する外部ストレージデバイス用のデバイスドライバが必要となります。

2. M3S-TFAT-Tinyについて

FATファイルシステムは自作することも可能ですが、すでに開発されているFATファイルシステムを使用するケースがほとんどだと思います。無償で提供されているものもあれば、有償のものもあります。

弊社でも最近、SDカードアクセスの組み込みソフト開発(以下、「今回の開発」)を行いましたが、ターゲットCPUがルネサス エレクトロニクス株式会社(以下、Renesas)のRXファミリだったこともあり、同RenesasのRXファミリ用FATファイルシステム[M3S-TFAT-Tiny]を使用しました。M3S-TFAT-TinyはRXファミリ用の他に、RL78ファミリ用やV850ファミリ用もあります。
M3S-TFAT-Tinyですが、オープンソースのFatFs(*1)をベースに作成されたFATファイルシステムで、FatFs自体は別の開発でも使用したことのあるFATファイルシステムでした。
また、使用したRXファミリのCPUには、SDホストインタフェース(SDHI)の機能が内蔵されており、その機能を使用するためのドライバソフトも必要になりますが、こちらもRenesasから無償で提供されているSDメモリカードドライバとSDHIモジュールを使用しました。使用したモジュールの構成図を図 1に示します。

モジュール構成図
図1. モジュール構成図

ハードウェア仕様に合わせてコード変更は必要ですが、ほぼ提供されたコードそのままで使用することができ、特にこれまで問題も発生していません。

3.  効率のよいファイルアクセスについて

組み込みソフトで効率よくファイルアクセスするにはFATファイルシステムの内部動作を考慮したファイル操作が必要になります。
また、同様に外部ストレージデバイスの仕様動作を考慮したデバイスドライバの調整・変更も必要になる場合もあります。

今回の開発時に検討した内容の一部になりますが、表 1にファイルアクセス効率化の検討事項を紹介します。FATファイルシステムはM3S-TFAT-Tiny(FatFs)、外部ストレージはSDカードを前提としています。
なお、検討した結果、対応を見送った内容もありますので、その点はご了承ください(理由は記載しています)。

表1.  ファイルアクセス効率化の検討事項一覧

対応箇所 項目 内容
アプリケーション ブロック転送 一般的にストレージはセクタ単位(512バイト)でしか読み書きできないため、1セクタ単位未満のサイズでのアクセスは効率が悪い。
そのため、アドレスの512の倍数までのデータが内部バッファに溜まったときに書き込みを行う。
内部バッファに溜まるまでの間にカード抜けなどが行われるとそのデータの書き込みは行われないので、一定時間(例えば1秒)、内部バッファへの追加がなかったときも書き込みを行う。
アプリケーション データのフラッシュ

ディスク上のFAT構造を操作している最中に突然の電源断が起きた場合、処理が中途半端な状態で中断され、その結果としてFAT構造が破壊され、データが失われる可能性がある。
対策として、ファイル書き込み(FatFsのf_write関数)の実行後、続けてキャッシュされたデータのフラッシュ(FatFsのf_sync関数)を行うことで、突然の電源断により失われるデータを最小にすることができる。

この他にも電源OFF監視による電源断対策も検討したが、ハード的にコンデンサ容量が不足していたことや、ログファイルなどの定常的にファイル書き込みを行うシステムではなかったため、本対策のみ実施。

アプリケーション クラスタ・プリ・アロケーション 書き込み前に、ファイルを最大サイズまで拡大しておくことで、空きクラスタの検索やチェーン延長のタイミングを減らす方法。
ただし、最大サイズに拡大したとき、拡大エリアのデータは不定データとなってしまうため、途中のカード抜けを考慮して今回の開発では対応を見送り。
アプリケーション/SDカードドライバ マルチブロックリード/マルチブロックライト SDカードからの読み込みは、1度に2セクタ以下の読み込みの場合はシングルブロックリードで読み込みを行い、3セクタ以上の読み込みの場合はマルチブロックリードで読み込みを行うのが効率良い。書き込み時のシングルブロックライトとマルチブロックライトも同じ。
RenesasのSDカードドライバでは、データサイズに応じた使い分けが行われているため、SDカードドライバ側の追加対応は不要だが、マルチブロックリード/マルチブロックライトを有効に使うためには、アプリケーション側で1度に複数セクタを読み書きする対応が必要。
FATファイルシステム/SDカードドライバ データ領域のプリ消去 SDカードでは、ブランク・ブロックへの書き込みが最大書き込み速度となる。そこで、書き込むデータ領域をあらかじめ消去しておく方法。
FatFsのdefine定義および、RenesasのSDカードドライバを1行コード変更することでプリ消去に対応可能。
ただし、RenesasのSDカードドライバのアプリケーションノートに、「ライト処理中にSDカードの抜去が発生した場合、通常書き込み設定時と比べ、SDメモリのデータが失われる可能性が高くなります。」の記載があるため、安全性を重視して今回の開発では対応を見送り。
SDカードドライバ データ転送 DMAC/DTCを使用したデータ転送を行うことで、ソフトウェア処理の負荷を下げることが可能。
今回の開発では、別のバスでDMAC/DTCを使用しており、SDカードでDMAC/DTCを使おうとした場合にバス解放待ちが発生してしまうため、DMAC/DTCを使用したデータ転送の対応は見送り、ソフトウェア転送(プログラムでデータコピーを行う)で対応。

4. RTOSなしで動作させるときの注意点

ファイルシステムは、ファイルの読み書きが完了するまでFATファイルシステムのAPIコールから返ってこないいわゆるブロッキング仕様のものが多いです。それは、RTOSなしに対応したFATファイルシステムを謳っているM3S-TFAT-Tinyでも同様でした。つまり、これはAPIコール中に、他の処理がまわらなくなってしまうことを意味します。
システムとしてファイルの読み書きが完了するまで特にその他の処理は行わなくても良い仕様であれば特に問題ありませんが、そうではない場合は対策が必要となります。
そのため、通常は、RTOSを使用するのが定石となりますが、以下のような理由で今回の開発ではRTOSなしを選択しました。

  • ベースソフトがRTOSなしであったこと。
  • FATファイルシステムがRTOSなしで使えるのであれば、その他にRTOSが必須な機能はないこと。
  • RTOSを使用する場合、ROM/RAMのリソースを消費すること。

そこで、今回はRTOSなしで動作させる場合の注意点を上げたいと思います。

その具体的な対策方法は、メイン処理とFATファイルシステム処理を別のタイマ割り込み上で動作させて非同期処理にすることです。これによって、RTOSなしでも、FATファイルシステムのAPIコール待ちによる影響をなくすことができます。
図 2に各処理の相関図、表 2に各処理の説明を示します。

RTOSなし時の各処理の相関図
図2. RTOSなし時の各処理の相関図

表2.  RTOSなし時の各処理の説明

処理 内容
リセット割り込み リセットによりプログラムが起動し、初期化処理実行後、タイマ割り込み1とタイマ割り込み2を起動し、以降はループする。必要に応じてスリープモードに遷移させる(割り込み要因発生でスリープモード解除)。
タイマ割り込み1:
メイン処理定期実行タイマ割り込み
通常のメイン処理。
ファイルの読み書きの管理も行っており、読み書きの要求があった時はタイマ割り込み2に対してFATアクセス要求(オープン/クローズ/書き込み/読み込みなど)を行う。タイマ割り込み2は非同期にFAT処理を行うため、FATアクセス要求後は定期的にFATアクセス結果を確認する。
タイマ割り込み2:
FAT処理定期実行タイマ割り込み
FATファイルシステム処理。
タイマ割り込み1より割り込み優先度を落とすことで、最大遅延時間を固定化し、メイン処理が待たされることをなくする。
タイマ割り込み1からのFATアクセス要求によりFATファイルシステムのAPIを実行する。APIの実行完了で結果をタイマ割り込み1に返す。
タイマ割り込み1から強制終了要求が行われた場合、FATファイルシステムのAPI実行完了後にファイルのクローズ処理に移行して強制終了する。

タイムアウトなどの異常処理やデータの排他処理などは注意して設計する必要がありますが、RTOSなしでも他処理に影響を与えることなく、問題なく動作させることができています。
ノンブロッキングコールに対応したFATファイルシステムである可能性もあるので、事前にFATファイルシステムの仕様確認は必要です。

5. おわりに

「3 効率のよいファイルアクセスについて」でも書きましたが、効率の良いファイルアクセスを行うにはFATファイルシステムや外部ストレージデバイスの仕様や動作を理解した上で、アプリケーション側で考慮した設計にする必要があります。
考慮しなかった場合、必要以上に外部ストレージデバイスにアクセスすることになり、効率の悪いファイルアクセスになってしまう他に、外部ストレージデバイスの寿命を縮めてしまうことにもなりかねません。

私自身、開発する上で必要最低限のところは押さえたつもりですが、まだ把握できていない仕様もあり、まだ改善できる点があるかもしれません。
今後も組み込みソフトでFATファイルシステムを扱う機会が増えると思いますので、引き続き勉強して理解を深めたいと思います。

(M.A.)

[注釈]
(*1) FatFs…
ChaN氏によって開発された小規模な組み込みシステム向けの汎用FAT ファイルシステム・モジュールです。ChaN 氏および、FatFs の公式Web ページは以下になります。
http://elm-chan.org/fsw/ff/00index_e.html
[参考文献]
  • ・CQ出版社 「定番!超軽量マイコン用ファイル・システムFatFs」
  • ・SD Association 「SD Specifications Part 1 Physical Layer Simplified Specification」
  • ・Renesus 「RXファミリ オープンソース FAT ファイルシステムM3S-TFAT-Tiny モジュール アプリケーションノート」
  • ・Renesus 「RXファミリ SDモードSDメモリカードドライバ アプリケーションノート」

関連ページへのリンク

関連するソフテックだより

ページTOPへ