From 289f6a146c0b2087607d8d8659531ea90142779a Mon Sep 17 00:00:00 2001 From: Leo C Date: Sun, 27 May 2018 21:26:38 +0200 Subject: Import fatfs R0.13b --- fatfs/doc/ja/appnote.html | 283 -------------------------------------------- fatfs/doc/ja/chdir.html | 81 ------------- fatfs/doc/ja/chdrive.html | 61 ---------- fatfs/doc/ja/chmod.html | 83 ------------- fatfs/doc/ja/close.html | 65 ---------- fatfs/doc/ja/closedir.html | 64 ---------- fatfs/doc/ja/config.html | 209 -------------------------------- fatfs/doc/ja/dinit.html | 46 ------- fatfs/doc/ja/dioctl.html | 98 --------------- fatfs/doc/ja/dread.html | 72 ----------- fatfs/doc/ja/dstat.html | 48 -------- fatfs/doc/ja/dwrite.html | 76 ------------ fatfs/doc/ja/eof.html | 62 ---------- fatfs/doc/ja/error.html | 62 ---------- fatfs/doc/ja/expand.html | 116 ------------------ fatfs/doc/ja/fattime.html | 57 --------- fatfs/doc/ja/fdisk.html | 92 -------------- fatfs/doc/ja/filename.html | 83 ------------- fatfs/doc/ja/findfirst.html | 110 ----------------- fatfs/doc/ja/findnext.html | 68 ----------- fatfs/doc/ja/forward.html | 139 ---------------------- fatfs/doc/ja/getcwd.html | 71 ----------- fatfs/doc/ja/getfree.html | 95 --------------- fatfs/doc/ja/getlabel.html | 82 ------------- fatfs/doc/ja/gets.html | 65 ---------- fatfs/doc/ja/lseek.html | 130 -------------------- fatfs/doc/ja/mkdir.html | 80 ------------- fatfs/doc/ja/mkfs.html | 114 ------------------ fatfs/doc/ja/mount.html | 82 ------------- fatfs/doc/ja/open.html | 172 --------------------------- fatfs/doc/ja/opendir.html | 75 ------------ fatfs/doc/ja/printf.html | 93 --------------- fatfs/doc/ja/putc.html | 62 ---------- fatfs/doc/ja/puts.html | 62 ---------- fatfs/doc/ja/rc.html | 95 --------------- fatfs/doc/ja/read.html | 74 ------------ fatfs/doc/ja/readdir.html | 129 -------------------- fatfs/doc/ja/rename.html | 85 ------------- fatfs/doc/ja/sdir.html | 38 ------ fatfs/doc/ja/setlabel.html | 91 -------------- fatfs/doc/ja/sfatfs.html | 63 ---------- fatfs/doc/ja/sfile.html | 45 ------- fatfs/doc/ja/sfileinfo.html | 69 ----------- fatfs/doc/ja/size.html | 62 ---------- fatfs/doc/ja/stat.html | 110 ----------------- fatfs/doc/ja/sync.html | 65 ---------- fatfs/doc/ja/tell.html | 62 ---------- fatfs/doc/ja/truncate.html | 66 ----------- fatfs/doc/ja/unlink.html | 73 ------------ fatfs/doc/ja/utime.html | 99 ---------------- fatfs/doc/ja/write.html | 74 ------------ 51 files changed, 4458 deletions(-) delete mode 100644 fatfs/doc/ja/appnote.html delete mode 100644 fatfs/doc/ja/chdir.html delete mode 100644 fatfs/doc/ja/chdrive.html delete mode 100644 fatfs/doc/ja/chmod.html delete mode 100644 fatfs/doc/ja/close.html delete mode 100644 fatfs/doc/ja/closedir.html delete mode 100644 fatfs/doc/ja/config.html delete mode 100644 fatfs/doc/ja/dinit.html delete mode 100644 fatfs/doc/ja/dioctl.html delete mode 100644 fatfs/doc/ja/dread.html delete mode 100644 fatfs/doc/ja/dstat.html delete mode 100644 fatfs/doc/ja/dwrite.html delete mode 100644 fatfs/doc/ja/eof.html delete mode 100644 fatfs/doc/ja/error.html delete mode 100644 fatfs/doc/ja/expand.html delete mode 100644 fatfs/doc/ja/fattime.html delete mode 100644 fatfs/doc/ja/fdisk.html delete mode 100644 fatfs/doc/ja/filename.html delete mode 100644 fatfs/doc/ja/findfirst.html delete mode 100644 fatfs/doc/ja/findnext.html delete mode 100644 fatfs/doc/ja/forward.html delete mode 100644 fatfs/doc/ja/getcwd.html delete mode 100644 fatfs/doc/ja/getfree.html delete mode 100644 fatfs/doc/ja/getlabel.html delete mode 100644 fatfs/doc/ja/gets.html delete mode 100644 fatfs/doc/ja/lseek.html delete mode 100644 fatfs/doc/ja/mkdir.html delete mode 100644 fatfs/doc/ja/mkfs.html delete mode 100644 fatfs/doc/ja/mount.html delete mode 100644 fatfs/doc/ja/open.html delete mode 100644 fatfs/doc/ja/opendir.html delete mode 100644 fatfs/doc/ja/printf.html delete mode 100644 fatfs/doc/ja/putc.html delete mode 100644 fatfs/doc/ja/puts.html delete mode 100644 fatfs/doc/ja/rc.html delete mode 100644 fatfs/doc/ja/read.html delete mode 100644 fatfs/doc/ja/readdir.html delete mode 100644 fatfs/doc/ja/rename.html delete mode 100644 fatfs/doc/ja/sdir.html delete mode 100644 fatfs/doc/ja/setlabel.html delete mode 100644 fatfs/doc/ja/sfatfs.html delete mode 100644 fatfs/doc/ja/sfile.html delete mode 100644 fatfs/doc/ja/sfileinfo.html delete mode 100644 fatfs/doc/ja/size.html delete mode 100644 fatfs/doc/ja/stat.html delete mode 100644 fatfs/doc/ja/sync.html delete mode 100644 fatfs/doc/ja/tell.html delete mode 100644 fatfs/doc/ja/truncate.html delete mode 100644 fatfs/doc/ja/unlink.html delete mode 100644 fatfs/doc/ja/utime.html delete mode 100644 fatfs/doc/ja/write.html (limited to 'fatfs/doc/ja') diff --git a/fatfs/doc/ja/appnote.html b/fatfs/doc/ja/appnote.html deleted file mode 100644 index 8b6cb66..0000000 --- a/fatfs/doc/ja/appnote.html +++ /dev/null @@ -1,283 +0,0 @@ - - -
- - - - - -FatFsモジュールはポータビリティに関して次の点を前提としています。
-下に示す依存関係図は、FatFsモジュール利用の組み込みシステムにおける代表的な構成を示します。
-(a) FatFs用に書かれたディスク モジュールがある場合は、そのまま追加するだけです。 (b) しかし、多くの既存のディスク モジュールはそのAPIをFatFsに合わせるため、グルー関数が必要になるでしょう。
-ポーティング作業は、要求されるデバイス制御関数を用意することが全てで、それ以外にすることは何もありません。既に動作しているデバイス制御モジュールがあるなら、そのインターフェースをFatFsに合わせるかグルー関数を介してつなぐだけで済みますが、無い場合はほかから移植するか最初から書くかする必要があります。定義されている全ての関数が常に必要なわけではありません。例えば、リード オンリ構成では書き込み系関数は必要ありません。次の表に構成オプションと要求される関数の対応を示します。
-必要な関数 | 必要となる条件 | 備考 |
---|---|---|
disk_status disk_initialize disk_read | 常時 | ffsample.zip (サンプル) その他web上に多数 |
disk_write get_fattime disk_ioctl (CTRL_SYNC) | _FS_READONLY == 0 | |
disk_ioctl (GET_SECTOR_COUNT) disk_ioctl (GET_BLOCK_SIZE) | _USE_MKFS == 1 | |
disk_ioctl (GET_SECTOR_SIZE) | _MAX_SS != _MIN_SS | |
disk_ioctl (CTRL_TRIM) | _USE_TRIM == 1 | |
ff_convert ff_wtoupper | _USE_LFN != 0 | option/unicode.cをプロジェクトに 加えればよい |
ff_cre_syncobj ff_rel_grant ff_req_grant ff_del_syncobj | _FS_REENTRANT == 1 | option/syscall.c (サンプル) |
ff_mem_alloc ff_mem_free | _USE_LFN == 3 |
次の表にいくつかのターゲットにおけるメモリ使用量の例を示します。テスト時の構成オプションはその下の通りです。数値の単位はバイトで、Vはボリューム数、Fは同時オープン ファイル数を示します。コンパイラの最適化オプションはコード サイズとしています。
-ARM7 32bit | ARM7 Thumb | CM3 Thumb-2 | AVR | H8/300H | PIC24 | RL78 | V850ES | SH-2A | RX600 | IA-32 | |
---|---|---|---|---|---|---|---|---|---|---|---|
Compiler | GCC | GCC | GCC | GCC | CH38 | C30 | CC78K0R | CA850 | SHC | RXC | MSC |
text (Full, R/W) | 10.4k | 6.8k | 6.3k | 12.4k | 9.8k | 11.1k | 12.8k | 8.6k | 8.9k | 6.4k | 8.5k |
text (Min, R/W) | 6.8k | 4.6k | 4.3k | 8.2k | 6.7k | 7.6k | 9.1k | 6.0k | 5.9k | 4.5k | 5.9k |
text (Full, R/O) | 4.8k | 3.1k | 2.8k | 5.6k | 4.6k | 5.3k | 6.3k | 4.0k | 3.9k | 3.0k | 3.9k |
text (Min, R/O) | 3.6k | 2.4k | 2.3k | 4.4k | 3.5k | 4.0k | 4.9k | 3.3k | 3.0k | 2.4k | 3.1k |
bss | V*4 + 2 | V*4 + 2 | V*4 + 2 | V*2 + 2 | V*4 + 2 | V*2 + 2 | V*2 + 2 | V*4 + 2 | V*4 + 2 | V*4 + 2 | V*4 + 2 |
Work area (_FS_TINY == 0) | V*564 + F*552 | V*564 + F*552 | V*564 + F*552 | V*560 + F*546 | V*560 + F*546 | V*560 + F*546 | V*560 + F*546 | V*564 + F*552 | V*564 + F*552 | V*564 + F*552 | V*564 + F*552 |
Work area (_FS_TINY == 1) | V*564 + F*40 | V*564 + F*40 | V*564 + F*40 | V*560 + F*34 | V*560 + F*34 | V*560 + F*34 | V*560 + F*34 | V*564 + F*40 | V*564 + F*40 | V*564 + F*40 | V*564 + F*40 |
-FatFs R0.12b options: -_FS_READONLY 0 (R/W) or 1 (R/O) -_FS_MINIMIZE 0 (Full, with all basic functions) or 3 (Min, with fully minimized) -_FS_TINY 0 (Default) or 1 (Tiny file object) -And any other options are left not changed from default setting. --
次の表は構成オプションの設定値によりどの機能が削除されるかを示します。API関数の行にxが無ければその関数は使用可能です。
-Function | _FS_ MINIMIZE | _FS_ READONLY | _USE_ STRFUNC | _FS_ RPATH | _USE_ FIND | _USE_ CHMOD | _USE_ EXPAND | _USE_ LABEL | _USE_ MKFS | _USE_ FORWARD | _MULTI_ PARTITION | ||||||||||||||
0 | 1 | 2 | 3 | 0 | 1 | 0 | 1 | 0 | 1 | 2 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | |
f_mount | |||||||||||||||||||||||||
f_open | |||||||||||||||||||||||||
f_close | |||||||||||||||||||||||||
f_read | |||||||||||||||||||||||||
f_write | x | ||||||||||||||||||||||||
f_sync | x | ||||||||||||||||||||||||
f_lseek | x | ||||||||||||||||||||||||
f_opendir | x | x | |||||||||||||||||||||||
f_closedir | x | x | |||||||||||||||||||||||
f_readdir | x | x | |||||||||||||||||||||||
f_findfirst | x | x | x | ||||||||||||||||||||||
f_findnext | x | x | x | ||||||||||||||||||||||
f_stat | x | x | x | ||||||||||||||||||||||
f_getfree | x | x | x | x | |||||||||||||||||||||
f_truncate | x | x | x | x | |||||||||||||||||||||
f_unlink | x | x | x | x | |||||||||||||||||||||
f_mkdir | x | x | x | x | |||||||||||||||||||||
f_rename | x | x | x | x | |||||||||||||||||||||
f_chdir | x | ||||||||||||||||||||||||
f_chdrive | x | ||||||||||||||||||||||||
f_getcwd | x | x | |||||||||||||||||||||||
f_chmod | x | x | |||||||||||||||||||||||
f_utime | x | x | |||||||||||||||||||||||
f_getlabel | x | ||||||||||||||||||||||||
f_setlabel | x | x | |||||||||||||||||||||||
f_expand | x | x | |||||||||||||||||||||||
f_forward | x | ||||||||||||||||||||||||
f_mkfs | x | x | |||||||||||||||||||||||
f_fdisk | x | x | x | ||||||||||||||||||||||
f_putc | x | x | |||||||||||||||||||||||
f_puts | x | x | |||||||||||||||||||||||
f_printf | x | x | |||||||||||||||||||||||
f_gets | x |
FatFsモジュールは、長いファイル名(LFN)をサポートします。ファイルに付けられた2つの異なる名前(短いファル名と長いファイル名)は、f_readdir関数を除くファイル操作関数において透過です。デフォルト構成では、LFN機能はOFFになっています。LFN機能を有効にするには、_USE_LFNを1,2または3に設定し、option/unicode.cをプロジェクトに追加します。LFN機能は、加えてある程度のワーク エリア(LFN操作バッファ)を必要とします。バッファ長は使用できるメモリに応じて_MAX_LFNで構成されることができます。LFNの長さは最大255文字に達するので、LFN完全対応のためには_MAX_LFNは255に設定されるべきです。与えられたファイル名に対してバッファ長が不足した場合、ファイル関数はFR_INVALID_NAMEで失敗します。
-ファイル関数に再入を行う条件の下でLFN機能を使用する場合は、_USE_LFNは2または3に設定されなければなりません。この場合、ファイル関数はワーク エリアを動的に確保(スタックまたはヒープ)します。ワーク エリアのサイズは、(_MAX_LFN + 1) * 2バイト(exFAT利用時はさらに+608バイト)になるので、スタック等のサイズはそれを考慮した十分な余裕がなければなりません。
-_CODE_PAGE | 追加コード |
---|---|
SBCS | +2.8K |
932(Shift_JIS) | +62.6k |
936(GBK) | +177k |
949(Korean) | +139k |
950(Big5) | +111k |
LFN機能の上手な使い方は、それを使わないということです。実際、組み込み用途ではLFN機能がどうしても必要になるということはほとんど無いはずです。LFNを有効にすると、選択されたコード ページに応じてモジュール サイズが増大します。右の表に各コード ページにおけるLFNを有効にしたときのモジュール サイズの違いを示します。特に、CJK地域では数万の文字が使われていますが、不幸なことにそれは巨大なOEM-Unicode相互変換テーブルを要求し、モジュール サイズは劇的に増大します。その結果、それらのコード ページにおいてLFNを有効にしたFatFsモジュールは、多くの8ビット マイコンにインプリメントすることができません。
-LFN機能のハードルはそれだけではありません。マイクロソフト社はFATファイルシステムについていくつかの特許を保有しています。いずれもLFN機能の実装に関するもので、その利用に対して$0.25/unitのライセンス料を要求しています。このため、商用製品でLFN機能を利用する場合は、製品の最終仕向地によってはライセンスが必要になります。最近のFAT32ドライバの多くはLFN機能を含んでいるため、それらの使用に当たってライセンスが必要になりますが、FatFsは構成オプションでLFN機能を任意にON/OFFできるため、無効にしてライセンス問題を回避することもできます。
-FatFs API上におけるファイル名等の文字列データの入出力は、デフォルトではANSI/OEMコードで行われますが、これをUnicode(UTF-16)に切り替えることもできます(_LFN_UNICODEで設定)。つまり、これはFatFsがLFN機能に完全対応していることを意味します。Unicodeのファイル名に関する詳細は、パス名のフォーマットを参照してください。
-exFAT(Microsoft's Extended File Allocation Table)ファイルシステムは、既に組み込みシステムや情報家電で広く使われているFATファイルシステムを置き換える目的で開発されました。exFATは、64GiB以上のSDメモリ カードで標準ファイルシステムに採用されるなど、FATに並びリムーバブル メディアの標準ファイルシステムの一つとなりつつあります。
-exFATボリュームでは、FATボリュームで制約となっていた4GiB以上のサイズのファイルを扱え、ファイルシステムのオーバーヘッド(特にファイル アロケーション ディレイ)も大幅に低減され、書き込みスループットがFATより向上しています。しかし、現リビジョンのFatFsでは、実装上の理由から不連続ファイルへのサイズ拡大を伴う書き込み時のとき、スループットがFATより低下します。f_expand関数による連続領域の割り当て機能は、この問題の回避に有効かもしれません。
-exFATはマイクロソフト社が開発したものなので、マイクロソフト社はexFATについていくつかの特許を保有しています。FatFsのexFAT機能は、それの US. Pat. App. Pub. No. 2009/0164440 A1 に基づいた実装です。このため、商用製品でexFAT機能を利用する場合、製品の最終仕向地によってはライセンスが必要になります。最近のFATドライバの多くはexFAT機能を含んでいるため、それらの使用に当たってライセンスが必要になりますが、FatFsは構成オプションでexFAT機能を任意にON/OFFできるため、無効にしてライセンス問題を回避することもできます。
-exFATを有効にすると、FatFsモジュールのC89互換は失われます(64ビット整数型が必要なため)。
-互いに異なるボリュームに対するファイル操作は、_USE_LFN == 1を除いて構成にかかわらずリエントラントで、常に同時平行に動作できます。
-同じボリュームに対してはデフォルトではリエントラントではありませんが、_FS_REENTRANTでリエントラント(スレッド セーフ)にすることはできます。この場合、OS依存の同期オブジェクト操作関数ff_cre_syncobj, ff_del_syncobj, ff_req_grant, ff_rel_grant関数もまたプロジェクトに追加されなければなりません。サンプル コードと解説はoption/syncobj.cにあります。
-この場合、あるタスクがボリュームを使用中に他のタスクからそのボリュームに対するファイル関数が呼び出されると、そのアクセスは先のタスクがファイル関数を抜けるまでサスペンドされます。待ち時間が_TIMEOUTで指定された期間を越えた場合、その関数はFR_TIMEOUTでアボートします。いくつかのRTOSではタイムアウト機能はサポートされないかも知れません。
-ひとつの例外がf_mount, f_mkfs, f_fdisk関数にあります。これらのボリューム制御関数は同じボリューム(または関連する物理ドライブ)に対してリエントラントではありません。これらの関数を使用するときは、アプリケーション レベルで排他制御しなければなりません。
-注: このセクションはFatFsモジュールそれ自体のリエントランシーについて説明しています。_FS_REENTRANTは、各ファイルシステム オブジェクトの排他制御を行うのみで、下位のディスク関数への再入を防止するものではありません。たとえば、シングル ボリューム構成ではdisk_status関数のみ再入される可能性があり、マルチ ボリューム構成ではどのディスク関数も再入される可能性があります。このように、複数のタスクから同時にFatFs APIを使う条件では、ディスクI/Oモジュールはスレッド セーフである必要があります。
-FatFsモジュールではデフォルトでは多重アクセス制御機能をサポートしていません。ファイルに対する多重アクセスは、そのアクセス モードによって制限されます。一つのファイルに対する多重オープンは、それらが全てリード モードのときに限って許可されます。書き込みモードを含む多重オープン、また開かれているファイルに対するリネームや削除を行ってはなりません。さもないと、そのボリュームのFAT構造が破壊される可能性があります。
-_FS_LOCKに1以上の値(値は同時に管理できるファイル数)をセットすることで多重アクセス制御機能が有効になり、ファイル単位のアクセス制御を自動で行うこともできます。この場合、上記のルールを破ったオープン・リネーム・削除を試みると、その関数はFR_LOCKEDで失敗します。また、_FS_LOCKを越える数のファイルやサブ ディレクトリを同時にオープンしようとすると、FR_TOO_MANY_OPEN_FILESで失敗します。
-小規模な組込システムでのファイルの読み書きにおける効率の良いアクセスのため、アプリケーション プログラマはFatFsモジュールの中でどのような処理が行われているか考慮すべきです。ストレージ上のデータはf_read関数により次のシーケンスで転送されます。
-図1. セクタ ミスアラインド リード (ショート)
-
-
図2. セクタ ミスアラインド リード (ロング)
-
-
図3. セクタ アラインド リード
-
-
ファイルI/Oバッファはセクタの一部のデータを読み書きするためのセクタ バッファを意味します。セクタ バッファは、それぞれのファイル オブジェクト内のプライベート セクタ バッファまたはファイルシステム オブジェクト内の共有セクタ バッファのどちらかです。バッファ構成オプションの_FS_TINYは、データ転送にどちらを使うかを決定します。タイニー バッファ(1)が選択されるとデータ メモリの消費はそれぞれのファイル オブジェクトで_MAX_SSバイト減少されます。この場合、FatFsモジュールはファイル データの転送とFAT/ディレクトリ アクセスにファイルシステム オブジェクト内のセクタ バッファだけを使用します。タイニー バッファの欠点は、セクタ バッファにキャッシュされたFATデータがファイル データの転送により失われ、クラスタ境界の毎にリロードされなければならないことです。でも、悪くない性能と少ないメモリ消費の視点から多くのアプリケーションに適するでしょう。
-図1はセクタの一部のデータがファイルI/Oバッファを経由で転送されることを示します。図2に示される長いデータの転送では、転送データの中間の1セクタまたはそれ以上のセクタにまたがる転送データがアプリケーション バッファに直接転送されています。図3は転送データ全体がセクタ境界にアライメントされている場合を示しています。この場合、ファイルI/Oバッファは使用されません。直接転送においては最大の範囲のセクタがdisk_read関数で一度に読み込まれますが、クラスタ境界を越えるマルチ セクタ転送はそれが隣接であっても行われません。
-このように、セクタにアライメントしたファイルの読み書きへの配慮はバッファ経由のデータ転送を避け、読み書き性能は改善されるでしょう。その効果に加え、タイニー構成でキャッシュされたFATデータがファイル データの転送によりフラッシュされず、非タイニー構成と同じ性能を小さなメモリ フットプリントで達成できます。
-HDDなどのディスク メディアとは異なり、SDCやCFCなどのフラッシュ メモリ メディアの性能を引き出すには、その特性を意識した制御が必要になります。
-フラッシュ メモリ メディアの書き込み速度はシングル セクタ書き込みの時に最も低いものになり、一回のトランザクションで転送されるセクタ数が大きくなるほど書き込み速度は向上します(図6)。この効果はバス速度が高速になるほど大きく、10倍以上の差が現れることも珍しくありません。テスト結果は、マルチ セクタ書き込み(W:16K, 32 sectors)がシングル セクタ書き込み(W:100, 1 sector)よりどの程度速いかを明確に示しています。大容量メディアほどシングル セクタ書き込みが遅くなる点もまた重要です。書き込みトランザクションの回数はまた、メディアの寿命にも影響してきます。つまり、同じ量のデータを書き込む場合、図6上のシングル セクタ書き込みは、図6下のマルチ セクタ書き込みに比べて16倍早くフラッシュ メモリ メディアを消耗させてしまうということです。
-このように、アプリケーションはなるべく大きなブロック(クラスタ サイズまたは2の累乗セクタ境界にアライメントした)で読み書きを行う必要があります。もちろん、アプリケーションからメディアに至る全てのレイヤがマルチ セクタ転送に対応していないと意味がありません。残念ながら、既存のオープン ソースのドライバの多くはマルチ セクタ転送に未対応です。なお、FatFsモジュールおよびサンプル ドライバはマルチ セクタ転送に対応しています。
-通常のファイル消去では、記録されたデータに対して何らかの処理が行われるわけではなく、単にFAT上にその領域を未使用と記録しているだけです。このため、ファイルが消去されたあともそれらは有効なデータ ブロックとしてフラッシュ メモリ上に残ります。そこで、ファイルを消去するとき、占有していたデータ セクタを明示的に消去(つまり未使用ブロックにする)することにより、メディア内の空きブロックを増やすことができます。これにより、次にそのブロックに書き込むときの消去動作が無くなり、書き込み性能が向上する可能性があります。また、ウェアレベリングに使えるブロックが増え、メディアの耐久性も向上するかも知れません。この機能を有効にするには、_USE_TRIMに1を設定します。これはフラッシュ メモリ ドライブの内部動作に期待した制御なので、効果があるとは限りません。また、ファイル消去の時間が延びることも考慮に入れるべきです。
-ストレージ上のFAT構造を操作している途中で、停電、不正なメディアの取り外し、回復不能なデータ エラー等の障害が発生すると、処理が中途半端な状態で中断され、その結果としてFATボリュームの構造が破壊される可能性があります。次にFatFsモジュールにおけるクリチカル セクションと、その間の障害により起きうるエラーの状態を示します。
-赤で示したセクションを実行中に中断が発生した場合、クロス リンクが発生して操作中のファイルやディレクトリが失われる可能性があります。黄色で示したセクションを実行中に中断が発生した場合、次のうちいずれかまたは複数の結果が生じる可能性があります。
-いずれの場合も操作の対象でないファイルには影響はありません。これらのクリチカル セクションは、ファイルを書き込みモードで開いている時間を最小限にするか、f_sync関数を適宜使用することで図5のようにリスクを最小化することができます。
-FatFs APIの拡張的使用例です。有用なコードがあった場合は、随時追加していきます。。
-FatFsは、作者(ChaN)の個人プロジェクトとして開発されています。現在までのリビジョンにおいてコントリビューターはいないため、作者以外の書いたソース コードは含まれません。ソース ファイルにライセンス条件が記述されているので、利用の際はそれに従うこと。原文は英語ですが、参考までに以下に日本語訳を示しておきます。
--/*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT file system module R0.12a / -/-----------------------------------------------------------------------------/ -/ -/ Copyright (C) 2016, ChaN, all right reserved. -/ -/ FatFsモジュールはオープンソースソフトウェアです。FatFsの再配布および使用は、 -/ ソースコードかバイナリ形式か、また変更の有無にかかわらず、次の条件が満たされ -/ る場合に限り許可されます。 -/ -/ 1. ソースコードで再配布するときは、その中に上記の著作権表示、この条件、および -/ 次の免責事項を保持すること。 -/ -/ このソフトウェアは、著作権者らおよびコントリビューターらによって現状のまま -/ 提供されており、いかなる保証もありません。 -/ 著作権者もコントリビューターも、このソフトウェアの使用により発生するいかなる -/ 損害についても、責任を負いません。 -/----------------------------------------------------------------------------*/ --
このようにFatFsはBSDライクなライセンスとしていますが、一つ大きな違いがあります。FatFsは主に組み込み向けとして開発されたため、バイナリ形式(ソース コードを含まない形式全て)での再配布については、商用での使いやすさを考慮して配布時の条件を設けていません。つまり、バイナリ配布の場合は、FatFsおよびそのライセンス文書についてドキュメントに明記してもしなくてもかまいません。これは、一条項BSDライセンスと等価ということです。もちろん、GNU GPLなどほとんど全てのオープン ソース ライセンスの下のプロジェクトにおいて共存可能です。FatFsからフォークを作成し公開する場合は、矛盾しない他のオープン ソース ライセンス(GNU GPLや修正BSDライセンスなど)に変更することも可能です。
-カレント ディレクトリを変更します。
--FRESULT f_chdir ( - const TCHAR* path /* [IN] ディレクトリ名へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_FILE, -FR_NO_PATH, -FR_INVALID_NAME, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_NOT_ENOUGH_CORE -
-各ボリュームのカレント ディレクトリを変更します。カレント ディレクトリは、そのボリュームのマウント動作が行われたとき、ルート ディレクトリに初期設定されます。カレント ディレクトリは、ファイル システム オブジェクトに保持されるため、そのボリュームを使用する全てのタスクに対して影響を与えます。
-_FS_RPATH == 1のときに使用可能となります。
-- /* カレント ドライブのカレント ディレクトリを変更 (ルート下のdir1へ) */ - f_chdir("/dir1"); - - /* ドライブ2のカレント ディレクトリを変更 (親ディレクトリへ) */ - f_chdir("2:.."); --
カレント ドライブを変更します。
--FRESULT f_chdrive ( - const TCHAR* path /* [IN] 対象ドライブを指定します */ -); --
-FR_OK, -FR_INVALID_DRIVE -
-カレント ドライブを変更します。システム起動時の初期値はドライブ0です。この設定はFatFsモジュールの静的変数に記録されるため、全てのタスクに対して影響を与えます。
-_FS_RPATH == 1で、且つ_VOLUMES > 1のときに使用可能となります。
-ファイルまたはサブ ディレクトリの属性を変更します。
--FRESULT f_chmod ( - const TCHAR* path, /* [IN] オブジェクト名へのポインタ */ - BYTE attr, /* [IN] 設定値 */ - BYTE mask /* [IN] 変更マスク */ -); --
値 | 意味 |
---|---|
AM_RDO | リード オンリー |
AM_ARC | アーカイブ |
AM_SYS | システム |
AM_HID | ヒドゥン |
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_FILE, -FR_NO_PATH, -FR_INVALID_NAME, -FR_WRITE_PROTECTED, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_LOCKED, -FR_NOT_ENOUGH_CORE -
-_FS_READONLY == 0で、且つ_FS_MINIMIZE == 0のとき使用可能です。
-
- /* リードオンリーをセット、アーカイブをクリア、その他は変更しない */
- f_chmod("file.txt", AM_RDO, AM_RDO | AM_ARC);
-
-ファイルを閉じます。
--FRESULT f_close ( - FIL* fp /* [IN] ファイル オブジェクトへのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_INVALID_OBJECT, -FR_TIMEOUT -
-ファイルを閉じます。何らかの書き込みの行われたファイルの場合、キャッシュされた状態(リード/ライト バッファ上のデータ、変更されたFATやディレクトリ項目)はディスクに書き戻されます。関数が正常終了すると、そのファイル オブジェクトは無効になり、そのメモリも解放できます。
-ファイル オブジェクトが読み出し専用モードで、_FS_LOCKオプションが選択されていない場合は、ファイルを閉じずにファイル オブジェクトを破棄することもできます。しかし、これは将来の互換性の点で推奨はされません。
-全ての構成で使用可能です。
-ディレクトリを閉じます。
--FRESULT f_closedir ( - DIR* dp /* [IN] ディレクトリ オブジェクトへのポインタ */ -); --
-FR_OK, -FR_INT_ERR, -FR_INVALID_OBJECT, -FR_TIMEOUT -
-ディレクトリを閉じます。関数が正常終了すると、そのディレクトリ オブジェクトは無効になり、そのメモリも解放できます。
-_FS_LOCKオプションが選択されていない場合は、この処理を行わずにディレクトリ オブジェクトを破棄することもできます。しかし、これは将来の互換性の点で推奨はされません。
-_FS_MINIMIZE <= 1のとき使用可能になります。
-FatFsには多くの構成オプションがあり、それぞれのプロジェクトの要求に応じて柔軟に機能を構成することができます。構成オプションは、ffconf.hに記述されます。
- -0:リード/ライト or 1:リード オンリ。リード オンリ構成では、f_write、f_sync、f_unlink、f_mkdir、f_chmod、f_rename、f_truncate、f_getfreeの基本API関数およびオプションの書き込み系API関数が削除されます。
- -基本API関数を段階的に削除します。
-値 | 解説 |
---|---|
0 | 全ての基本API関数が利用可能。 |
1 | f_stat、f_getfree、f_unlink、f_mkdir、f_chmod、f_utime、f_truncate、f_rename関数が削除される。 |
2 | 1に加え、f_opendir、f_readdir、f_closedir関数が削除される。 |
3 | 2に加え、f_lseek関数が削除される。 |
文字列入出力API関数f_gets, f_putc, f_puts and f_printfの構成。
-値 | 解説 |
---|---|
0 | 文字列入出力API関数を使用しない。 |
1 | 文字列入出力API関数を使用する。データのLF-CRLF変換はしない。 |
2 | 文字列入出力API関数を使用する。データのLF-CRLF変換をする。 |
フィルタ付きディレクトリ読み出し機能の構成(0:無効 または 1:有効)。有効にすると、f_findfirst、f_findnext関数が利用可能になります。_FS_MINIMIZEは、1以下でなければなりません。
- -ボリューム作成機能の構成(0:無効 または 1:有効)。有効にするとf_mkfs関数が利用可能になります。
- -高速シーク機能の構成(0:無効 または 1:有効)。有効にすると、f_lseek、f_read、f_write関数において高速化モードが利用可能になります。詳しくは、こちらを参照してください。
- -連続領域割り当て機能の構成(0:無効 または 1:有効)。有効にするとf_expand関数が利用可能になります。_FS_READONLYは0でなければなりません。
- -メタデータ操作機能の構成(0:無効 または 1:有効)。有効にすると、f_chmod、f_utime関数が利用可能になります。_FS_READONLYは0でなければなりません。
- -ボリューム ラベル操作機能の構成(0:無効 または 1:有効)。有効にすると、f_getlabel、f_setlabel関数(_FS_READONLY == 0のとき)が利用可能になります。
- -ストリーミング読み出し機能(f_forward関数)の構成(0:無効 または 1:有効)。
- -パス名等の文字列データのコード ページを指定します。不適切な設定は、ファイル オープン エラーの原因になる可能性があります。拡張文字が全く使われない場合は、どれを選んでも同じです。
-値 | 解説 |
---|---|
1 | ASCII (非LFN構成でのみ有効) |
437 | U.S. |
720 | Arabic |
737 | Greek |
771 | KBL |
775 | Baltic |
850 | Latin 1 |
852 | Latin 2 |
855 | Cyrillic |
857 | Turkish |
860 | Portuguese |
861 | Icelandic |
862 | Hebrew |
863 | Canadian French |
864 | Arabic |
865 | Nordic |
866 | Russian |
869 | Greek 2 |
932 | 日本語 (DBCS) |
936 | 簡体字中国語 (DBCS) |
949 | 韓国語 (DBCS) |
950 | 繁体字中国語 (DBCS) |
LFN(長いファイル名)対応を設定します。LFN機能を有効にするときは、Unicode操作関数option/unicode.cをプロジェクトに加える必要があります。また、LFN操作のワーク エリアとして(_MAX_LFN + 1) * 2バイト(exFAT構成時はさらに608バイト)を使用します。このため、バッファをスタックに確保するときは、スタック オーバ フローに注意する必要があります。ヒープに確保するときは、メモリ操作関数(ff_memallocとff_memfree(option/syscall.cにサンプルあり))をプロジェクトに加える必要があります。
-値 | 解説 |
---|---|
0 | LFN機能を使わない。8.3形式の名前のみ使用可能。 |
1 | LFN機能を使う。ワーク エリアは静的に確保。常にスレッド セーフではない。 |
2 | LFN機能を使う。ワーク エリアはスタックに確保。 |
3 | LFN機能を使う。ワーク エリアはヒープに確保。 |
LFN操作バッファのサイズを文字単位で指定(12~255)します。LFN機能が無効のときは意味を持ちません。
- -ファイルAPI上におけるUnicode対応機能を設定します。非LFN構成のときは、0でなければなりません。LFN構成のときに1を選択すると、ファイルAPI上の文字列データTCHAR型の定義が切り替わり、パス名等にUnicodeを使用するようになります。この機能は、文字列入出力関数にも影響します。詳しくは、こちらを参照してください。
- -Unicode API構成のとき、文字列入出力関数、f_gets、f_putc、f_puts、f_printf、におけるファイル上のエンコーディングを指定します。非Unicode API構成のときは意味を持ちません。
-値 | 解説 |
---|---|
0 | ANSI/OEM |
1 | UTF-16LE |
2 | UTF-16BE |
3 | UTF-8 |
相対パス機能を設定します。この機能は、ディレクトリ読み出し関数の出力にも影響します。詳しくは、こちらを参照してください。
-値 | 解説 |
---|---|
0 | 相対パス機能を使わない。パス名は常にルート ディレクトリから辿る。 |
1 | 相対パス機能を使う。f_chdir、f_chdrive関数が利用可能になる。 |
2 | 1に加え、f_getcwd関数が利用可能になる。 |
利用するボリューム(論理ドライブ)の数を1~9の範囲で設定します。
- -文字列ボリュームIDの設定(0:無効 または 1:有効)。パス名中のボリュームIDに数字に加え任意の文字列も使用できるようにするオプションです。ボリュームID文字列は_VOLUME_STRSで定義します。
- -ボリュームID文字列を定義します。_VOLUMESで設定された個数の文字列を"RAM","SD","CF",... のように挙列します。使用可能な文字はA~Zおよび0~9で、先頭の項目が論理ドライブ0に対応します。
- -マルチ区画機能の設定(0:無効 または 1:有効)。無効のときは、個々の論理ドライブは同じ番号の物理ドライブに1:1で対応し、それぞれの物理ドライブ中の最初の区画に結びつけられます。マルチ区画機能を有効にすると、論理ドライブはそれぞれ任意の物理ドライブの任意の区画に結びつけることができます。マッピングは、ユーザ定義の変換テーブルVolToPart[]によって行います。また、f_fdisk関数が利用可能になります。詳しくは、こちらを参照してください。
- -使用する物理ドライブのセクタ サイズ(データの読み書きの最小単位)を設定します。有効な値は、512、1024、2048、4096です。_MIN_SSは最小サイズ、_MAX_SSは最大サイズを設定します。メモリ カードやハードディスクでは、常に両方に512を設定しますが、オンボード メモリや一部の光学メディアでは大きな値を設定する必要があるかも知れません。_MAX_SS > _MIN_SSに設定したときは可変セクタ サイズ構成となり、disk_ioctl関数にはGET_SECTOR_SIZEコマンドを実装する必要があります。
- -ATA-TRIM機能の使用の設定(0:無効 または 1:有効)。この機能を有効にしたときは、disk_ioctl関数にCTRL_TRIMコマンドを実装するべきです。
- -FAT32ボリュームのFSINFOの使用の設定(0~3)。FAT32ボリュームで必ず正確な空き容量を取得する必要があるとき、設定値のビット0をセットするとf_getfree関数はFSINFOの情報を使わずに全FATスキャンを行って空き容量を得ます。ビット1は最終割り当てクラスタ番号の利用の制御です。
-値 | 解説 |
---|---|
bit0=0 | FSINFOの空きクラスタ情報が有効なときはそれを利用する。 |
bit0=1 | FSINFOの空きクラスタ情報を利用しない。 |
bit1=0 | FSINFOの最終割り当てクラスタ番号が有効なときはそれを利用する。 |
bit1=1 | FSINFOの最終割り当てクラスタ番号を利用しない。 |
ファイル データ転送バッファの構成(0:ノーマル または 1:タイニ)。タイニ構成では、ファイル オブジェクトFIL内のプライベート セクタ バッファが削除され、_MAX_SSバイト小さくなります。ファイル データの転送には、代わりにファイル システム オブジェクトFATFS内のボリューム共有セクタ バッファが使われます。
- -exFATのサポート(0:使用しない または 1:使用する)。exFATを使用するには、LFN機能を有効にしなければなりません。また、exFATの完全サポートのためには、_LFN_UNICODE = 1と_MAX_LFN = 255の設定が推奨されます。exFAT機能では64ビット整数を使用するため、これを有効にするとC89(ANSI C)互換が失われます。
- -RTC機能の使用の設定(0:使用する または 1:使用しない)。システムがRTC(カレンダ時計)をサポートしない場合は、1をセットします。この場合、FatFsが変更を加えたオブジェクトのタイムスタンプはデフォルトの日時を持ちます。RTCが使用可能なときは、0を設定し、get_fattime関数をプロジェクトに加えます。リード オンリ構成ではこのオプションは意味を持ちません。
- -デフォルト日時の設定。_FS_NORTCが1のとき、固定して与えられる日付を指定します。_FS_NORTCが0のとき、およびリード オンリ構成ではこれらのオプションは意味を持ちません。
- -ファイル ロック機能の設定。このオプションは、開かれたオブジェクトに対する不正な操作の制御機能を設定します。リード オンリ構成では0に設定しなければなりません。なお、ファイル ロック機能はリエントランシーとは関係ありません。
- -値 | 解説 |
---|---|
0 | ファイル ロック機能を使わない。ボリュームの破損を防ぐため、アプリケーションは不正なファイル操作を避けなければならない。 |
>0 | ファイル ロック機能を使う。数値は同時にオープンできるファイルやサブ ディレクトリの数を設定します。 |
リエントランシーの設定(0:無効 または 1:有効)。このオプションは、FatFsモジュール自体のリエントランシー(スレッド セーフ)の設定をします。異なるボリュームに対するファイル アクセスはこのオプションに関係なく常にリエントラントで、f_mount、f_mkfs、f_fdiskなどのボリューム操作関数はこのオプションに関係なく常にリエントラントではありません。同じボリュームに対するファイル アクセス(つまり、ファイル システム オブジェクトの排他使用)のみがこのオプションの制御下にあります。このオプションを有効にしたときは、同期関数であるff_req_grant、ff_rel_grant、ff_del_syncobj、ff_cre_syncobjをプロジェクトに追加する必要があります。サンプルがoption/syscall.cにあります。
- -タイムアウト時間の設定。待ち合わせ時間が長いときにFR_TIMEOUTでファイル関数をアボートする時間を設定します。_FS_REENTRANTが0のときは意味を持ちません。
- -O/S定義の同期オブジェクトの型を設定します。例: HANDLE、ID、OS_EVENT*、SemaphoreHandle_tなど。また、O/S機能のヘッダ ファイルをff.cのスコープ内にインクルードする必要があります。_FS_REENTRANTが0のときは意味を持ちません。
- -ストレージ デバイスを初期化します。
--DSTATUS disk_initialize ( - BYTE pdrv /* [IN] 物理ドライブ番号 */ -); --
この関数は戻り値としてディスク ステータスを返します。ディスク ステータスの詳細に関してはdisk_status関数を参照してください。
-ストレージ デバイスを初期化し、データの読み書きなど全ての動作が可能な状態にします。関数が成功すると、戻り値のSTA_NOINITフラグがクリアされます。
-この関数はFatFsの管理下にあり、自動マウント動作により必要に応じて呼び出されます。アプリケーションからはこの関数を呼び出してはなりません。さもないと、FATボリュームが破壊される可能性があります。再初期化が必要なときは、f_mount関数を使用してください。
-一般的なデータ読み書き以外のストレージ デバイス自体に対する様々な制御を行います。
--DRESULT disk_ioctl ( - BYTE pdrv, /* [IN] 物理ドライブ番号 */ - BYTE cmd, /* [IN] 制御コマンド */ - void* buff /* [I/O] データ受け渡しバッファ */ -); --
ストレージ デバイスの種類によりサポートされるコマンドは異なりますが、FatFsモジュール自体は、次の汎用コマンドのみ使用し、特定のデバイスに依存した制御は行いません。
-コマンド | 解説 |
---|---|
CTRL_SYNC | デバイスのデータ書き込み処理を完了させます。ドライバがライト バック キャッシュなどを持っている場合は、書き込まれていないデータを即時書き込みます。メディア上への書き込みがそれぞれdisk_write関数の中で完了する場合は、このコマンドに対してすることはありません。 |
GET_SECTOR_COUNT | 総セクタ数の取得。buffの指すDWORD型変数にドライブ上の総セクタ数を返します。f_mkfs, f_fdisk関数内から呼び出され、作成するボリュームのサイズを決定するために使用されます。 |
GET_SECTOR_SIZE | セクタ サイズの取得。セクタ サイズ可変(_MAX_SS > _MIN_SS)のとき、disk_initailize関数の成功に続き呼び出されるので、buffの指すWORD型変数に現在のセクタ サイズを返します。有効値は512、1024、2048または4096です。セクタ サイズ固定(_MAX_SS == _MIN_SS)のときはこのコマンドは使われることはなく、デバイスは常にそのセクタ サイズで動作しなければなりません。 |
GET_BLOCK_SIZE | 消去ブロック サイズの取得。buffの指すDWORD型変数にフラッシュ メモリの消去ブロック サイズ(セクタ単位)を返します。1から32768の範囲で2の累乗の値でなければなりません。ブロック サイズ不明またはフラッシュ メモリ以外のデバイスでは1を返します。f_mkfs関数内でのみ使用され、作成されるボリュームのデータ領域はこの境界にアライメントされます。 |
CTRL_TRIM | 不必要セクタの通知。buffの指すDWORD型配列には不必要になった領域 {開始セクタ,終了セクタ} を指定して呼び出されます。TRIM機能が有効(_USE_TRIM == 1)で、クラスタが解放されるとき、およびフォーマット時に呼び出されます。これは、ATAコマンド セットのTrimコマンドと等価で、この機能をサポートしないデバイスは何もする必要はありません。また、戻り値はチェックされず、結果によってFatFsの動作が影響を受けることはありません。 |
FatFs自体はデバイス依存コマンドやユーザ定義コマンドは一切使用しませんが、アプリケーションから何らかのデバイス制御が行えると便利なことがあります。アプリケーション上で標準以外の制御が必要なときは、必要に応じてユーザ定義コマンドを追加して利用するとよいでしょう。次にコマンドの例を示します。
-コマンド | 解説 |
---|---|
CTRL_FORMAT | メディアの物理フォーマットを行います。buffはNULLでないとき、進行表示のためのコールバック関数のアドレスを示します。 |
CTRL_POWER_IDLE | デバイスをアイドル状態にします。通常の読み書き要求でアクティブ状態に戻るなら、STA_NOINITフラグをセットする必要はありません。 |
CTRL_POWER_OFF | デバイスをシャットダウン状態にします。STA_NOINITはセットされます。デバイスはdisk_initialize関数でアクティブ状態に戻ります。 |
CTRL_LOCK | ユーザによるメディアの取り出しを禁止します。 |
CTRL_UNLOCK | ユーザによるメディアの取り出しを許可します。 |
CTRL_EJECT | メディアを排出します。完了後、STA_NOINITとSTA_NODISKフラグはセットされます。 |
MMC_GET_TYPE | カード タイプを示すフラグ(b0:MMCv3, b1:SDv1, b2:SDv2+, b3:LBA)をbuffの示すBYTE変数に読み出します。(MMC/SDカード専用) |
MMC_GET_CSD | CSDレジスタの内容をbuffの示す16バイトのバッファに読み出します。(MMC/SDカード専用) |
MMC_GET_CID | CIDレジスタの内容をbuffの示す16バイトのバッファに読み出します。(MMC/SDカード専用) |
MMC_GET_OCR | OCRレジスタの内容をbuffの示す4バイトのバッファに読み出します。(MMC/SDカード専用) |
MMC_GET_SDSTAT | SD STATUSレジスタの内容をbuffの示す64バイトのバッファに読み出します。(SDカード専用) |
ATA_GET_REV | リビジョン コードをbuffの示す16バイトのバッファに読み出します。(ATA/CFカード専用) |
ATA_GET_MODEL | モデル コードをbuffの示す40バイトのバッファに読み出します。(ATA/CFカード専用) |
ATA_GET_SN | シリアル番号をbuffの示す20バイトのバッファに読み出します。(ATA/CFカード専用) |
ISDIO_READ | buffの示すコマンド構造体に従いiSDIOレジスタからデータを読み出します。(FlashAir専用) |
ISDIO_WRITE | buffの示すコマンド構造体に従いiSDIOレジスタにデータを書き込みます。(FlashAir専用) |
ISDIO_MRITE | buffの示すコマンド構造体に従いiSDIOレジスタの一部のビットを書き換えます。(FlashAir専用) |
リード オンリー構成で、かつセクタ サイズ固定構成のときは、この関数は必要とされません。
-ストレージ デバイスからデータを読み出します。
--DRESULT disk_read ( - BYTE pdrv, /* [IN] 物理ドライブ番号 */ - BYTE* buff, /* [OUT] 読み出しバッファへのポインタ */ - DWORD sector, /* [IN] 読み出し開始セクタ番号 */ - UINT count /* [IN] 読み出すセクタ数 */ -); --
ストレージ デバイスに対するデータの読み書きは、セクタ単位で行われます。FatFsでは512~4096バイトのセクタ サイズをサポートします。固定セクタ サイズ構成(_MIN_SS == MAX_SS)のときは、暗黙的にそのセクタ サイズで動作しなければなりません。可変セクタ サイズ構成(_MIN_SS < MAX_SS)のときは、disk_initialize関数に続いてdisk_ioctl関数でセクタ サイズを問い合わせてくるので、それに対して正しい値を返す必要があります。
-buffはBYTE型なので、指定されるアドレスは常にワード アライメントされているとは限りません。非アライメント アドレスへの転送は、直接転送において発生することがあります。もしも、ハードウェア上の制約でそのような転送が不可能なときは、この関数内で二段転送するなどして解決するか、または別の方法で対応しなければなりません。次にいくつかの対応方法を示します(いずれか一つでOK)。
-一般的に、複数セクタの転送要求は、ストレージ デバイスに対して可能な限りマルチ セクタ転送しなければなりません。複数のシングル セクタ読み出しに分解された場合、スループットが低下することがあります。
-ストレージ デバイスの状態を取得します。
--DSTATUS disk_status ( - BYTE pdrv /* [IN] 物理ドライブ番号 */ -); --
現在のストレージ デバイスの状態を次のフラグの組み合わせ値で返します。
-ストレージ デバイスにデータを書き込みます。
--DRESULT disk_write ( - BYTE pdrv, /* [IN] 物理ドライブ番号 */ - const BYTE* buff, /* [IN] 書き込むデータへのポインタ */ - DWORD sector, /* [IN] 書き込み開始セクタ番号 */ - UINT count /* [IN] 書き込むセクタ数 */ -); --
buffに指定されるアドレスは常にワード アライメントされているとは限りません。これについては、disk_read関数の解説を参照してください。
-一般的に、複数セクタの転送要求は、デバイスに対して可能な限りマルチ セクタ転送しなければなりません。複数のシングル セクタ書き込みに分解された場合、スループットが著しく低下することがあります。
-FatFsはディスク制御レイヤが遅延書き込み機能を持つことも想定しています。この関数から戻るとき、デバイスが書き込みを実行中だったり単にライトバック キャッシュに書き込まれただけなど、必ずしもメディアへの書き込みが完了している必要はありません。ただし、buffのデータは、この関数から戻ると無効となります。書き込み完了の要求は、disk_ioctl関数のCTRL_SYNCコマンドによって行われます。このような遅延書き込み機能が実装された場合、書き込みスループットを向上させることができます。
-アプリケーションからはこの関数を呼び出してはなりません。さもないと、FATボリュームが破壊される可能性があります。
-リード オンリー構成(_FS_READONLY == 1)ではこの関数は必要とされません。
-リード/ライト ポインタがファイル終端に達しているかどうか調べます。.
--int f_eof ( - FIL* fp /* [IN] ファイル オブジェクト */ -); --
リード/ライト ポインタがファイル終端にあり読み出すデータがない場合は、0以外の値を返します。それ以外のときは0を返します。
-この関数は、現リビジョンではマクロとして実装されています。ファイル オブジェクトの正当性チェックや排他制御は行いません。
-
-#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
-
-常に使用可能。
-エラー発生の有無を調べます。
--int f_error ( - FIL* fp /* [IN] ファイル オブジェクト */ -); --
そのファイルにおいてハード エラーによって処理が中断されている場合は、0以外の値を返します。それ以外の時は0を返します。
-この関数は、現リビジョンではマクロとして実装されています。ファイル オブジェクトの正当性チェックや排他制御は行いません。
-
-#define f_error(fp) ((fp)->err)
-
-常に使用可能。
-ファイルに連続したデータ領域を割り当てます。
- --FRESULT f_expand ( - FIL* fp, /* [IN] ファイル オブジェクト構造体へのポインタ */ - FSIZE_t fsz, /* [IN] 割り当てサイズ */ - BYTE opt /* [IN] 動作オプション */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_INVALID_OBJECT, -FR_DENIED, -FR_TIMEOUT -
-optに1を指定すると、ファイルに連続したデータ領域を割り当てます。f_lseekによるサイズ拡張とは異なり、対象ファイルのサイズは0(つまりデータ領域未割り当て)でなければなりません。また、リード/ライト ポインタは、ファイル先頭に留まります。この関数により割り当てられたファイルの内容は未定義なので、それに対して何の前提も持つべきではありません。この関数は、次の理由によりFR_DENIEDで失敗することがあります。
-optに0を指定したときは、連続したデータ領域を探すのみで、その時点ではファイルへの割り当てを行わず、代わりにそれを検索開始ポイントとしてファイル システム オブジェクトにセットします。これにより、そのボリューム上で別の操作(FAT変更を伴う)が行われない限り、書き込まれるファイルは少なくともそのサイズまでは連続性が保証され、遅延無く書き込めることになります。
-時間的制約のあるファイル読み書き操作において、連続データ領域を割り当てられたファイルは有利となります。これは、分割されたファイルによりもたらされる無用なランダム アクセスが減ることにより、ファイル システムやストレージ デバイスの処理のオーバーヘッドが削減されるからです。特にexFATボリューム上の連続ファイルでは一切のFATアクセスが発生せず、効率的なシーケンシャル アクセスが行えます。
-連続ファイルに対して低レベルI/Oを使用したさらに効率的な直接アクセスも容易に行えますが、これは将来の互換性の点で推奨はされません。
-_USE_EXPAND == 1で、かつ_FS_READONLY == 0のとき使用可能です。
-- /* 連続ファイルの作成 */ - - /* 新しいファイルの作成 */ - res = f_open(fp = malloc(sizeof (FIL)), "file.dat", FA_WRITE|FA_CREATE_ALWAYS); - if (res) { /* ファイルが開かれたかチェック */ - free(fp); - ... - } - - /* 100 MiB の連続領域を割り当てる */ - res = f_expand(fp, 104857600, 1); - if (res) { /* 割り当てられたかチェック */ - ... - free(fp); - ... - } - /* 連続ファイル作成成功 fp でアクセス可能 */ - --
- /* ファイル システムを介さず直接アクセスする例 */ - - /* ファイル データの物理的位置を取得 */ - drv = fp->obj.fs->drv; - sect = fp->obj.fs->database + fp->obj.fs->csize * (fp->obj.sclust - 2); - - /* ファイル先頭から2048セクタを書き込み */ - res = disk_write(drv, buffer, sect, 2048); - --
現在時刻を取得します。
--DWORD get_fattime (void); --
現在のローカル タイムをDWORD値にパックして返します。ビット フィールドは次に示すようになります。
-RTCをサポートしないシステムでも、ダミーとして何らかの日付として有効な値を返すべきです。0などを返した場合、そのファイルのタイムスタンプは無効になります。
-リード オンリー構成(_FS_READONLY == 1)または、非RTCサポート構成(_RTC_NOUSE == 1)ではこの関数は必要とされません。
-物理ドライブを分割します。
--FRESULT f_fdisk ( - BYTE pdrv, /* [IN] 物理ドライブ番号 */ - const DWORD* szt, /* [IN] 区画サイズ テーブル */ - void* work /* [-] ワークエリア */ -); --
-FR_OK, -FR_DISK_ERR, -FR_NOT_READY, -FR_WRITE_PROTECTED, -FR_INVALID_PARAMETER -
-この関数は、指定された物理ドライブのMBRに区画テーブルを作成します。区画分けは一般的なFDISK形式で行うため、最大4つの基本区画を作成することができます。拡張区画には対応していません。区画サイズ テーブルにはドライブをどのように分割するか指定します。この配列は4つの項目から成り、先頭の項目が1番目の区画のサイズを示します。項目の値が100以下の場合、その区画のドライブの総容量に対する割合をパーセント単位で指定します。100を超える値の場合はセクタ数の直接指定になります。ドライブ上への区画の配置順は、項目順になります。
-_FS_READOLNY == 0 で _USE_MKFS == 1 で _MULTI_PARTITION == 1 のとき使用可能です。
-- /* ユーザ定義のボリューム管理テーブル (_MULTI_PARTITION == 1 のとき必要) */ - - PARTITION VolToPart[] = { - {0, 1}, /* 論理ドライブ 0 ==> 物理ドライブ 0, 第1区画 */ - {0, 2}, /* 論理ドライブ 1 ==> 物理ドライブ 0, 第2区画 */ - {1, 0} /* 論理ドライブ 2 ==> 物理ドライブ 1, 自動検出 */ - }; --
- /* 新しい物理ドライブ(0)の初期化 */ - - FATFS fs; - DWORD plist[] = {50, 50, 0, 0}; /* 第1区画,第2区画それぞれに50%ずつ割り当て */ - BYTE work[_MAX_SS]; - - f_fdisk(0, plist, work); /* 物理ドライブ 0 の分割 */ - - f_mkfs("0:", FMT_ANY, work, sizeof work); /* 論理ドライブ 0: のフォーマット */ - f_mkfs("1:", FMT_ANY, work, sizeof work); /* 論理ドライブ 1: のフォーマット */ - --
FatFsモジュールでは、パス名によるファイル、ディレクトリ、ドライブの指定方法はDOS/Windows APIとほぼ同じです。パス名のフォーマットは次の通りです。
-"[論理ドライブ番号:][/]ディレクトリ名/ファイル名"-
FatFsモジュールは長いファイル名(LFN)および8.3形式ファイル名(SFN)に対応しています。LFNは、(_USE_LFN > 0)のとき使用可能になります。ディレクトリ セパレータにはDOS/Windows APIと同じく'/'と'\'を使用します。連続したセパレータは無視され1個として扱われます。唯一の違いは、論理ドライブの指定だけです。論理ドライブ番号は、'0'~'9'の一文字の数字とコロンで指定し、省略した場合はデフォルト ドライブ(0またはカレント ドライブ)が選択されます。
-ヌル文字や制御文字('\0'~'\x1F')は、パス名の終端として認識されます。パス名に先行あるいは中に含まれるスペースは、LFN構成では名前の一部として有効ですが、非LFN構成ではスペースはパス名の終端として認識されます。
-標準構成(_FS_RPATH == 0)のときは、全てのオブジェクトがルート ディレクトリから辿る絶対パスで指定されます。OS指向なカレント ディレクトリという概念は無く、またドット ディレクトリ("."や"..")は使用できません。パス名先頭のセパレータは無視されます。デフォルト ドライブ番号は常に0になります。
-相対パスを有効(_FS_RPATH >= 1)にしたときは、先行するセパレータの有無によって検索開始ディレクトリが変わり、セパレータがある場合はルート ディレクトリから、無い場合はf_chdir関数で設定されるカレント ディレクトリからになります。またパス名にドット ディレクトリが使用できます。デフォルト ドライブ番号はf_chdrive関数で設定された値となります。
-パス名の例 | _FS_RPATH == 0 | _FS_RPATH >= 1 |
file.txt | ドライブ0のルート ディレクトリ下のファイル | カレント ドライブのカレント ディレクトリ下のファイル |
/file.txt | ドライブ0のルート ディレクトリ下のファイル | カレント ドライブのルート ディレクトリ下のファイル |
ドライブ0のルート ディレクトリ | カレント ドライブのカレント ディレクトリ | |
2: | ドライブ2のルート ディレクトリ | ドライブ2のカレント ディレクトリ |
2:file1.txt | ドライブ2のルート ディレクトリ下のファイル | ドライブ2のカレント ディレクトリ下のファイル |
2:/ | ドライブ2のルート ディレクトリ | ドライブ2のルート ディレクトリ |
../file.txt | 無効 | 親ディレクトリ下のファイル |
. | 無効 | このディレクトリ |
.. | 無効 | カレント ディレクトリの親ディレクトリ |
dir1/.. | 無効 | カレント ディレクトリ |
/.. | 無効 | ルート ディレクトリ(その上は辿れない) |
また、_STR_VOLUME_IDオプションを有効にすることでドライブ番号の識別には数字のほか、"sd:file1.txt"や"ram:swapfile.dat"のように、任意の文字列(もちろんDOS/Windowsライクなドライブ文字も)を使用することも可能になります。
-【注意】現リビジョン(R0.12)では、exFATボリューム上においてダブル ドット".."はシングル ドット"."として機能し、親ディレクトリを辿ることはできません。
-FATファイル システムでファイル名に使用可能な文字は、0~9 A~Z ! # $ % & ' ( ) - @ ^ _ ` { } ~および拡張文字(\x80~\xFF)となっています。LFN拡張ではこれらに加え、+ , ; = [ ]およびスペースが使用可能になり、スペースとピリオドはファイル名の末尾を除く任意の位置に挿入できます。
-FATファイル システムでは、パス名についてケース インセンシティブです。たとえば、file.txt, File.Txt, FILE.TXTの3つの名前は同じ物として扱われます。これは、ASCII文字だけでなく拡張文字についても適用されます。ファイルが作成される際、SFNエントリには全て大文字に変換された名前が記録されます。LFN対応システムでは、LFNエントリには大文字変換されない名前が記録されます。
-古い日本語MS-DOSでは拡張文字(いわゆる全角文字)についてはケース センシティブでした。FatFsモジュールではこれにしたがい、非LFN構成で文字コードにDBCSが選択されたときに限り、拡張文字に対して大文字変換を行わずにSFNエントリに記録および検索されます(日本語MSDOS仕様)。LFN構成では拡張文字についても大文字変換を行います(WindowsNT仕様)。このため、非LFN構成で全角小文字を含む名前でファイルを作成すると、Windowsでそのファイルを開けなくなるなどの互換性問題を起こすので、それらのシステムで相互利用するボリューム上ではDBCS拡張文字の使用は避けるべきです。
-ファイル関数の入出力のうちファイル名やパス名を指定する引数の型は、TCHARで定義されていますが、これは通常はcharのエリアスになっています。そして、_CODE_PAGEで指定されるANSI/OEMコード(SBCSまたはDBCS)の文字列として扱われます。ファイル名入出力をUnicodeとする構成(_LFN_UNICODE == 1)にしたときは、TCHARはワイド文字(WCHAR, unsigned short)に切り替わり、パス名の入出力にUnicodeを使用するようになります。これによりLFN規格に完全対応となり、ファイル名としてANSI/OEMコードにない文字(たとえば ✝☪✡☸☭など)も使用できます。この設定は文字列入出力関数においては、データ型とファイル上のエンコーディングに影響を与えます。リテラル文字列を定義するとき、次に示すように_T(s)および_TEXT(s)マクロを使ってANSI/OEMとUnicodeを自動切り替えすることができます。
-- f_open(fp, "filename.txt", FA_READ); /* ANSI/OEM専用コード */ - f_open(fp, L"filename.txt", FA_READ); /* Unicode専用コード */ - f_open(fp, _T("filename.txt"), FA_READ); /* 両用コード(自動切り替え) */ --
デフォルトの構成では、それぞれの論理ドライブは同じ番号の物理ドライブに1:1で結びつけられていて、自動検出機能によりその物理ドライブ上の一つのFATボリュームがマウントされます。FATボリュームの検出は、セクタ0(SFD)、第一区画~第四区画(FDISK)の順に行われます。
-_MULTI_PARTITIONに1を指定すると、それぞれの論理ドライブに対して個別に物理ドライブ番号と区画を指定できるようになります。この構成では、論理ドライブと区画の対応を解決するためのテーブルを次に示すように定義する必要があります。
--例:論理ドライブ0~2を物理ドライブ0(非リムーバブル)の3つの基本区画に割り当て、 - 論理ドライブ3を物理ドライブ1(リムーバブル)に割り当てる場合。 - -PARTITION VolToPart[] = { - {0, 1}, /* "0:" ==> 物理ドライブ 0, 第1区画 */ - {0, 2}, /* "1:" ==> 物理ドライブ 0, 第2区画 */ - {0, 3}, /* "2:" ==> 物理ドライブ 0, 第3区画 */ - {1, 0} /* "3:" ==> 物理ドライブ 1, 自動検出 */ -}; --
複数区画指定を使用する場合、次の点に注意しなければなりません。 -
ディレクトリ内のオブジェクトの検索を開始します。
--FRESULT f_findfirst ( - DIR* dp, /* [OUT] ディレクトリ オブジェクト構造体へのポインタ */ - FILINFO* fno, /* [OUT] ファイル情報構造体へのポインタ */ - const TCHAR* path, /* [IN] ディレクトリ名へのポインタ */ - const TCHAR* pattern /* [IN] マッチ パターン文字列へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_PATH, -FR_INVALID_NAME, -FR_INVALID_OBJECT, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE, -FR_TOO_MANY_OPEN_FILES -
-pathで指定されるディレクトリを開き、そのディレクトリ内の項目の検索を開始します。正常終了すると、ディレクトリ オブジェクト構造体が作成され、最初に検索名文字列に名前がマッチした項目の情報がfnoの指定するファイル情報構造体にストアされます。名前のマッチする項目が見つからなかった場合は、fno->fname[]にヌル文字列が返されます。ファイル情報構造体の使い方については、f_readdir関数を参照してください。
-マッチ パターン文字列は、ワイルドカード文字(?と*)を含むことができます。?は任意の1文字に、*は0文字以上の任意の文字列にマッチします。LFN構成では、_USE_FIND = 1のときfname[]のみテストし、_USE_FIND = 2のときはaltname[]もテストします。現リビジョンではパターン マッチングにおいて次の点で標準システムとは異なる動作となります。
--/* ディレクトリ内のオブジェクトの検索と表示 */ - -void find_image (void) -{ - FRESULT fr; /* API戻り値 */ - DIR dj; /* ディレクトリ オブジェクト */ - FILINFO fno; /* ファイル情報 */ - - fr = f_findfirst(&dj, &fno, "", "dsc*.jpg"); /* "dsc"で始まるJPEGファイルを検索 */ - - while (fr == FR_OK && fno.fname[0]) { /* 見つかる間繰り返し */ - printf("%s\n", fno.fname); /* 見つけた項目の名前を表示 */ - fr = f_findnext(&dj, &fno); /* 次を検索 */ - } - f_closedir(&dj); -} --
次にマッチするオブジェクトを検索します。
--FRESULT f_findnext ( - DIR* dp, /* [IN] ディレクトリ構造体へのポインタ */ - FILINFO* fno /* [OUT] ファイル情報構造体へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_INVALID_OBJECT, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE -
-次に名前のマッチするディレクトリ項目を検索し、見つかった項目をファイル情報構造体にストアします。名前のマッチする項目が見つからずディレクトリの最後まで達した場合は、fno->fname[]にヌル文字列が返されます。
-この関数は、f_readdir関数のラッパー関数です。_USE_FIND >= 1で、かつ_FS_MINIMIZE <= 1のとき使用可能になります。
-ファイルからデータを読み出し、送信ストリームに直接転送します。
--FRESULT f_forward ( - FIL* fp, /* [IN] ファイル オブジェクト構造体 */ - UINT (*func)(const BYTE*,UINT), /* [IN] データ転送関数 */ - UINT btf, /* [IN] 転送するバイト数 */ - UINT* bf /* [OUT] 転送されたバイト数 */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_DENIED, -FR_INVALID_OBJECT, -FR_TIMEOUT -
-ファイルのデータをバッファに読み出さずに送信ストリームに直接転送します。アプリケーション側でデータ バッファを必要としないので、メモリの限られた環境で有効です。リード/ライト ポインタは転送されたバイト数だけ進みます。指定されたバイト数の転送中にファイルの終端に達した場合や送信ストリームがビジーになった場合、*bfはbtfよりも小さくなります。
-_USE_FORWARD == 1のときに使用可能です。
--/*-----------------------------------------------------------------------*/ -/* f_forward関数から呼ばれるデータ送信関数の例 */ -/*-----------------------------------------------------------------------*/ - -UINT out_stream ( /* 戻り値: 転送されたバイト数またはストリームの状態 */ - const BYTE *p, /* 転送するデータを指すポインタ */ - UINT btf /* >0: 転送を行う(バイト数). 0: ストリームの状態を調べる */ -) -{ - UINT cnt = 0; - - - if (btf == 0) { /* センス要求 */ - /* ストリームの状態を返す (0: ビジー, 1: レディ) */ - /* 一旦、レディを返したら、続く転送要求で少なくとも1バイトは */ - /* 転送されないと f_forward関数は FR_INT_ERR となる。 */ - if (FIFO_READY) cnt = 1; - } - else { /* 転送要求 */ - do { /* 全てのバイトを転送するか、ストリームがビジーになるまで繰り返す */ - FIFO_PORT = *p++; - cnt++; - } while (cnt < btf && FIFO_READY); - } - - return cnt; -} - - -/*-----------------------------------------------------------------------*/ -/* f_forward関数の使用例 */ -/*-----------------------------------------------------------------------*/ - -FRESULT play_file ( - char *fn /* 再生するオーディオ ファイル名を指すポインタ */ -) -{ - FRESULT rc; - FIL fil; - UINT dmy; - - /* ファイルを読み出しモードで開く */ - rc = f_open(&fil, fn, FA_READ); - if (rc) return rc; - - /* 全てのデータが転送されるかエラーが発生するまで続ける */ - while (rc == FR_OK && !f_eof(&fil)) { - - /* ほかの処理... */ - - /* 定期的または要求に応じてデータをストリームに送出する */ - rc = f_forward(&fil, out_stream, 1000, &dmy); - } - - /* ファイルを閉じて戻る */ - f_close(&fil); - return rc; -} --
カレント ディレクトリを得ます。
--FRESULT f_getcwd ( - TCHAR* buff, /* [OUT] バッファ */ - UINT len /* [IN] バッファ サイズ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE -
-カレント ドライブのカレント ディレクトリのフル パス文字列を取得します。_VOLUMESが2以上のときは、論理ドライブ番号の付加されたパス名となります。
-現リビジョン(R0.12)では、exFATボリューム上ではカレント ディレクトリを得ることが出来ません。常にルート ディレクトリを返します。
-_FS_RPATH == 2のとき使用可能です。
-ボリューム上の空き領域のサイズを取得します。
--FRESULT f_getfree ( - const TCHAR* path, /* [IN] 対象ドライブを指定します */ - DWORD* nclst, /* [OUT] 空きクラスタ数を格納する変数へのポインタ */ - FATFS** fatfs /* [OUT] ファイル システム オブジェクトを指すポインタへのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT -
-論理ドライブ上の空き領域のサイズをクラスタ単位で取得します。返されたファイル システム オブジェクトのcsizeメンバがクラスタあたりのセクタ数を示しているので、これを元にセクタ単位の空きサイズが計算できます。FAT32ボリュームにおいては、FSINFOの情報が実際の空きクラスタ数と同期していない場合、不正確な値を返す可能性があります。この問題を避けるため、_FS_NOFSINFOオプションでマウント後の初回は必ずフルFATスキャンをするように構成することもできます。
-_FS_READONLY == 0で、且つ_FS_MINIMIZE == 0のとき使用可能です。
-- FATFS *fs; - DWORD fre_clust, fre_sect, tot_sect; - - - /* ドライブ1のボリューム情報と空きクラスタ数を得る */ - res = f_getfree("1:", &fre_clust, &fs); - if (res) die(res); - - /* 全セクタ数と空きセクタ数を計算 */ - tot_sect = (fs->n_fatent - 2) * fs->csize; - fre_sect = fre_clust * fs->csize; - - /* ボリュームのサイズと空きサイズを表示 (512バイト/セクタと仮定) */ - printf("%10lu KiB total drive space.\n%10lu KiB available.\n", - tot_sect / 2, fre_sect / 2); --
ボリューム ラベルを取得します。
--FRESULT f_getlabel ( - const TCHAR* path, /* [IN] 対象ドライブ */ - TCHAR* label, /* [OUT] ボリューム名を格納するバッファ */ - DWORD* vsn /* [OUT] ボリューム シリアル番号を格納する変数 */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT -
-_USE_LABEL == 1のときに使用可能です。
-- char str[24]; - - /* デフォルト ドライブのボリューム名を得る */ - f_getlabel("", str, 0); - - /* ドライブ2のボリューム名を得る */ - f_getlabel("2:", str, 0); --
ファイルから文字列を読み出します。
--TCHAR* f_gets ( - TCHAR* buff, /* [OUT] バッファ */ - int len, /* [IN] バッファのサイズ */ - FIL* fp /* [IN] ファイル オブジェクト */ -); --
関数が成功するとbuffが返されます。
-読み出し動作は、最初の'\n'を読み込むか、ファイル終端に達するか、len - 1文字を読み出すまで続きます。読み込まれた文字列の終端には'\0'が付加されます。既にファイル終端で1文字も読み込まれなかったとき、または何らかのエラーが発生したときは関数は失敗しヌル ポインタを返します。ファイル終端かエラーかはf_eof/f_error関数で調べられます。
-Unicode API構成(_LFN_UNICODE == 1)が選択されているときは、buffはUTF-16文字列になりますが、ファイル上のエンコードは、_STRF_ENCODEオプションで選択できます。それ以外の時は無変換(1バイト/1文字)で読み出します。
-この関数はf_read関数のラッパー関数です。_USE_STRFUNCが1または2のとき使用可能です。2のときは、ファイルに含まれる'\r'が取り除かれてバッファに読み込まれます。
-ファイルのリード/ライト ポインタを移動します。また、高速シーク機能使用時にはCLMT(後述)の作成にも使用します。
--FRESULT f_lseek ( - FIL* fp, /* [IN] ファイル オブジェクト構造体へのポインタ */ - FSIZE_t ofs /* [IN] 移動先オフセット */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_INVALID_OBJECT, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE -
-ファイルのリード/ライト ポインタ(次に読み出し・書き込みされるバイトのオフセット)を移動します。オフセットの原点はファイル先頭です。書き込みモードでファイル サイズより大きな値を指定すると、そこまでファイル サイズが拡張され、拡張された部分のデータは未定義となります。データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイル サイズを拡張しておくと良いでしょう。ファイルに連続したデータ領域を割り当てる必要があるときは、f_expand関数を使用してください。f_lseek関数が正常終了したあとは、リード/ライト ポインタが正しく移動したかチェックするべきです。リード/ライト ポインタが指定より小さいときは、次の原因が考えられます。
-高速シーク モードは、ファイルのクラスタ配置情報(CLMT)をメモリ上に保持しておくことにより、FATにアクセスすることなく後方シークやロング シークを高速に行う機能で、シーク動作のほかf_read/f_wtite関数の動作にも適用されます。ファイルが高速シーク モードの間はf_wtite/f_lseek関数によるファイル サイズの拡張はできません。
-高速シーク モードは、ファイル オブジェクトのメンバcltbl(f_open関数でNULLになる)にNULL以外を設定したとき有効になるので、まずCLMTを作成しておく必要があります。これを作成するには、まずCLMT格納バッファ(DWORD型配列)を準備し、cltblにそのポインタをセットします。そして、配列の先頭要素にその配列のサイズ(要素数)を入れ、f_lseek関数をofsにCREATE_LINKMAPを指定して呼び出します。関数が成功するとCLMTが作成され、以降のf_read/f_write/f_lseek関数ではFATへのアクセスは発生しません。CLMTの先頭要素には実際に使用した(または必要となる)要素数が返されます。使用される要素数は、(ファイルの分割数 + 1) * 2 です。たとえば、ファイルが5つのフラグメントに分断されているときは、12要素が使用されます。FR_NOT_ENOUGH_COREで失敗したときは、配列サイズが不足です。
-_FS_MINIMIZE < 3のとき使用可能です。高速シーク モードを利用するときは、_USE_FASTSEEK == 1である必要があります。
-- /* ファイルを開く */ - fp = malloc(sizeof (FIL)); - res = f_open(fp, "file.dat", FA_READ|FA_WRITE); - if (res) ... - - /* ファイル オフセット5000へ移動 */ - res = f_lseek(fp, 5000); - - /* ファイル終端へ移動(ファイル追記の準備) */ - res = f_lseek(fp, f_size(fp)); - - /* 3000バイト進める */ - res = f_lseek(fp, f_tell(fp) + 3000); - - /* 2000バイト戻す (ラップアラウンドに注意) */ - res = f_lseek(fp, f_tell(fp) - 2000); --
-/* クラスタ先行割り当て (ストリーミング ライト時のバッファ オーバーラン防止) */ - - res = f_open(fp, "record.wav", FA_CREATE_NEW | FA_WRITE); /* ファイル作成 */ - - res = f_lseek(fp, MAX_SIZE); /* 十分なクラスタの先行割り当て */ - if (res || f_tell(fp) != PRE_SIZE) ... /* 正しくファイルが拡張されたかチェック */ - - res = f_lseek(fp, DATA_START); /* データ ストリームの記録(アロケーションディレイ無し) */ - ... - - res = f_truncate(fp); /* 不要領域の切り捨て */ - res = f_lseek(fp, 0); /* ヘッダの記録 */ - ... - - res = f_close(fp); --
-/* 高速シーク機能を使う */ - - DWORD clmt[SZ_TBL]; /* リンク マップ テーブル格納バッファ */ - - res = f_open(fp, fname, FA_READ | FA_WRITE); /* ファイルを開く */ - - res = f_lseek(fp, ofs1); /* 通常シーク (オープン時、cltblはNULLに初期化される) */ - - fp->cltbl = clmt; /* 高速シーク機能の有効化 */ - clmt[0] = SZ_TBL; /* 先頭要素に配列要素数をセット */ - res = f_lseek(fp, CREATE_LINKMAP); /* CLMTの作成 */ - ... - - res = f_lseek(fp, ofs2); /* 以降、f_read/f_write/f_lseekでFATアクセスは発生しない */ --
サブ ディレクトリを作成します。
--FRESULT f_mkdir ( - const TCHAR* path /* [IN] 作成するディレクトリ名へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_PATH, -FR_INVALID_NAME, -FR_DENIED, -FR_EXIST, -FR_WRITE_PROTECTED, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE -
-空のサブ ディレクトリを作成します。ディレクトリを削除するときはf_unlink関数を使用してください。
-_FS_READONLY == 0で、且つ_FS_MINIMIZE == 0のとき使用可能です。
-- res = f_mkdir("sub1"); - if (res) die(res); - res = f_mkdir("sub1/sub2"); - if (res) die(res); - res = f_mkdir("sub1/sub2/sub3"); - if (res) die(res); --
論理ドライブ上にFAT/exFATボリュームを作成(フォーマット)します。
--FRESULT f_mkfs ( - const TCHAR* path, /* [IN] 論理ドライブ番号 */ - BYTE opt, /* [IN] フォーマット オプション */ - DWORD au, /* [IN] クラスタ サイズ */ - void* work, /* [-] ワーク エリア */ - UINT len /* [IN] ワーク エリアのサイズ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_NOT_READY, -FR_MKFS_ABORTED, -FR_INVALID_PARAMETER -
-exFAT以外のボリュームのFATタイプ(FAT12/FAT16/FAT32)は、そのボリューム上のクラスタ数によってのみ決定される決まり[FAT仕様書より]になっていて、それ以外の要因はありません。したがって、どのFATタイプになるかはボリューム サイズとクラスタ サイズに依存します。そのボリュームのサイズにおいて、指定されたFATタイプとクラスタ サイズの組み合わせが成立し得ないときは、関数はFR_MKFS_ABORTEDで失敗します。
-クラスタとは、データ格納領域の管理の単位のことで、これを単位にファイルにデータ領域が割り当てられます。たとえば、クラスタ サイズが32768のときは、100バイトのファイルも32768バイトのスペースを消費することになります。このように、クラスタ サイズを大きくするほどボリュームの利用効率が悪くなりますが、その一方で読み書きの性能は上がります。クラスタ サイズによる利用効率と性能はトレード オフの関係にあります。GBクラスのストレージでは、極端に多くのファイルを扱わない限り32768バイト以上に(デフォルト指定ではそのようになる)しておくとよいでしょう。
-パーテーション形式には、FDISK形式とSFD形式の二通りあります。FDISK形式は、ハードディスク、マルチメディアカード、SDカード、CFカード、USBメモリなどで標準的に使用されます。FDISK形式では一台の物理ドライブ上に一つまたは複数の区画を作成することができ、区画管理情報はMBR(物理ドライブの先頭セクタ)に記録されます。SFD形式は単に何の分割も行わない形式で、ボリュームは物理ドライブの先頭セクタから開始します。SFD形式は、フロッピー ディスク、マイクロドライブ、光学ディスク、およびその他スーパー フロッピー メディアで標準的に使用されています。システムによっては、FDISK形式またはSFD形式のどちらか一方のみをサポートし他方をサポートしません。
-FM_SFDが指定されないときはFDISK形式となり、その物理ドライブ全体を占める1個の基本区画(パーテーション)が作成され、その中にFATボリュームが作成されます。FM_SFDが指定されたときはSFD形式となり、FATボリュームがその物理ドライブの先頭セクタからベタで作成されます。
-マルチ パーテーション機能(_MULTI_PARTITION)により、その論理ドライブが特定の区画(1~4)に結び付けられている場合は、その区画の中にFATボリュームが作成されます。FM_SFDの指定は無視され、その物理ドライブはこれに先立ち、f_fdisk関数または他のツールで適切に区画設定されている必要があります。
-_FS_READONLY == 0で、且つ_USE_MKFS == 1のとき使用可能です。
--/* Format default drive and create a file */ -int main (void) -{ - FATFS fs; /* File system object */ - FIL fil; /* File object */ - FRESULT res; /* API result code */ - UINT bw; /* Bytes written */ - BYTE work[_MAX_SS]; /* Work area (larger is better for process time) */ - - - /* Create FAT volume */ - res = f_mkfs("", FM_ANY, 0, work, sizeof work); - if (res) ... - - /* Register work area */ - f_mount(&fs, "", 0); - - /* Create a file as new */ - res = f_open(&fil, "hello.txt", FA_CREATE_NEW | FA_WRITE); - if (res) ... - - /* Write a message */ - f_write(&fil, "Hello, World!\r\n", 15, &bw); - if (bw != 15) ... - - /* Close the file */ - f_close(&fil); - - ... --
論理ドライブにファイル システム オブジェクトを登録・抹消します。
--FRESULT f_mount ( - FATFS* fs, /* [IN] ファイル システム オブジェクト */ - const TCHAR* path, /* [IN] 論理ドライブ番号 */ - BYTE opt /* [IN] 動作オプション */ -); --
-FR_OK, -FR_INVALID_DRIVE, -FR_DISK_ERR, -FR_NOT_READY, -FR_NO_FILESYSTEM -
-FatFsモジュールでは、それぞれの論理ドライブにファイル システム オブジェクトというワーク エリアが必要です。この関数は論理ドライブにファイル システム オブジェクトを登録したり抹消したりします。何らかのファイル関数を使用する前に、この関数でその論理ドライブのファイル システム オブジェクトを与えておかなければなりません。fsにヌル ポインタを指定すると、その論理ドライブのファイル システム オブジェクトの登録は抹消されるだけです。登録抹消されたファイル システム オブジェクトのメモリは解放できます。操作の対象の論理ドライブ上に開かれたままのファイルやディレクトリがあった場合、それらに対して作成された構造体は全て無効になります。この関数の内部処理は次のような順に行われます。
-optに0を指定すると、マウント動作(物理ドライブの初期化、FATボリュームの検索、BPBを解析しファイル システム オブジェクトを初期化)は行われず、関数は物理ドライブの状態に関わらず常に成功します。関数内では下位レイヤへのアクセスは発生せず、指定されたファイル システム オブジェクトをクリア(無効化)し、そのアドレスを内部配列に登録するだけです。単に登録済みのファイル システム オブジェクトをクリアする目的にも使えます。実際のマウント動作は、ボリュームへのアクセス(パス名を渡すもの全て)が行われたときに、次のうちいずれかの条件が真の場合に行われます。
-optに1を指定すると、ファイル システムオブジェクトの登録に続きマウント動作が行われます。メディアが無いなどの理由でマウント動作に失敗すると対応するエラーを返しファイル システム オブジェクトはクリア状態のままになりますが、登録自体は有効なので続いてボリュームへのアクセスがあれば再びマウント動作が実行されます。
-下位レイヤの実装上メディア交換の検出がサポートされない(disk_status関数に反映されない)ときは、アプリケーションはメディア交換の後この関数でファイル システム オブジェクトを明示的にクリアし、マウント動作が正常に行えるようにする必要があります。
-全ての構成で使用可能です。
-ファイルをオープンまたは作成します。
--FRESULT f_open ( - FIL* fp, /* [OUT] 空のファイル オブジェクト構造体へのポインタ */ - const TCHAR* path, /* [IN] ファイル名へのポインタ */ - BYTE mode /* [IN] モードフラグ */ -); --
値 | 意味 |
---|---|
FA_READ | 読み出しモードで開きます。読み書きする場合はFA_WRITEと共に指定します。 |
FA_WRITE | 書き込みモードで開きます。読み書きする場合はFA_READと共に指定します。 |
FA_OPEN_EXISTING | 既存のファイルを開きます。ファイルが無いときはエラーになります。(デフォルト) |
FA_CREATE_NEW | ファイルを作成します。同名のファイルがある場合は、FR_EXISTで失敗します。 |
FA_CREATE_ALWAYS | ファイルを作成します。同名のファイルがある場合は、サイズを0にしてから開きます。 |
FA_OPEN_ALWAYS | 既存のファイルを開きます。ファイルが無いときはファイルを作成します。 |
FA_OPEN_APPEND | FA_OPEN_ALWAYSと同じですが、リード/ライト ポインタはファイルの最後尾にセットされます。 |
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_FILE, -FR_NO_PATH, -FR_INVALID_NAME, -FR_DENIED, -FR_EXIST, -FR_INVALID_OBJECT, -FR_WRITE_PROTECTED, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_LOCKED, -FR_NOT_ENOUGH_CORE, -FR_TOO_MANY_OPEN_FILES -
-既存のファイルを開いたり、新しいファイルを作成します。関数が成功するとファイル オブジェクトが作成され、以降そのファイルに対するアクセスに使用します。ファイルを閉じるときは、f_close関数を使用します。何らかの変更が行われたファイルがその後正しく閉じられなかった場合、そのファイルが破損する場合があります。
-既に開かれているファイルを開く必要がある場合は、多重アクセス制御を参照してください。しかし、一つのファイルに対する書き込みモードを含む重複オープンは常に禁止です。
-ファイル アクセスを開始する前に、f_mount関数を使ってそれぞれの論理ドライブにワーク エリア(ファイル システム オブジェクト)を与える必要があります。この初期化の後、その論理ドライブに対して全てのファイル関数が使えるようになります。f_mkfs関数とf_fdsk関数は、ワークエリア無しでも使えます。
-全ての構成で使用可能です。_FS_READONLY == 1のときは、FA_READとFA_OPEN_EXISTING以外の各フラグはサポートされません。
--/* テキストファイルを読み出して表示 */ - -FATFS FatFs; /* 論理ドライブのワーク エリア(ファイル システム オブジェクト) */ - -int main (void) -{ - FIL fil; /* ファイル オブジェクト */ - char line[82]; /* 行バッファ */ - FRESULT fr; /* 戻り値 */ - - - /* デフォルト ドライブにワークエリアを与える */ - f_mount(&FatFs, "", 0); - - /* テキスト ファイルを開く */ - fr = f_open(&fil, "message.txt", FA_READ); - if (fr) return (int)fr; - - /* 1行ずつ読み出して表示 */ - while (f_gets(line, sizeof line, &fil)) - printf(line); - - /* ファイルを閉じる */ - f_close(&fil); - - return 0; -} --
-/* ドライブ1のファイル "file.bin" をドライブ0へコピー */ - -int main (void) -{ - FATFS fs[2]; /* 論理ドライブのワークエリア(ファイル システム オブジェクト) */ - FIL fsrc, fdst; /* ファイル オブジェクト */ - BYTE buffer[4096]; /* File copy buffer */ - FRESULT fr; /* FatFs function common result code */ - UINT br, bw; /* File R/W count */ - - /* ドライブ0,1にワーク エリアを与える */ - f_mount(&fs[0], "0:", 0); - f_mount(&fs[1], "1:", 0); - - /* ドライブ1のコピー元ファイルを開く */ - res = f_open(&fsrc, "1:file.dat", FA_OPEN_EXISTING | FA_READ); - if (fr) return (int)fr; - - /* ドライブ0にコピー先ファイルを作成する */ - res = f_open(&fdst, "0:file.dat", FA_CREATE_ALWAYS | FA_WRITE); - if (fr) return (int)fr; - - /* コピー元からコピー先にデータ転送する */ - for (;;) { - res = f_read(&fsrc, buffer, sizeof buffer, &br); /* コピー元からから読み出す */ - if (res || br == 0) break; /* エラーかファイル終端 */ - res = f_write(&fdst, buffer, br, &bw); /* それをコピー先に書き込む */ - if (res || bw < br) break; /* エラーかディスク満杯 */ - } - - /* 全てのファイルを閉じる */ - f_close(&fsrc); - f_close(&fdst); - - /* ワーク エリアを開放する */ - f_mount(NULL, "0:", 0); - f_mount(NULL, "1:", 0); - - return (int)fr; -} --
ディレクトリを開きます。
--FRESULT f_opendir ( - DIR* dp, /* [OUT] ディレクトリ ブジェクト構造体へのポインタ */ - const TCHAR* path /* [IN] ディレクトリ名へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_PATH, -FR_INVALID_NAME, -FR_INVALID_OBJECT, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE, -FR_TOO_MANY_OPEN_FILES -
-ディレクトリを開きます。正常終了したら、作成されたディレクトリ オブジェクト構造体を使ってこのディレクトリの項目を順次読み出せます。
-_FS_MINIMIZE <= 1のとき使用可能になります。
-ファイルに書式化文字列を書き込みます。
--int f_printf ( - FIL* fp, /* [IN] ファイル オブジェクト */ - const TCHAR* fmt, /* [IN] 書式制御文字列 */ - ... -); --
文字列が正常に書き込まれると、書き込まれた文字数が返されます。ディスクが満杯またはその他エラーにより正常に書き込まれなかったときは、関数は失敗しEOF (-1)が返されます。
-書式制御機能はC標準ライブラリのサブセットとなっていて、書式制御文字は次に示すものが使用可能です。
-この関数は、f_putc関数およびf_puts関数のラッパー関数です。_FS_READONLY == 0で、且つ_USE_STRFUNCが1または2のとき使用可能になります。2の時は、出力に含まれる'\n'が'\r'+'\n'に展開されてファイルに書き込まれます。
-APIにUnicodeが選択(_LFN_UNICODEが1)されているときは、fmtはUnicode文字列になりますが、ファイル上のエンコードは、_STRF_ENCODEオプションで選択できます。それ以外の時は無変換(1バイト/1文字)で書き込みます。
-- f_printf(&fil, "%d", 1234); /* "1234" */ - f_printf(&fil, "%6d,%3d%%", -200, 5); /* " -200, 5%" */ - f_printf(&fil, "%ld", 12345L); /* "12345" */ - f_printf(&fil, "%06d", 25); /* "000025" */ - f_printf(&fil, "%06d", -25); /* "000-25" */ - f_printf(&fil, "%-6d", 25); /* "25 " */ - f_printf(&fil, "%u", -1); /* "65535" or "4294967295" */ - f_printf(&fil, "%04x", 0xAB3); /* "0ab3" */ - f_printf(&fil, "%08LX", 0x123ABCL); /* "00123ABC" */ - f_printf(&fil, "%016b", 0x550F); /* "0101010100001111" */ - f_printf(&fil, "%s", "String"); /* "String" */ - f_printf(&fil, "%8s", "abc"); /* " abc" */ - f_printf(&fil, "%-8s", "abc"); /* "abc " */ - f_printf(&fil, "%c", 'a'); /* "a" */ - f_printf(&fil, "%f", 10.0); /* 浮動小数点は未サポート */ --
ファイルに文字を書き込みます。
--int f_putc ( - TCHAR chr, /* [IN] 書き込む文字 */ - FIL* fp /* [IN] ファイル オブジェクト */ -); --
文字が正常に書き込まれると書き込んだ文字数が返されます。ディスクが満杯またはエラーにより書き込まれなかったときはEOF (-1)が返されます。
-APIにUnicodeが選択(_LFN_UNICODEが1)されているときは、chrはUTF-16文字になりますが、ファイル上のエンコードは、_STRF_ENCODEオプションで選択できます。それ以外の時は無変換(1バイト/1文字)で書き込みます。
-1文字をファイルに書き込みます。
-この関数はf_write関数のラッパー関数です。_FS_READONLY == 0で、且つ_USE_STRFUNCが 1または 2のとき使用可能です。2を指定すると、'\n'は'\r'+'\n'に展開されてファイルに書き込まれます。
-ファイルに文字列を書き込みます。
--int f_puts ( - const TCHAR* str, /* [IN] 書き込む文字列 */ - FIL* fp /* [IN] ファイル オブジェクト */ -); --
文字列が正常に書き込まれると、書き込まれた文字数が返されます。ディスクが満杯またはエラーにより書き込みが中断されたときはEOF (-1)が返されます。
-APIにUnicodeが選択(_LFN_UNICODEが1)されているときは、strはUTF-16文字列になりますが、ファイル上のエンコードは、_STRF_ENCODEオプションで選択できます。それ以外の時は無変換(1バイト/1文字)で書き込みます。
-文字列をファイルに書き込みます。
-この関数はf_write関数のラッパー関数です。_FS_READONLY == 0で、且つ_USE_STRFUNCが1または2のとき使用可能です。2を指定すると、文字列に含まれる'\n'は'\r'+'\n'に展開されてファイルに書き込まれます。
-FatFsのAPIでは、一部の関数を除き結果に応じた共通のリザルト コード(FRESULT型(enum))を返します。関数が成功した場合は0 (FR_OK)を返します。失敗した場合は0以外の値を返し、値はエラーの種類を示します。
- -ファイルからデータを読み出します。
--FRESULT f_read ( - FIL* fp, /* [IN] ファイル オブジェクト構造体 */ - void* buff, /* [OUT] 読み出したデータを格納するバッファ */ - UINT btr, /* [IN] 読み出すバイト数 */ - UINT* br /* [OUT] 読み出されたバイト数 */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_DENIED, -FR_INVALID_OBJECT, -FR_TIMEOUT -
-読み込み開始位置は、現在のリード/ライト ポインタからになります。リード/ライト ポインタは読み込まれたバイト数だけ進みます。関数が正常終了した後は、*brの値をチェックすべきです。*brがbtrよりも小さいときは、読み込み中にファイルの終端に達したことを示しています。
-全ての構成で使用可能です。
-ディレクトリ項目を読み出します。
--FRESULT f_readdir ( - DIR* dp, /* [IN] ディレクトリ ブジェクト構造体へのポインタ */ - FILINFO* fno /* [OUT] ファイル情報構造体へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_INVALID_OBJECT, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE -
-ディレクトリの項目(ファイルおよびサブ ディレクトリ)の情報を順次読み出します。この関数を繰り返し実行することによりそのディレクトリの全ての項目を読み出すことができます。得られるファイル情報の詳細については FILINFO構造体を参照してください。全ての項目が読み出され、読み出す項目がもう無いときは、fno->fname[]にヌル文字列が返されます。fnoにヌル ポインタを指定すると、そのディレクトリのリード インデックスを先頭に巻き戻します。サブ ディレクトリのドット エントリ("."と"..")は、出力に現れません。
-LFN構成では、altname[]が新たに定義され、そのオブジェクトの短いファイル名がストアされます。次の条件のときは長いファイル名を返せないのでfname[]に短いファイル名がストアされ、altname[]はヌル文字列になります。
-exFATボリュームのディレクトリを読み出すとき、構成によっては問題が発生します。exFATでは短いファイル名がサポートされません。つまり、上記の条件のとき代わりに返すファイル名が無いということです。このような場合はfname[]に"?"が返され、そのオブジェクトにアクセスできないことを示します。この問題を避けるには、FatFsの構成を_LFN_UNICODE = 1および_MAX_LFN = 255として長いファイル名に完全対応とする必要があります。
-_FS_MINIMIZE <= 1のときに使用可能です。
--FATFS fs; -char buff[256]; - -FRESULT scan_files ( - char* path /* 開始ノード (ワークエリアとしても使用) */ -) -{ - FRESULT res; - DIR dir; - UINT i; - static FILINFO fno; - - - res = f_opendir(&dir, path); /* ディレクトリを開く */ - if (res == FR_OK) { - for (;;) { - res = f_readdir(&dir, &fno); /* ディレクトリ項目を1個読み出す */ - if (res != FR_OK || fno.fname[0] == 0) break; /* エラーまたは項目無しのときは抜ける */ - if (fno.fattrib & AM_DIR) { /* ディレクトリ */ - i = strlen(path); - sprintf(&path[i], "/%s", fno.fname); - res = scan_files(path); /* 一つ下へ */ - if (res != FR_OK) break; - path[i] = 0; - } else { /* ファイル */ - printf("%s/%s\n", path, fno.fname); - } - } - f_closedir(&dir) - } - - return res; -} - - -int main (void) -{ - FRESULT res; - - - res = f_mount(&fs, "", 1); - if (res == FR_OK) { - strcpy(buff, "/"); - res = scan_files(buff); - } - - return res; -} --
ファイルまたはサブ ディレクトリの名前の変更または移動します。
--FRESULT f_rename ( - const TCHAR* old_name, /* [IN] 古いオブジェクト名 */ - const TCHAR* new_name /* [IN] 新しいオブジェクト名 */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_FILE, -FR_NO_PATH, -FR_INVALID_NAME, -FR_EXIST, -FR_WRITE_PROTECTED, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_LOCKED -
-ファイルまたはサブ ディレクトリの名前を変更します。また、同時に別のディレクトリへの移動も可能ですが、異なるドライブ間の移動はできません。開かれているオブジェクトに対する使用は不正な操作となり、FAT構造が破壊される可能性があります。多重アクセス制御が有効のときは安全に拒否されます。
-_FS_READONLY == 0で、且つ_FS_MINIMIZE == 0のときに使用可能です。
-- /* デフォルト ドライブにあるオブジェクトの名前を変更 */ - f_rename("oldname.txt", "newname.txt"); - - /* ドライブ2にあるオブジェクトの名前を変更 */ - f_rename("2:oldname.txt", "newname.txt"); - - /* 名前の変更と同時に別のディレクトリに移動 */ - f_rename("log.txt", "old/log0001.txt"); --
DIR構造体は、f_opendir/f_readdir/f_findfirst/f_findnext関数のワーク エリアとして使用されます。アプリケーションは、この構造体のメンバを書き換えてはなりません。
--typedef struct { - _FDID obj; /* オブジェクトID */ - DOWRD dptr; /* 現在のread/writeオフセット */ - DWORD clust; /* 現在のクラスタ番号 */ - DWORD sect; /* 現在のセクタ番号 */ - BYTE* dir; /* 現在のSFNエントリ(Win[]内)へのポインタ */ - BYTE* fn; /* SFNバッファへのポインタ (in/out) {file[8],ext[3],status[1]} */ -#if _USE_LFN - DWORD blk_ofs; /* 現在のエントリブロックの先頭 (0xFFFFFFFF:無効) */ - WCHAR* lfn; /* LFNバッファへのポインタ (in/out) */ -#endif -#if _USE_FIND - const TCHAR* pat; /* マッチング パターンへのポインタ */ -#endif -} DIR; --
ボリュームにボリューム ラベルを設定します。
--FRESULT f_setlabel ( - const TCHAR* label /* [IN] 設定するボリューム ラベルへのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_INVALID_NAME, -FR_WRITE_PROTECTED, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT -
-文字列の先頭にドライブ番号を含む場合は、その論理ドライブに対して設定されます。含まない場合は、デフォルト ドライブに設定されます。ボリューム ラベルを削除するときは、ヌル文字列を指定します。FATボリューム上では、ボリューム ラベルのフォーマットは、ファイル名とほぼ同じですが、次の点が異なります。
-【補足】 標準システム(Windows)では\xE5で始まるボーリューム ラベル(CP932なら「薔薇」など)の扱いに問題があります。このため、この関数ではそのような名前は無効として処理しています。
-_FS_READONLY == 0で、且つ_USE_LABEL == 1のときに使用可能です。
-- /* デフォルト ドライブにボリューム ラベルを設定 */ - f_setlabel("DATA DISK"); - - /* ドライブ2にボリューム ラベルを設定 */ - f_setlabel("2:DISK 3 OF 4"); - - /* ドライブ2のボリューム ラベルを削除 */ - f_setlabel("2:"); --
FATFS構造体(ファイル システム オブジェクト)は、個々の論理ドライブのダイナミック ワーク エリアを保持し、f_mount関数でFatFsモジュールに登録されます。初期化が行われるタイミングは、f_mount関数(強制マウント指定)の実行またはメディア交換の後の最初のファイル アクセスの時です。アプリケーションは、この構造体のメンバを書き換えてはなりません。
- --typedef struct { - BYTE fs_type; /* ファイル システム (0, FS_FAT12, FS_FAT16, FS_FAT32 or FS_EXFAT) */ - BYTE drv; /* 物理ドライブ番号 */ - BYTE n_fats; /* FATの多重化数 (1,2) */ - BYTE wflag; /* win[]ダーティ フラグ */ - BYTE fsi_flag; /* FSINFOフラグ (b7:Disabled, b0:Dirty) */ - WORD id; /* ファイル システム マウントID */ - WORD n_rootdir; /* ルート ディレクトリのエントリ数 (FAT12/16) */ - WORD csize; /* クラスタ当たりのセクタ数 */ -#if _MAX_SS != _MIN_SS - WORD ssize; /* セクタ サイズ (512, 1024, 2048 or 4096) */ -#endif -#if _FS_EXFAT - BYTE* dirbuf; /* ディレクトリ エントリ ブロック操作バッファへのポインタ */ -#endif -#if _FS_REENTRANT - _SYNC_t sobj; /* 同期オブジェクトID */ -#endif -#if !_FS_READONLY - DWORD last_clust; /* FSINFO: 最後に割り当てられたクラスタ番号 */ - DWORD free_clust; /* FSINFO: 空きクラスタ数 */ -#endif -#if _FS_RPATH - DWORD cdir; /* カレント ディレクトリのクラスタ番号 (0:ルート) */ -#if _FS_EXFAT - DWORD cdc_scl; /* カレント ディレクトリを含むディレクトリの開始クラスタ番号 (cdir == 0では無効) */ - DWORD cdc_size; /* b31-b8:カレント ディレクトリを含むディレクトリのサイズ, b7-b0: チェーン ステータス */ - DWORD cdc_ofs; /* カレント ディレクトリを含むディレクトリ内の位置 (cdir == 0では無効) */ -#endif -#endif - DWORD n_fatent; /* FATエントリ数 (総クラスタ数 + 2) */ - DWORD fsize; /* FAT 1個のセクタ数 */ - DWORD volbase; /* ボリューム開始セクタ */ - DWORD fatbase; /* FAT領域開始セクタ */ - DWORD dirbase; /* ルート ディレクトリ領域開始(セクタ|クラスタ) */ - DWORD database; /* データ領域開始セクタ */ - DWORD winsect; /* win[]に現れているセクタ番号 */ - BYTE win[_MAX_SS]; /* ディスク アクセス ウィンドウ */ -} FATFS; --
FIL構造体(ファイル オブジェクト)は、f_open関数で初期化され、以後そのファイルの状態を保持します。また、f_close関数でファイルが閉じられると無効化されます。アプリケーションは、この構造体のメンバを書き換えてはなりません(cltblは例外)。非タイニー構成(_FS_TINY == 0)では、内部に_MAX_SSバイトのセクタ バッファが確保されるので、そのサイズには注意が必要です。
- --typedef struct { - _FDID obj; /* オブジェクトID */ - BYTE flag; /* ファイル ステータス フラグ */ - BYTE err; /* エラー中断フラグ */ - FSIZE_t fptr; /* ファイル読み書きポインタ (ファイル先頭からのバイト オフセット) */ - DWORD clust; /* 現在のクラスタ (fptrがクラスタ境界上のときは前のクラスタ、fptrが0のときは無効) */ - DWORD dsect; /* 現在のデータ セクタ */ -#if !_FS_READONLY - DWORD dir_sect; /* このファイルのディレクトリ エントリのあるセクタ */ - BYTE* dir_ptr; /* このファイルのディレクトリへのポインタ */ -#endif -#if _USE_FASTSEEK - DWORD* cltbl; /* ファイルのクラスタ リンク情報へのポインタ (オープン時にNULLがセットされる) */ -#endif -#if _FS_LOCK - UINT lockid; /* ファイル ロックID */ -#endif -#if !_FS_TINY - BYTE buf[_MAX_SS]; /* ファイル プライベート データ転送バッファ (fptrがセクタ境界上にない時は常に有効だが、fptrがセクタ境界上のときは無効な場合がある) */ -#endif -} FIL; --
FILINFO構造体は、f_stat/f_readdir/f_findfirst/f_findnext関数で返されるオブジェクトに関する情報を保持します。
--typedef struct { - FSIZE_t fsize; /* ファイル サイズ */ - WORD fdate; /* 最後に更新された日付 */ - WORD ftime; /* 最後に更新された時刻 */ - BYTE fattrib; /* アトリビュート */ -#if _USE_LFN != 0 - TCHAR altname[13]; /* 代替ファイル名 */ - TCHAR fname[_MAX_LFN + 1]; /* 主ファイル名 */ -#else - TCHAR fname[13]; /* ファイル名 */ -#endif -} FILINFO; --
ファイルのサイズを取得します。
--FSIZE_t f_size ( - FIL* fp /* [IN] ファイル オブジェクト */ -); --
バイト単位のファイル サイズが返ります。
-この関数は、現リビジョンではマクロとして実装されています。ファイル オブジェクトの正当性チェックや排他制御は行いません。
-
-#define f_size(fp) ((fp)->obj.objsize)
-
-常に使用可能。
-ファイルまたはサブ ディレクトリの存在を調べ、またその情報を取得します。
--FRESULT f_stat ( - const TCHAR* path, /* [IN] オブジェクト名へのポインタ */ - FILINFO* fno /* [OUT] ファイル情報構造体へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_FILE, -FR_NO_PATH, -FR_INVALID_NAME, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE -
-指定されたファイルまたはサブ ディレクトリの存在を調べます。存在しない場合は、FR_NO_FILEが帰ります。存在する場合はFR_OKが帰り、それ関する情報(サイズ、タイムスタンプおよび属性)がファイル情報構造体にストアされます。
-_FS_MINIMIZE == 0のときに使用可能です。
-- FRESULT fr; - FILINFO fno; - - - printf("Test for 'file.txt'...\n"); - - fr = f_stat("file.txt", &fno); - switch (fr) { - - case FR_OK: - printf("Size: %lu\n", fno.fsize); - printf("Timestamp: %u/%02u/%02u, %02u:%02u\n", - (fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31, - fno.ftime >> 11, fno.ftime >> 5 & 63); - printf("Attributes: %c%c%c%c%c\n", - (fno.fattrib & AM_DIR) ? 'D' : '-', - (fno.fattrib & AM_RDO) ? 'R' : '-', - (fno.fattrib & AM_HID) ? 'H' : '-', - (fno.fattrib & AM_SYS) ? 'S' : '-', - (fno.fattrib & AM_ARC) ? 'A' : '-'); - break; - - case FR_NO_FILE: - printf("It is not exist.\n"); - break; - - default: - printf("An error occured. (%d)\n", fr); - } --
書き込み中のファイルのキャッシュされた情報をフラッシュします。
--FRESULT f_sync ( - FIL* fp /* [IN] ファイル オブジェクト構造体へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_INVALID_OBJECT, -FR_TIMEOUT -
-この関数はf_close関数と同じ処理を実行しますが、ファイルは引き続き開かれたままになり、読み書きを続行できます。ロギングなど、書き込みモードで長時間ファイルが開かれているアプリケーションにおいて、定期的または区切りの良いところでこの関数を使用することにより、不意の電源断やメディアの取り外しにより失われるデータを最小にすることができます。この背景については、アプリケーション ノートも参照してください。
-実際のところ、f_close関数内ではこの関数を呼び出した後ファイル オブジェクトを無効化しているだけなので、f_close関数の直前にf_sync関数を置くことは無意味です。
-_FS_READONLY == 0のときに使用可能です。
-現在のリード/ライト ポインタを取得します。
--FSIZE_t f_tell ( - FIL* fp /* [IN] ファイル オブジェクト */ -); --
現在のリード/ライト ポインタ(ファイル先頭からのバイト単位のオフセット)が返ります。
-f_tell関数は、現リビジョンではマクロとして実装されています。ファイル オブジェクトの正当性チェックや排他制御は行いません。
-
-#define f_tell(fp) ((fp)->fptr)
-
-常に使用可能。
-ファイル長を切り詰めます。
--FRESULT f_truncate ( - FIL* fp /* [IN] ファイル オブジェクトへのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_DENIED, -FR_INVALID_OBJECT, -FR_TIMEOUT -
-ファイルの長さが現在のリード/ライト ポインタに切り詰められます。リード/ライト ポインタが既にファイルの終端を指しているときは、この関数は何の効果も持ちません。
-_FS_READONLY == 0で、且つ_FS_MINIMIZE == 0のときに使用可能です。
-ファイルまたはサブ ディレクトリを削除します。
--FRESULT f_unlink ( - const TCHAR* path /* [IN] オブジェクト名へのポインタ */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_FILE, -FR_NO_PATH, -FR_INVALID_NAME, -FR_DENIED, -FR_WRITE_PROTECTED, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_LOCKED, -FR_NOT_ENOUGH_CORE -
-削除対象のオブジェクトが次の条件に当てはまる場合、そのアクセスは拒否(FR_DENIED)され関数は失敗します。
-_FS_READONLY == 0で、且つ_FS_MINIMIZE == 0のときに使用可能です。
-ファイルまたはサブ ディレクトリのタイムスタンプを変更します。
--FRESULT f_utime ( - const TCHAR* path, /* [IN] オブジェクト名へのポインタ */ - const FILINFO* fno /* [IN] 設定する日付 */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_NOT_READY, -FR_NO_FILE, -FR_NO_PATH, -FR_INVALID_NAME, -FR_WRITE_PROTECTED, -FR_INVALID_DRIVE, -FR_NOT_ENABLED, -FR_NO_FILESYSTEM, -FR_TIMEOUT, -FR_NOT_ENOUGH_CORE -
-オブジェクトのタイムスタンプを変更します。
-
-FRESULT set_timestamp (
- char *obj, /* ファイル名へのポインタ */
- int year,
- int month,
- int mday,
- int hour,
- int min,
- int sec
-)
-{
- FILINFO fno;
-
- fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
- fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U);
-
- return f_utime(obj, &fno);
-}
-
-_FS_READONLY == 0で、且つ_FS_MINIMIZE == 0のときに使用可能です。
-ファイルにデータを書き込みます。
--FRESULT f_write ( - FIL* fp, /* [IN] ファイル オブジェクト */ - const void* buff, /* [IN] 書き込みデータ */ - UINT btw, /* [IN] 書き込むバイト数 */ - UINT* bw /* [OUT] 書き込まれたバイト数 */ -); --
-FR_OK, -FR_DISK_ERR, -FR_INT_ERR, -FR_DENIED, -FR_INVALID_OBJECT, -FR_TIMEOUT -
-書き込み開始位置は、リード/ライト ポインタの位置からになります。リード/ライト ポインタは実際に書き込まれたバイト数だけ進みます。関数が正常終了した後、要求したバイト数が書き込まれたかどうか*bwをチェックすべきです。*bwがbtwより小さいときは、ディスク フルを意味します。ディスク フルが発生しているときまたはそれに近いときは、制御が帰るまで時間がかかる場合があります。
-_FS_READONLY == 0のときに使用可能です。
-