組込み機器向けのFATファイルシステム「GR-FILE」(FATファイルシステム解説②)

つぶつぶコラム

FATファイルシステムについて解説する全3回のコラムの第2回です。
今回は、弊社で開発した組込み機器向けのFATファイルシステム「GR-FILE」を解説します。
第1回をまだご覧にになっていない方は是非合わせてお読みください。

第1回FATファイルシステムについて

GR-FILEとは

GR-FILEとは、弊社で開発した組込み機器向けのFATファイルシステムミドルウェアです。
前述のMicrosoftの仕様書「Microsoft Extensible Firmware Initiative FAT32 File System Specification」を元に作成されており、これまで様々な組込み機器に採用されてきました。
特に、弊社のUSBドライバと組み合わせた、「USBマスストレージ統合キット」は組込むだけでUSBメモリを扱えるようになるため多くのお客様より好評をいただいています。

GR-FILEの特徴

以下にGR-FILEの特徴を列挙します。

  • FAT12/16/32、ロングファイルネーム(LFN)をサポート
  • POSIX、C言語標準、GR-FILE固有のAPI
  • デバイス直接制御API
  • メディアの取出し/ロック/アンロック、物理フォーマット等、デバイス固有機能に利用できるIOCTRL
  • マルチタスクによる同時I/O
  • Shift-JISファイル名をサポート
  • 他の日本語コード、多国語の対応も可能
  • ドライブ方式、階層型方式のmount
  • 各種キャッシング機能による高速化
  • 豊富なキャッシュ反映方法
  • キャッシングを行わないDirectIO機能
  • メディアサイズに応じた自動フォーマットパラメータの決定
  • パーティションの設定、変更
  • RAM DISKのサンプルドライバが付属
  • 豊富なパラメータ設定

組込み機器向けのファイルシステムとしては少し機能が贅沢な気もしますが、色々出来るという事で良いかと思っています。POSIXやC言語標準のAPIもありますので、PCなどでファイルへの読み書きを経験されている方には馴染みのあるAPIとなっています。キャッシュも様々持っており、ファイルシステムではよく採用されるセクターキャッシュやファイル名をキャッシュする機能などもあります。また、多くのパラメータやコンパイルスイッチを持っており必要に応じて機能を削除できます。この辺りはGR-FILEの概要説明書にも記載がありますので興味があればお問い合わせください。

GR-FILEの外部インターフェース

GR-FILEはFATファイルシステムの処理のみを行いますので、実際のメディアへのアクセスにはメディアドライバが必要になります。
メディアドライバはGR-FILEから呼び出されますが、このためのI/FはGR-FILEで定義されています。
ですので、メディアドライバとのソフト的な接続部分を作る必要があります。(ポーティング)

メディアドライバとのI/F

GR-FILEからメディアアクセスのために呼び出されるI/Fは以下の5つの機能です。

  • デバイスオープン
  • デバイスクローズ
  • デバイスリード
  • デバイスライト
  • デバイスIOコントロール

一般的なブロックデバイスドライバにはあると思われる機能ですが、デバイスIOコントロールは機能が無い場合もあるので実装依存になります。
弊社の「USBマスストレージ統合キット」や「GR-SD」にはすでにGR-FILEとのI/F部分が用意されていますので、容易に組込みが行えます。
もちろん、弊社以外のメディアドライバを使用することもできますが、この場合はメディアドライバとのソフト的な接続部分を作る必要があります。

OSとのI/F

GR-FILEはマルチタスクに対応していますが、排他制御が必要となります。また、GR-FILEはタスクごとにカレントディレクトリを認識します。この区別を行うためにはタスクの識別が必要になります。これらの処理を行うために、GR-FILEではセマフォとタスクIDを使用します。
GR-FILEにはITRONへの対応を行うサンプルが付属しますが、この部分を変更(ポーティング)することで様々なOSへの対応が可能です。

時刻取得I/F

ファイルシステムとは切っても切れない機能として時刻の取得があります。
タイムスタンプに使用されますが、GR-FILEはこの部分も外部I/Fが定義されています。
ですので、OSの管理する時刻を返すことでも良いですし、RTC(Real Time Clock)のような外部機器から読み取って返すことでも良いですし、時刻情報を使わない場合は固定値を返すことでも良いです。
GR-FILEとしては返された時刻情報をディレクトリエントリに書き込むのみになります。

ただし、この機能はファイルへのアクセスのたびに頻繁に呼ばれるので、時間のかかる処理はあまりお勧めできません。

FATファイルシステムを使った設計方法

組込み機器でFATファイルシステム(GR-FILE)を使用する場合に気を付けた方が良さそうな部分を書いていこうと思います。

CPUキャッシュ

組込みではファイルシステムに限らず注意すべき項目です。
CPUキャッシュ機能が有効な場合、データの転送をCPUがすべて行う場合は問題がありませんが、メディアドライバでDMAなどのCPUが介在しないデータ転送を行うとこの問題が発生することがあります。
CPUが介在しないので、CPUが見ているメモリの状態と、DMAがデータ転送した実メモリの状態が異なる現象が発生します。ファイルに間違ったデータが書き込まれる、ファイルの内容は正しいのに読み込んだデータが壊れている、などが発生することがあります。
これを回避するにはDMAなどのCPUが介在しないデータ転送を利用する場合は、適切なタイミングでCPUキャッシュをフラッシュすることや、CPUのキャッシュメモリにデータを置かない、などの対策を行う必要があります。

ディレクトリ構成

FATファイルシステムでは大文字小文字の区別がなく、同名も許可されていない為、ファイル/ディレクトリを作成するときにチェックを行う必要があります。このチェックはファイルシステム側で行いますが、あまりにも多くのファイル/ディレクトリがあるとチェックのためのリードが多く発生し時間がかかります。
特にLFNを利用したファイル/ディレクトリ名の場合は、長いファイル名でのチェックと短いファイル名でのチェックの両方を行う必要がある為、より長時間がかかります。
PCなどではリソースも潤沢にある為あまり気にならない場合が多いですが、組込み機器の場合はこの点を考慮する必要があります。
とは言っても、使用できるリソースも千差万別ですし、使用するメディアやドライバの性能にも左右されるので試してみて許容できるところを探すのが無難に思います。(経験上では1つのディレクトリにファイル/ディレクトリは100~200程度が良いと思います。)

ファイル名

LFNをサポートしている場合は長いファイル名が使えます。長いファイル名には小文字も扱えるので便利なのですが、逆にLFNをサポートしている環境で、短いファイル名のみを扱おうとする場合、短いファイル名に小文字が含まれると、長いファイル名の扱いになることがあります。
これは小文字が含まれるため小文字を優先するために起こります。これは短いファイル名では扱えず、長いファイル名で扱える文字を指定した場合でも同様に起きます。
ですので、ファイルを作成する際は大文字や扱える文字に注意して指定する必要があります。

キャッシュパラメータ

これに関しては、「GR-FILEアプリケーションノート」に記載しています。
「GR-FILEアプリケーションノート」はGR-FILEを使う上でのパラメータ設定指針や、これまで問い合わせの多かったトラブルシューティングなどを記載しています。ですがこのような資料の性質上、GR-FILEを購入いただいたお客様のみに公開しております。
一般的にはキャッシュメモリが多い方がIO回数を減らせますので、パフォーマンスの向上が期待できます。

メディアドライバとのI/F

メディアドライバとのI/F部分でも注意する点があります。
CPUキャッシュも注意すべきですが、データのアライメントも注意する必要があります。
メディアドライバによっては、DMAなどを使用する場合がありますが、DMAによっては4バイトアライメントでの転送のみサポートするなどの制約があります。
このような場合、ファイルシステムからのデータを別のメモリにコピーしてからメディアドライバに渡すなどの工夫が必要になる場合があります。(メディアドライバによってはDMA転送できない場合にPIO転送に切り替えるものもあります。)
また、排他制御が必要な場合があります。メディアドライバがマルチタスクに対応していない場合、メディアドライバに制御が渡る際に排他制御が必要です。GR-FILEはマルチタスクに対応しているため複数のタスクのアクセスを処理できます。その結果、メディアドライバに複数のタスクのIO要求が行われる場合があります。メディアドライバがマルチタスクに対応していない場合はメディアドライバの入り口で排他制御を行う必要があります。

ファイルキャッシュ

多くのファイルシステムではキャッシュ機能を提供していると思います。
キャッシュ機能の無いシステムでは毎回メディアへのアクセスが発生します。利点としては毎回アクセスを行うため、システムの認識している状態とメディアの状態が一致することです。昔のゲームにはこれを利用してゲームオーバーの情報を記録するものもありました。(リセットしても復活できない様になっていました。)
ファイルシステムでのキャッシュ機能は、メモリ上にメディアのセクタ情報を保持し、再読み込みや書き込みをメモリ上だけで行い、必要に応じてIOを行うような処理を指します。

ファイルシステムのメディアドライバはブロックメディアを扱いますので、IOの最小単位が存在します。
(多くの場合は512バイト~4096バイトです。)この最小単位をセクタと呼びます。
ですが、ファイルの中の情報はセクタのサイズにかかわらず1バイト単位で記録が出来ます。例えば、あるファイルに10バイト単位で何度も追記書き込みを行う場合、キャッシュ機能の無いファイルシステムでは10バイトの書き込みを行うたびに、読み込み、マージ、書き込みを行わないとならなくなります。

一方、キャッシュ機能のあるファイルシステムでは、読み込みは最初に行い、書き込みはメモリ上で処理され、キャッシュが埋まるか、ファイルを閉じる際にIOを行います。
キャッシュの目的は高速なメモリを使って、低速なIO回数を削減することにあります。ですがデメリットも存在します。メモリ上で書き込みを処理してしまうので、キャッシュの情報がメディアに反映されるまでは書き込み情報がメモリ上にしかないタイミングが存在します。このタイミングで電源が切断されるなど、システムが停止してしまうと、システム上では書き込んだ情報がメディアには反映されておらずデータが失われる危険性があります。キャッシュを使用したシステムを作る際はこのあたりも考慮する必要があります。
キャッシュは特にIOの遅いメディアで大きな恩恵を得ることが出来ます。昔、フロッピーディスクで動作させていたシステムにディスクキャッシュを導入した時の驚きは大きかったです。現在でもファイルシステムの処理として一番時間のかかる部分はメディアへのIO処理になります。

GR-File関連製品のページはこちら