From 5366852335044c1e68a5c32548d3051cc943552f Mon Sep 17 00:00:00 2001 From: Leo C Date: Tue, 19 Aug 2014 15:31:33 +0200 Subject: Import fatfs R0.10b FatFs Module Source Files R0.10b Author: (C)ChaN, 2014 (http://elm-chan.org) URL: http://elm-chan.org/fsw/ff/ff10b.zip --- fatfs/doc/ja/appnote.html | 282 ++++++++++++++++++++++++++++++++++++++++++++ fatfs/doc/ja/chdir.html | 81 +++++++++++++ fatfs/doc/ja/chdrive.html | 61 ++++++++++ fatfs/doc/ja/chmod.html | 83 +++++++++++++ fatfs/doc/ja/close.html | 66 +++++++++++ fatfs/doc/ja/closedir.html | 64 ++++++++++ fatfs/doc/ja/dinit.html | 46 ++++++++ fatfs/doc/ja/dioctl.html | 95 +++++++++++++++ fatfs/doc/ja/dread.html | 71 +++++++++++ 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/fattime.html | 57 +++++++++ fatfs/doc/ja/fdisk.html | 97 +++++++++++++++ fatfs/doc/ja/filename.html | 76 ++++++++++++ fatfs/doc/ja/forward.html | 140 ++++++++++++++++++++++ fatfs/doc/ja/getcwd.html | 70 +++++++++++ fatfs/doc/ja/getfree.html | 95 +++++++++++++++ fatfs/doc/ja/getlabel.html | 82 +++++++++++++ fatfs/doc/ja/gets.html | 65 ++++++++++ fatfs/doc/ja/lseek.html | 129 ++++++++++++++++++++ fatfs/doc/ja/mkdir.html | 80 +++++++++++++ fatfs/doc/ja/mkfs.html | 73 ++++++++++++ fatfs/doc/ja/mount.html | 82 +++++++++++++ fatfs/doc/ja/open.html | 171 +++++++++++++++++++++++++++ fatfs/doc/ja/opendir.html | 76 ++++++++++++ fatfs/doc/ja/printf.html | 93 +++++++++++++++ fatfs/doc/ja/putc.html | 62 ++++++++++ fatfs/doc/ja/puts.html | 62 ++++++++++ fatfs/doc/ja/rc.html | 85 +++++++++++++ fatfs/doc/ja/read.html | 75 ++++++++++++ fatfs/doc/ja/readdir.html | 126 ++++++++++++++++++++ fatfs/doc/ja/rename.html | 82 +++++++++++++ fatfs/doc/ja/sdir.html | 40 +++++++ fatfs/doc/ja/setlabel.html | 89 ++++++++++++++ fatfs/doc/ja/sfatfs.html | 55 +++++++++ fatfs/doc/ja/sfile.html | 48 ++++++++ fatfs/doc/ja/sfileinfo.html | 70 +++++++++++ fatfs/doc/ja/size.html | 62 ++++++++++ fatfs/doc/ja/stat.html | 74 ++++++++++++ fatfs/doc/ja/sync.html | 66 +++++++++++ fatfs/doc/ja/tell.html | 62 ++++++++++ fatfs/doc/ja/truncate.html | 67 +++++++++++ fatfs/doc/ja/unlink.html | 74 ++++++++++++ fatfs/doc/ja/utime.html | 99 ++++++++++++++++ fatfs/doc/ja/write.html | 75 ++++++++++++ 47 files changed, 3856 insertions(+) create mode 100644 fatfs/doc/ja/appnote.html create mode 100644 fatfs/doc/ja/chdir.html create mode 100644 fatfs/doc/ja/chdrive.html create mode 100644 fatfs/doc/ja/chmod.html create mode 100644 fatfs/doc/ja/close.html create mode 100644 fatfs/doc/ja/closedir.html create mode 100644 fatfs/doc/ja/dinit.html create mode 100644 fatfs/doc/ja/dioctl.html create mode 100644 fatfs/doc/ja/dread.html create mode 100644 fatfs/doc/ja/dstat.html create mode 100644 fatfs/doc/ja/dwrite.html create mode 100644 fatfs/doc/ja/eof.html create mode 100644 fatfs/doc/ja/error.html create mode 100644 fatfs/doc/ja/fattime.html create mode 100644 fatfs/doc/ja/fdisk.html create mode 100644 fatfs/doc/ja/filename.html create mode 100644 fatfs/doc/ja/forward.html create mode 100644 fatfs/doc/ja/getcwd.html create mode 100644 fatfs/doc/ja/getfree.html create mode 100644 fatfs/doc/ja/getlabel.html create mode 100644 fatfs/doc/ja/gets.html create mode 100644 fatfs/doc/ja/lseek.html create mode 100644 fatfs/doc/ja/mkdir.html create mode 100644 fatfs/doc/ja/mkfs.html create mode 100644 fatfs/doc/ja/mount.html create mode 100644 fatfs/doc/ja/open.html create mode 100644 fatfs/doc/ja/opendir.html create mode 100644 fatfs/doc/ja/printf.html create mode 100644 fatfs/doc/ja/putc.html create mode 100644 fatfs/doc/ja/puts.html create mode 100644 fatfs/doc/ja/rc.html create mode 100644 fatfs/doc/ja/read.html create mode 100644 fatfs/doc/ja/readdir.html create mode 100644 fatfs/doc/ja/rename.html create mode 100644 fatfs/doc/ja/sdir.html create mode 100644 fatfs/doc/ja/setlabel.html create mode 100644 fatfs/doc/ja/sfatfs.html create mode 100644 fatfs/doc/ja/sfile.html create mode 100644 fatfs/doc/ja/sfileinfo.html create mode 100644 fatfs/doc/ja/size.html create mode 100644 fatfs/doc/ja/stat.html create mode 100644 fatfs/doc/ja/sync.html create mode 100644 fatfs/doc/ja/tell.html create mode 100644 fatfs/doc/ja/truncate.html create mode 100644 fatfs/doc/ja/unlink.html create mode 100644 fatfs/doc/ja/utime.html create 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 new file mode 100644 index 0000000..0fb5579 --- /dev/null +++ b/fatfs/doc/ja/appnote.html @@ -0,0 +1,282 @@ + + +
+ + + + + +FatFsモジュールは移植性に関して次の点を前提としています。
+下に示す依存関係図は、FatFsモジュール利用の組み込みシステムにおける代表的な構成を示します。
+(a) FatFs用に書かれたディスク・モジュールがある場合は、そのまま追加するだけです。 (b) しかし、多くの既存のディスク・モジュールはそのAPIをFatFsに合わせるため、グルー関数が必要になるでしょう。
+必要なのはFatFsモジュールの要求するディスク関数を用意することだけで、それ以外にすることはありません。既に動作しているディスク・モジュールがあるなら、そのAPIを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_ERASE_SECTOR) | _USE_ERASE == 1 | |
ff_convert ff_wtoupper | _USE_LFN >= 1 | 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 | VC6 |
_WORD_ACCESS | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
text (Full, R/W) | 10675 | 7171 | 6617 | 13355 | 10940 | 11722 | 13262 | 8113 | 9048 | 6032 | 7952 |
text (Min, R/W) | 6727 | 4631 | 4331 | 8569 | 7262 | 7720 | 9088 | 5287 | 5800 | 3948 | 5183 |
text (Full, R/O) | 4731 | 3147 | 2889 | 6235 | 5170 | 5497 | 6482 | 3833 | 3972 | 2862 | 3719 |
text (Min, R/O) | 3559 | 2485 | 2295 | 4575 | 4064 | 4240 | 5019 | 2993 | 3104 | 2214 | 2889 |
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*560 + F*550 | V*560 + F*550 | V*560 + F*550 | V*560 + F*544 | V*560 + F*550 | V*560 + F*544 | V*560 + F*544 | V*560 + F*544 | V*560 + F*550 | V*560 + F*550 | V*560 + F*550 |
Work area (_FS_TINY == 1) | V*560 + F*36 | V*560 + F*36 | V*560 + F*36 | V*560 + F*32 | V*560 + F*36 | V*560 + F*32 | V*560 + F*32 | V*560 + F*36 | V*560 + F*36 | V*560 + F*36 | V*560 + F*36 |
+FatFs R0.10a options: +_FS_READONLY 0 (R/W) or 1 (R/O) +_FS_MINIMIZE 0 (Full function) or 3 (Minimized function) +_USE_STRFUNC 0 (Disable string functions) +_USE_MKFS 0 (Disable f_mkfs function) +_USE_FORWARD 0 (Disable f_forward function) +_USE_FASTSEEK 0 (Disable fast seek feature) +_CODE_PAGE 932 (Japanese Shift-JIS) +_USE_LFN 0 (Disable LFN feature) +_MAX_SS 512 (Fixed sector size) +_FS_RPATH 0 (Disable relative path feature) +_FS_LABEL 0 (Disable volume label functions) +_VOLUMES V (Number of logical drives to be used) +_MULTI_PARTITION 0 (Single partition per drive) +_FS_REENTRANT 0 (Disable thread safe) +_FS_LOCK 0 (Disable file lock control) ++
次の表は構成オプションの設定値によりどの機能が削除されるかを示します。
+Function | _FS_MINIMIZE | _FS_READONLY | _USE_STRFUNC | _FS_RPATH | _FS_LABEL | _USE_MKFS | _USE_FORWARD | _MULTI_PARTITION | |||||||||||
0 | 1 | 2 | 3 | 0 | 1 | 0 | 1/2 | 0 | 1 | 2 | 0 | 1 | 0 | 1 | 0 | 1 | 0/1 | 2 | |
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_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_chmod | x | x | x | x | |||||||||||||||
f_utime | x | x | x | x | |||||||||||||||
f_rename | x | x | x | x | |||||||||||||||
f_chdir | x | ||||||||||||||||||
f_chdrive | x | ||||||||||||||||||
f_getcwd | x | x | |||||||||||||||||
f_getlabel | x | ||||||||||||||||||
f_setlabel | 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バイトになるので、スタック等のサイズはそれを考慮した十分なサイズでなければなりません。
+コードページ | コードサイズ[bytes] |
---|---|
SBCS | +3721 |
932(Shift-JIS) | +62609 |
936(GBK) | +177797 |
949(Korean) | +139857 |
950(Big5) | +111497 |
LFN機能の上手な使い方は、それを使わないということです。実際、組み込み用途ではLFN機能がどうしても必要になるということはほとんど無いはずです。LFNを有効にすると、選択されたコード・ページに応じてモジュール・サイズが増大されます。右の表に各コード・ページにおけるLFNを有効にしたときのモジュール・サイズの違いを示します。特に、CJK地域では数万の文字が使われていますが、不幸なことにそれは巨大なOEM-Unicode相互変換テーブルを要求し、モジュール・サイズは劇的に増大されます。その結果、それらのコード・ページにおいてLFNを有効にしたFatFsモジュールは、AVRを含む殆どの8ビット・マイコンにインプリメントされることができません。
+LFN機能のハードルはそれだけではありません。マイクロソフト社はFATファイル・システムについていくつかの特許を保有しています。いずれもLFN機能の実装に関するもので、その利用に対して$0.25/unitのライセンス料を要求しています。このため、商用製品でLFN機能を利用するときは、最終仕向地によってはライセンスが必要になります。最近のFAT32ドライバの多くはLFN機能を含んでいるため、それらの使用に当たってライセンスが必要になりますが、FatFsではLFN機能を構成オプションで任意にON/OFFできるため、無効にしてライセンス問題を回避することもできます。
+CP932(Shift_JIS)でかつ非LFN構成のときは、拡張文字の小文字(2バイト英字・キリル文字・ギリシャ文字)に対して大文字変換を行わず、小文字のままSFNエントリに記録・検索されます(日本語MSDOS仕様)。このため、非LFN構成で全角小文字を含むファイルを作成すると、NT系Windowsでそのファイルを開けなくなります。LFN構成では大文字変換を行います(NT系Windows仕様)。
+FatFs API上におけるファイル名等の文字列データの入出力は、デフォルトではANSI/OEMコードで行われますが、これをUnicode(UTF-16)に切り替えることもできます(_LFN_UNICODEオプションで設定)。つまり、これはFatFsがLFN機能に完全対応していることを意味します。Unicodeのファイル名に関する詳細は、ファイル名を参照してください。
+互いに異なるボリュームに対するファイル操作はリエントラントで、常に同時平行に動作できます。同じボリュームに対してはデフォルトではリエントラントではありませんが、_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モジュールそれ自体のリエントランシーについて説明しています。その下位のディスク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)が選択されるとデータ・メモリの消費はそれぞれのファイル・オブジェクトで512バイト減少されます。この場合、FatFsモジュールはファイル・データの転送とFAT/ディレクトリ・アクセスにファイル・システム・オブジェクト内のセクタ・バッファだけを使用します。タイニー・バッファの欠点は、セクタ・バッファにキャッシュされたFATデータがファイル・データの転送により失われ、クラスタ境界の毎にリロードされなければならないことです。でも、悪くない性能と少ないメモリ消費の視点から多くのアプリケーションに適するでしょう。
+図1はセクタの一部のデータがファイルI/Oバッファを経由で転送されることを示します。図2に示される長いデータの転送では、転送データの中間の1セクタまたはそれ以上のセクタにまたがる転送データがアプリケーション・バッファに直接転送されています。図3は転送データ全体がセクタ境界にアライメントされている場合を示しています。この場合、ファイルI/Oバッファは使用されません。直接転送においては最大の範囲のセクタがdisk_read()で一度に読み込まれますが、クラスタ境界を越えるマルチ・セクタ転送はそれが隣接であっても行われません。
+このように、セクタにアライメントしたファイルの読み書きへの配慮はバッファ経由のデータ転送を避け、読み書き性能は改善されるでしょう。その効果に加え、タイニー構成でキャッシュされたFATデータがファイル・データの転送によりフラッシュされず、非タイニー構成と同じ性能を小さなメモリ・フットプリントで達成できます。
+HDDなどのディスク・メディアとは異なり、SDCやCFCなどのフラッシュ・メモリ・メディアの性能を引き出すには、その特性を意識した制御が必要になります。
+フラッシュ・メモリ・メディアの書き込み速度はシングル・セクタ書き込みの時に最も低いものになり、一回のトランザクションで転送されるセクタ数が大きくなるほど書き込み速度は向上します。この効果はバス速度が高速になるほど顕著で、10倍以上の差が現れることも珍しくありません。テスト結果は、マルチ・セクタ書き込み(W:16K, 32 sectors)がシングル・セクタ書き込み(W:100, 1 sector)よりどの程度速いかを明確に示しています。大容量メディアほどシングル・セクタ書き込みが遅くなる点もまた重要です。書き込みトランザクションの回数はまた、メディアの寿命にも影響してきます。このため、アプリケーションはなるべく大きなブロック(クラスタ・サイズまたは2の累乗セクタ境界にアライメントした)で読み書きを行う必要があります。もちろん、アプリケーションからメディアに至る全てのレイヤがマルチ・セクタ転送に対応していないと意味がありません。残念ながら、既存のオープン・ソースのドライバの多くはマルチ・セクタ転送に未対応です。なお、FatFsモジュールおよびサンプル・ドライバはマルチ・セクタ転送に対応しています。
+通常のファイル消去では、記録されたデータに対して何らかの制御が行われるわけではなく、単にFAT上に未使用クラスタとして記録されているだけです。このため、ファイルが消去されたあともそれらは有効なメモリ・ブロックとしてフラッシュ・メモリ上に残ります。そこで、ファイルを消去するとき、占有していたデータ・セクタを明示的に消去(つまり未使用ブロックにする)することにより、メディア内の空きブロックを増やすことができます。これにより、次にそのブロックに書き込むときの消去動作が無くなり、書き込み性能が向上する可能性があります。また、ウェアレベリングに使えるブロックが増え、メディアの耐久性も向上するかも知れません。この機能を有効にするには、構成オプションの_USE_ERASEに1を設定します。これはフラッシュ・メモリ・メディアの内部動作に期待した制御なので、効果があるとは限りません。また、ファイル消去の時間が延びることも考慮に入れるべきです。
+ストレージ上のFAT構造を操作している途中で、停電、不正なメディアの取り外し、回復不能なデータ・エラー等の障害が発生すると、処理が中途半端な状態で中断され、その結果としてFATボリュームの構造が破壊される可能性があります。次にFatFsモジュールにおけるクリチカル・セクションと、その間の障害により起きうるエラーの状態を示します。
+赤で示したセクションを実行中に障害が発生した場合、クロス・リンクが発生して操作対象のファイル・ディレクトリが失われる可能性があります。黄色で示したセクションを実行中に障害が発生した場合、つぎのうちいずれかまたは複数の結果が生じる可能性があります。
+いずれも書き込み中や操作の対象でないファイルには影響はありません。これらのクリチカル・セクションは、ファイルを書き込みモードで開いている時間を最小限にするか、f_sync()を適宜使用することで図5のようにリスクを最小化することができます。
+FatFs APIの拡張的使用例です。有用なコードがあった場合は、随時追加していきます。。
+ +ソース・ファイルのヘッダにライセンス条件が記述されているので、利用の際はそれに従うこと。英語を読めない方のために以下に日本語訳を示しておきます。
+/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.10b (C)ChaN, 2014 +/-----------------------------------------------------------------------------/ +/ FatFsモジュールは、小規模な組み込みシステム向けの汎用FATファイルシステム・ +/ モジュールです。これはフリー・ソフトウェアとして、教育・研究・開発のために +/ 以下のライセンス・ポリシーの下で公開されています。 +/ +/ Copyright (C) 2014, ChaN, all right reserved. +/ +/ * FatFsモジュールはフリー・ソフトウェアであり、また無保証です。 +/ * 用途に制限はありません。あなたの責任の下において、個人的・非営利的な +/ ものから商用製品の開発に及ぶ目的に使用・改変・再配布することができます。 +/ * ソース・コードを再配布するときは、上記の著作権表示を保持しなければなりません。 +/ +/-----------------------------------------------------------------------------/+
要するにFatFsはタダで自由に使えるということです。ソース・コードを再配布するときは、このブロックをそのまま保持しておくこと。このようにFatFsはBSDライクなライセンスとしていますが、一つ大きな違いがあります。特に組み込み用途での利用価値を高めるため、バイナリ形式(ソース・コードを含まない形式全て)での再配布については、条件は設けていません。その場合は、FatFsおよびそのライセンス文書についてはドキュメントに明記してもしなくてもかまいません。これは、一条項BSDライセンスと等価ということです。もちろんGNU GPLプロジェクトとも共存可能です。何らかの変更を加えて再配布する際は、矛盾しない他のライセンス(GNU GPLや修正BSDライセンスなど)に変更することも可能です。
+JgEfBNgύX܂B
++FRESULT f_chdir ( + const TCHAR* path /* [IN] fBNgւ̃|C^ */ +); ++
+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 +
+e{[̃JgEfBNgύX܂BJgEfBNǵÃ{[̃}Eg삪sꂽƂA[gEfBNgɏݒ肳܂BJgEfBNǵAt@CEVXeEIuWFNgɕێ邽߁Ã{[gpSẴ^XNɑĉe^܂B
+_FS_RPATH == 1̂ƂɎgp\ƂȂ܂B
++ /* JgEhCũJgEfBNgύX ([gdir1) */ + f_chdir("/dir1"); + + /* hCu2̃JgEfBNgύX (efBNg) */ + f_chdir("2:.."); ++
JgEhCuύX܂B
++FRESULT f_chdrive ( + const TCHAR* path /* [IN] ΏۃhCuw肵܂ */ +); ++
+FR_OK, +FR_INVALID_DRIVE +
+JgEhCuύX܂BVXeN̏l̓hCu0łB̐ݒFatFsW[̐ÓIϐɋL^邽߁ASẴ^XNɑĉe^܂B
+_FS_RPATH == 1ŁA_VOLUMES > 1̂ƂɎgp\ƂȂ܂B
+t@C܂̓TuEfBNg̑ύX܂B
++FRESULT f_chmod ( + const TCHAR* path, /* [IN] IuWFNgւ̃|C^ */ + BYTE attr, /* [IN] ݒl */ + BYTE mask /* [IN] ύX}XN */ +); ++
l | Ӗ |
---|---|
AM_RDO | [hEI[ |
AM_ARC | A[JCu |
AM_SYS | VXe |
AM_HID | qhD |
+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ŁA_FS_MINIMIZE == 0̂Ƃgp\łB
+
+ /* [hI[ZbgAA[JCuNAȂ͕ύXȂ */
+ f_chmod("file.txt", AM_RDO, AM_RDO | AM_ARC);
+
+t@C܂B
++FRESULT f_close ( + FIL* fp /* [IN] t@CEIuWFNgւ̃|C^ */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_INVALID_OBJECT, +FR_TIMEOUT +
+t@C܂B炩݂̏̍sꂽt@C̏ꍇALbVꂽ([h/CgEobt@̃f[^AύXꂽFATfBNg)̓fBXNɏ߂܂BIƁÃt@CEIuWFNg͖ɂȂÃł܂B
+t@CEIuWFNgǂݏop[hŁA_FS_LOCKIvVIĂȂꍇ́At@CɃt@CEIuWFNgj邱Ƃł܂BA͏̌݊̓_Ő͂܂B
+SĂ̍\Ŏgp\łB
+fBNg܂B
++FRESULT f_closedir ( + DIR* dp /* [IN] fBNgEIuWFNgւ̃|C^ */ +); ++
+FR_OK, +FR_INT_ERR, +FR_INVALID_OBJECT, +FR_TIMEOUT +
+fBNg܂BIƁÃfBNgEIuWFNg͖ɂȂÃł܂B
+_FS_LOCKIvVIĂȂꍇ́Ȁs킸ɃfBNgEIuWFNgj邱Ƃł܂BA͏̌݊̓_Ő͂܂B
+_FS_MINIMIZE <= 1̂Ƃgp\ɂȂ܂B
+Xg[WEfoCX܂B
++DSTATUS disk_initialize ( + BYTE pdrv /* [IN] hCuԍ */ +); ++
͖̊߂lƂăfBXNEXe[^XԂ܂BfBXNEXe[^X̏ڍׂɊւĂdisk_status()QƂĂB
+Xg[WEfoCXAf[^̓ǂݏȂǑSĂ̓삪\ȏԂɂ܂BƁA߂lSTA_NOINITtONA܂B
+AvP[V͂̊ĂяoĂ͂Ȃ܂BȂƁAFAT{[j\܂BG[ɂďKvȂƂ́Af_mount()gpĂBFatFsW[́A}EgɂAKvɉĂ̊Ăяo܂B
+ʓIȃf[^ǂݏȊÕXg[WEfoCX̂ɑlXȐs܂B
++DRESULT disk_ioctl ( + BYTE pdrv, /* [IN] hCuԍ */ + BYTE cmd, /* [IN] R}h */ + void* buff /* [I/O] f[^nobt@ */ +); ++
Xg[WEfoCX̎ނɂT|[gR}h͈قȂ܂AFatFsW[̂́A̔ėpR}ĥݎgpÃfoCXɈˑ͍s܂B
+R}h | |
---|---|
CTRL_SYNC | Xg[WEfoCX̃f[^ݏ܂BCgEobNELbVȂǂ݂ꍇ́A܂ĂȂf[^݂܂BfBAւ݂̏ꂼdisk_write()̓Ŋꍇ́ÃR}hɑĂ邱Ƃ͂܂B |
GET_SECTOR_COUNT | buff̎wDWORD^ϐɃhCȗZN^Ԃ܂Bf_mkfs()f_fdisk()ĂяoA쐬{[̃TCY肷邽߂Ɏgp܂B |
GET_SECTOR_SIZE | buff̎wWORD^ϐɃhCũZN^ETCYԂ܂BLl512A1024A2048܂4096łBZN^ETCYŒ\(_MAX_SS ==_MIN_SS)̂Ƃ͂̃R}h͎g邱Ƃ͂ȂAɂ̃ZN^ETCYœ삵ȂȂ܂B |
GET_BLOCK_SIZE | buff̎wDWORD^ϐɃtbVȄubNETCY(ZN^P)Ԃ܂B132768͈̔͂2̗ݏ̒lłȂȂ܂Bsȏꍇ܂̓tbVEȊÕfBAł1Ԃ܂Bf_mkfs()ł̂ݎgpA{[̃f[^̈͂̋EɃACg܂B |
CTRL_ERASE_SECTOR | tbVË̗̖IBbuff̎wDWORD^zɂ͏̈ {JnZN^,IZN^} w肵ČĂяo܂B_USE_ERASE1̂ƂANX^ƂɌĂяo܂B́AATAR}hEZbgTrimR}hƓŁA̋@\T|[gȂꍇ͉Kv͂܂B܂A߂l̓`FbNꂸASɍsȂƂĂFatFs̓ɂ͉e܂B |
FatFŝ̓foCXˑR}h[U`R}h͈؎gp܂AAvP[V牽炩̃foCX䂪sƕ֗ȂƂ܂BAvP[VŕWȊO̐䂪KvȂƂ́AKvɉă[U`R}hljėpƂ悢ł傤BɃR}h̗܂B
+R}h | |
---|---|
CTRL_FORMAT | fBA̕tH[}bgs܂BbuffNULLłȂƂAis\̂߂̃R[obÑAhX܂B |
CTRL_POWER_IDLE | foCXAChԂɂ܂Bʏ̓ǂݏvŃANeBuԂɖ߂ȂASTA_NOINITtOZbgKv͂܂B |
CTRL_POWER_OFF | foCXVbg_EԂɂ܂BSTA_NOINIT̓Zbg܂BfoCXdisk_initialize()ŃANeBuԂɖ߂܂B |
CTRL_LOCK | [Uɂ郁fBA̎o֎~܂B |
CTRL_UNLOCK | [Uɂ郁fBA̎o܂B |
CTRL_EJECT | fBAro܂BASTA_NOINITSTA_NODISKtO̓Zbg܂B |
MMC_GET_TYPE | J[hE^CvtO(b0:MMCv3, b1:SDv1, b2:SDv2+, b3:LBA)buff̎BYTEϐɓǂݏo܂B(MMC/SDJ[hp) |
MMC_GET_CSD | CSDWX^̓ebuff̎16oCg̃obt@ɓǂݏo܂B(MMC/SDJ[hp) |
MMC_GET_CID | CIDWX^̓ebuff̎16oCg̃obt@ɓǂݏo܂B(MMC/SDJ[hp) |
MMC_GET_OCR | OCRWX^̓ebuff̎4oCg̃obt@ɓǂݏo܂B(MMC/SDJ[hp) |
MMC_GET_SDSTAT | SD STATUSWX^̓ebuff̎64oCg̃obt@ɓǂݏo܂B(SDJ[hp) |
ATA_GET_REV | rWER[hbuff̎16oCg̃obt@ɓǂݏo܂B(ATA/CFJ[hp) |
ATA_GET_MODEL | fER[hbuff̎40oCg̃obt@ɓǂݏo܂B(ATA/CFJ[hp) |
ATA_GET_SN | VAԍbuff̎20oCg̃obt@ɓǂݏo܂B(ATA/CFJ[hp) |
[hEI[\ŁAZN^ETCYŒ\̂Ƃ́Å͕KvƂ܂B
+Xg[WEfoCXf[^ǂݏo܂B
++DRESULT disk_read ( + BYTE pdrv, /* [IN] hCuԍ */ + BYTE* buff, /* [OUT] ǂݏoobt@ւ̃|C^ */ + DWORD sector, /* [IN] ǂݏoJnZN^ԍ */ + UINT count /* [IN] ǂݏoZN^ */ +); ++
buffBYTE^Ȃ̂ŁAw肳AhXɃ[hEACgĂƂ͌܂BACgEAhXւ̓]́Aړ]ɂĔ邱Ƃ܂BAn[hEFA̐ł̂悤ȓ]s\ȂƂ́Åœi]Ȃǂĉ邩A܂͕ʂ̕@őΉȂȂ܂Bɂ̑Ή@܂(ꂩOK)B
+ʓIɁAZN^̓]v́AXg[WEfoCXɑĉ\Ȍ}`EZN^]ȂȂ܂B̃VOEZN^ǂݏoɕꂽꍇAX[vbgቺ邱Ƃ܂B
+Xg[WEfoCX̏Ԃ擾܂B
++DSTATUS disk_status ( + BYTE pdrv /* [IN] hCuԍ */ +); ++
Xg[WEfoCX̏Ԃ̃tȎgݍ킹lŕԂ܂B
+Xg[WEfoCXɃf[^݂܂B
++DRESULT disk_write ( + BYTE pdrv, /* [IN] hCuԍ */ + const BYTE* buff, /* [IN] ރf[^ւ̃|C^ */ + DWORD sector, /* [IN] ݊JnZN^ԍ */ + UINT count /* [IN] ރZN^ */ +); ++
buffɎw肳AhXɃ[hEACgĂƂ͌܂Bڍׂ́Adisk_read()̉QƂĂB
+ʓIɁAZN^̓]v́AfoCXɑĉ\Ȍ}`EZN^]ȂȂ܂B̃VOEZN^݂ɕꂽꍇAX[vbgቺ邱Ƃ܂B
+FatFs̓fBXNx@\Ƃz肵Ă܂B̊߂ƂAfoCXݒƂLbVɏ܂ꂽȂǁAKf[^݂̏ĂKv͂܂BAbuff̃f[^́Å߂ƖƂȂ܂B̗݊v́Adisk_ioctl()CTRL_SYNCR}hɂčs܂B̂悤Ȓx@\ꂽꍇAX[vbgɌコ邱Ƃł܂B
+AvP[V͂̊ĂяoĂ͂Ȃ܂BȂƁAFAT{[j\܂B
+[hEI[\(_FS_READONLY == 1)ł͕͂̊KvƂ܂B
+[h/CgE|C^t@CI[ɒBĂ邩ǂׂ܂B.
++int f_eof ( + FIL* fp /* [IN] t@CEIuWFNg */ +); ++
[h/CgE|C^t@CI[ɂǂݏof[^Ȃꍇ́A0ȊO̒lԂ܂BȊO̎0Ԃ܂B
+f_eof́ArWł̓}NƂĎĂ܂B
+
+#define f_eof(fp) (((fp)->fptr) == ((fp)->fsize) ? 1 : 0)
+
+Ɏgp\B
+G[̗Lׂ܂B
++int f_error ( + FIL* fp /* [IN] t@CEIuWFNg */ +); ++
t@C쒆̃G[ɂďfĂꍇ́A0ȊO̒lԂ܂BȊO̎0Ԃ܂B
+f_erroŕArWł̓}NƂĎĂ܂B
+
+#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
+
+Ɏgp\B
+ݎ擾܂B
++DWORD get_fattime (void); ++
݂̃[JE^CDWORDlɃpbNĕԂ܂BrbgEtB[h͎Ɏ悤ɂȂ܂B
+RTCT|[gȂVXełA_~[Ƃĉ炩̓tƂėLȒlԂׂłB0ȂǂԂꍇÃt@C̃^CX^v͖ɂȂ܂B
+[hEI[\(_FS_READONLY == 1)ł͕͂̊KvƂ܂B
+hCu܂B
++FRESULT f_fdisk ( + BYTE pdrv, /* [IN] hCuԍ */ + const DWORD part[], /* [IN] }bvEe[u */ + void* work /* [-] [NGA */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_NOT_READY, +FR_WRITE_PROTECTED, +FR_INVALID_PARAMETER +
+̊́Aw肳ꂽhCuMBRɋe[u쐬܂B敪͈ʓIFDISK`ōs߁Aő4̊{쐬邱Ƃł܂Bgɂ͑ΉĂ܂B}bve[upart[]ɂ̓hCuǂ̂悤ɕ邩w肵ēn܂B̔z4̍ڂ琬A擪̍ڂ1Ԗڂ́AŌ̍ڂ4Ԗڂ̋̃TCY܂Bl100ȉ̏ꍇAhCȗeʂɑ銄p[ZgPʂŎw肵܂B100l̏ꍇ̓ZN^̒ڎwɂȂ܂B
+_FS_READOLNY == 0 _USE_MKFS == 1 _MULTI_PARTITION == 1 ̂Ƃgp\łB
++ /* [U`̃{[Ǘe[u (_MULTI_PARTITION == 1 ̂ƂKv) */ + + PARTITION VolToPart[] = { + {0, 1}, /* _hCu 0 ==> hCu 0, 1 */ + {0, 2}, /* _hCu 1 ==> hCu 0, 2 */ + {1, 0} /* _hCu 2 ==> hCu 1, o */ + }; ++
+ /* VhCu(0)̏ */ + + FATFS fs; + DWORD plist[] = {50, 50, 0, 0}; /* 2 */ + BYTE work[_MAX_SS]; + + f_fdisk(0, plist, work); /* hCu 0 ̕ */ + + f_mount(&fs "0:", 0); + f_mkfs("0:", 0, 0); /* _hCu 0 ̃tH[}bg. ͖. */ + f_mount(0, "0:", 0); + + f_mount(&fs, "1:", 0); + f_mkfs("1:", 0, 0); /* _hCu 0 ̃tH[}bg. ͖. */ + f_mount(0, "1:", 0); + ++
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オプションを有効にすることでドライブ番号の識別には数字のほか、任意の文字列を使用することも可能になります。
+ファイル関数の入出力のうちファイル名やパス名を指定する引数の型は、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、第一区画~第四区画の順に行われます。
+_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, 自動検出 */ +}; + +++
複数区画指定を使用する場合、次の点に注意しなければなりません。 +
t@Cf[^ǂݏoAMXg[ɒړ]܂B
++FRESULT f_forward ( + FIL* fp, /* [IN] t@CEIuWFNg\ */ + UINT (*func)(const BYTE*,UINT), /* [IN] f[^] */ + UINT btf, /* [IN] ]oCg */ + UINT* bf /* [OUT] ]ꂽoCg */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_DENIED, +FR_INVALID_OBJECT, +FR_TIMEOUT +
+t@C̃f[^obt@ɓǂݏoɑMXg[ɒړ]܂BAvP[VŃf[^Eobt@KvƂȂ̂ŁǍꂽŗLłB[h/CgE|C^͓]ꂽoCgi݂܂Bw肳ꂽoCg̓]Ƀt@C̏I[ɒBꍇMXg[rW[ɂȂꍇA*bfbtfȂ܂B
+_USE_FORWARD == 1ŁA_FS_TINY == 1̂ƂɎgp\łB
++/*-----------------------------------------------------------------------*/ +/* f_forwardĂf[^M̗ */ +/*-----------------------------------------------------------------------*/ + +UINT out_stream ( /* ߂l: ]ꂽoCg܂̓Xg[̏ */ + const BYTE *p, /* ]f[^w|C^ */ + UINT btf /* >0: ]s(oCg). 0: Xg[̏Ԃׂ */ +) +{ + UINT cnt = 0; + + + if (btf == 0) { /* ZXv */ + /* Xg[̏ԂԂ (0: rW[, 1: fB) */ + /* UAfBԂA]vŏȂƂ1oCg */ + /* ]Ȃ f_forward FR_INT_ERR ƂȂB */ + if (FIFO_READY) cnt = 1; + } + else { /* ]v */ + do { /* SẴoCg]邩AXg[rW[ɂȂ܂ŌJԂ */ + FIFO_PORT = *p++; + cnt++; + } while (cnt < btf && FIFO_READY); + } + + return cnt; +} + + +/*-----------------------------------------------------------------------*/ +/* f_forward̎gp */ +/*-----------------------------------------------------------------------*/ + +FRESULT play_file ( + char *fn /* ĐI[fBIEt@Cw|C^ */ +) +{ + FRESULT rc; + FIL fil; + UINT dmy; + + /* t@Cǂݏo[hŊJ */ + rc = f_open(&fil, fn, FA_READ); + if (rc) return rc; + + /* SẴf[^]邩G[܂ő */ + while (rc == FR_OK && fil.fptr < fil.fsize) { + + /* ق̏... */ + + /* I܂͗vɉăf[^Xg[ɑo */ + rc = f_forward(&fil, out_stream, 1000, &dmy); + } + + /* t@CĖ߂ */ + f_close(&fil); + return rc; +} ++
JgEfBNg܂B
++FRESULT f_getcwd ( + TCHAR* buff, /* [OUT] obt@ */ + UINT len /* [IN] obt@ETCY */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_NOT_ENABLED, +FR_NO_FILESYSTEM, +FR_TIMEOUT, +FR_NOT_ENOUGH_CORE +
+JgEhCũJgEfBNg̃tEpX擾܂B_VOLUMES2ȏ̂Ƃ́A_hCuԍ̕tꂽpXƂȂ܂B
+_FS_RPATH == 2̂Ƃgp\łB
+{[̋̈̃TCY擾܂B
++FRESULT f_getfree ( + const TCHAR* path, /* [IN] ΏۃhCuw肵܂ */ + DWORD* nclst, /* [OUT] NX^i[ϐւ̃|C^ */ + FATFS** fatfs /* [OUT] t@CEVXeEIuWFNgw|C^ւ̃|C^ */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_INVALID_DRIVE, +FR_NOT_ENABLED, +FR_NO_FILESYSTEM, +FR_TIMEOUT +
+_hCű̈̃TCYNX^PʂŎ擾܂BԂꂽt@CEVXeEIuWFNgcsizeoNX^̃ZN^Ă̂ŁAɃZN^Pʂ̋TCYvZł܂BFAT32{[ɂẮAFSINFȌۂ̋NX^ƓĂȂꍇAsmȒlԂ\܂B̖邽߁A_FS_NOFSINFOIvVŃ}Eg͕̏KtFATXL悤ɍ\邱Ƃł܂B
+_FS_READONLY == 0ŁA_FS_MINIMIZE == 0̂Ƃgp\łB
++ FATFS *fs; + DWORD fre_clust, fre_sect, tot_sect; + + + /* hCu1̃{[ƋNX^ */ + res = f_getfree("1:", &fre_clust, &fs); + if (res) die(res); + + /* SZN^ƋZN^vZ */ + tot_sect = (fs->n_fatent - 2) * fs->csize; + fre_sect = fre_clust * fs->csize; + + /* {[Ŝ̃TCYƋ̃TCY\ (512oCg/ZN^Ɖ) */ + printf("%10lu KiB total drive space.\n%10lu KiB available.\n", + tot_sect / 2, fre_sect / 2); ++
{[Ex擾܂B
++FRESULT f_getlabel ( + const TCHAR* path, /* [IN] ΏۃhCu */ + TCHAR* label, /* [OUT] {[i[obt@ */ + DWORD* vsn /* [OUT] {[EVAԍi[ϐ */ +); ++
+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̂ƂɎgp\łB
++ char str[12]; + + /* ftHgEhCũ{[ */ + f_getlabel("", str, 0); + + /* hCu2̃{[ */ + f_getlabel("2:", str, 0); ++
t@C當ǂݏo܂B
++TCHAR* f_gets ( + TCHAR* buff, /* [OUT] obt@ */ + int len, /* [IN] obt@̃TCY */ + FIL* fp /* [IN] t@CEIuWFNg */ +); ++
buffԂ܂B
+̊f_read()̃bp[łBǂݏóAŏ'\n'ǂݍނAt@CI[ɒB邩Alen - 1ǂݏo܂ő܂Bǂݍ܂ꂽ̏I[ɂ'\0't܂BɃt@CI[1ǂݍ܂ȂƂA܂͉炩̃G[Ƃ͎͊skE|C^Ԃ܂Bt@CI[G[f_eof(),f_error()}NŒׂ܂B
+Unicode API\(_LFN_UNICODE == 1)IĂƂ́AbuffUTF-16ɂȂ܂At@C̃GR[h́A_STRF_ENCODEIvVőIł܂BȊO͖̎ϊ(1oCg/1)œǂݏo܂B
+_USE_STRFUNC1܂2̂Ƃgp\łB2̂Ƃ́At@CɊ܂܂'\r'菜ăobt@ɓǂݍ܂܂B
+t@C̃[h/CgE|C^ړ܂B܂AV[N@\gpɂCLMT(q)̍쐬ɂgp܂B
++FRESULT f_lseek ( + FIL* fp, /* [IN] t@CEIuWFNg\̂ւ̃|C^ */ + DWORD ofs /* [IN] ړItZbg */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_INVALID_OBJECT, +FR_TIMEOUT, +FR_NOT_ENOUGH_CORE +
+t@C̃[h/CgE|C^(ɓǂݏoE݂oCg̃ItZbg)ړ܂BItZbǧ_̓t@C擪łB݃[hŃt@CETCY傫Ȓlw肷ƁA܂Ńt@CETCYgAgꂽ̃f[^͖`ƂȂ܂Bf[^xɏ݂Ƃ́A\߂̊ŕKvȃTCY܂Ńt@CETCYgĂƗǂł傤Bf_lseek()IƂ́A[h/CgE|C^ړ`FbNׂłB[h/CgE|C^w菬Ƃ́Ǎl܂B
+_USE_FASTSEEK1ŁAt@CEIuWFNgcltbloNULLȊO(f_open()NULLɐݒ肳)̂ƂAV[NE[hɂȂ܂B̓t@C̃NX^zu(CLMT)ɕێĂƂɂAFATɃANZX邱ƂȂV[NOEV[Nɍs@\łBV[NE[h́Af_read()/f_wtite()̓ɂKp܂BV[NE[hłf_wtite()/f_lseek()ɂt@CETCY̊g͂ł܂B
+V[NsOɁACLMT쐬ĂKv܂B쐬ɂ́A܂CLMTi[obt@(DWORD^z)Acltbloɂ̃|C^Zbg܂BāAz̐擪vfɂ̔z̃TCY(vf)Af_lseek()ofsCREATE_LINKMAPw肵ČĂяo܂BCLMT쐬Aȍ~f_read()/f_write()/f_lseek()łFATւ̃ANZX͔܂BFR_NOT_ENOUGH_COREŎsƂ͔zTCYsŁA擪vfɂ͎ۂɕKvƂȂvfԂ܂BKvȗvf́A(t@C̕ + 1) * 2 łBƂAt@C5̃tOgɕfĂƂɕKvȗvf́A12ƂȂ܂B
+_FS_MINIMIZE < 3̂Ƃgp\łB
++ /* t@CJ */ + fp = malloc(sizeof (FIL)); + res = f_open(fp, "file.dat", FA_READ|FA_WRITE); + if (res) ... + + /* t@CEItZbg5000ֈړ */ + res = f_lseek(fp, 5000); + + /* t@CI[ֈړ(t@CNjL̏) */ + res = f_lseek(fp, f_size(fp)); + + /* 3000oCgi߂ */ + res = f_lseek(fp, f_tell(fp) + 3000); + + /* 2000oCg߂ (bvAEhɒ) */ + res = f_lseek(fp, f_tell(fp) - 2000); ++
+/* NX^s蓖 (Xg[~OECg̃obt@EI[o[h~) */ + + res = f_open(fp, "record.wav", FA_CREATE_NEW | FA_WRITE); /* t@C쐬 */ + + res = f_lseek(fp, MAX_SIZE); /* \ȃNX^̐s蓖 */ + if (res || f_tell(fp) != PRE_SIZE) ... /* t@Cgꂽ`FbN */ + + res = f_lseek(fp, DATA_START); /* f[^EXg[̋L^(AP[VfBC) */ + ... + + res = f_truncate(fp); /* sv̈̐̂ */ + res = f_lseek(fp, 0); /* wb_̋L^ */ + ... + + res = f_close(fp); ++
+/* V[N@\g */ + + DWORD clmt[SZ_TBL]; /* NE}bvEe[ui[obt@ */ + + res = f_lseek(fp, ofs1); /* ʏV[N (I[vAcltblNULLɏ) */ + + fp->cltbl = clmt; /* V[N@\̗L */ + clmt[0] = SZ_TBL; /* 擪vfɔzvfZbg */ + res = f_lseek(fp, CREATE_LINKMAP); /* CLMT̍쐬 */ + ... + + res = f_lseek(fp, ofs2); /* ȍ~Af_read/f_write/f_lseekFATANZX͔Ȃ */ ++
fBNg쐬܂B
++FRESULT f_mkdir ( + const TCHAR* path /* [IN] 쐬fBNgւ̃|C^ */ +); ++
+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 +
+̃fBNg쐬܂B
+_FS_READONLY == 0ŁA_FS_MINIMIZE == 0̂Ƃgp\łB
++ 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); ++
_hCuFAT{[쐬(tH[}bg)܂B
++FRESULT f_mkfs ( + const TCHAR* path, /* [IN] _hCuԍ */ + BYTE sfd, /* [IN] 쐬@ */ + UINT au /* [IN] NXE^TCY */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_NOT_READY, +FR_NOT_ENABLED, +FR_MKFS_ABORTED, +FR_INVALID_PARAMETER +
+hCuFAT{[쐬܂BFDISK`w肳ꂽꍇ́AhCuŜ߂{(p[e[V)쐬A̒FAT{[쐬܂BSFD`ł́AFAT{[hCu̐擪ZN^x^ō쐬܂B
+tH[}bg_hCu}`Ep[e[V@\(_MULTI_PARTITION)ɂē̋(1`4)ɌѕtĂꍇ́A̋̒FAT{[쐬܂Bsfd͖A܂Ή镨hCu͂ɐ旧Af_fdisk()܂͑̃c[œKɋݒ肳ĂKv܂B
+p[e[V`ɂ́AFDISK`SFD`̓ʂ肠܂BFDISK`́An[hfBXNAMMCASDCACFCAU DiskȂǂŕWIɎgp܂BFDISK`ł͈̕hCuɈ܂͕̋쐬邱Ƃł܂BǗMBR(hCu̐擪ZN^)ɋL^܂BSFD`͒Pɉ̕sȂ`ŁA{[͕hCu̐擪ZN^Jn܂BSFD`́Atbs[EfBXNA}CNhCuAwfBXNAт̑X[p[Etbs[EfBAŕWIɎgpĂ܂B
+FAT^Cv(FAT12/FAT16/FAT32)́Ã{[NX^ɂĂ̂錈܂[FATdl]ɂȂĂāAȊO̗v͂܂BāAǂFAT^CvɂȂ邩̓{[ETCYƃNX^ETCYɈˑ܂BNX^ETCY͑傫قǐ\オ܂B
+NX^FAT^Cv̋Eɋ߂ȂƂ́AFR_MKFS_ABORTEDŊs\܂B
+_FS_READONLY == 0ŁA_USE_MKFS == 1̂Ƃgp\łB
+_hCuɃt@CEVXeEIuWFNgo^E܂B
++FRESULT f_mount ( + FATFS* fs, /* [IN] t@CEVXeEIuWFNg */ + const TCHAR* path, /* [IN] _hCuԍ */ + BYTE opt /* [IN] IvV */ +); ++
+FR_OK, +FR_INVALID_DRIVE, +FR_DISK_ERR, +FR_NOT_READY, +FR_NO_FILESYSTEM +
+FatFsW[ł́Aꂼ̘_hCut@CEVXeEIuWFNgƂ[NEGAKvłB̊͘_hCuɃt@CEVXeEIuWFNgo^薕肵܂B炩̃t@CgpOɁÅł̘_hCũt@CEVXeEIuWFNg^ĂȂȂ܂BfsɃkE|C^w肷ƁA̘_hCũt@CEVXeEIuWFNg̓o^͖邾łBo^ꂽt@CEVXeEIuWFNg͉̃ł܂BΏۂ̘_hCuɊJĂt@CfBNgꍇA͑SĖɂȂ܂B͎̊̓̂悤ȏɍs܂B
+opt0w肷ƁA}Eg(hCȕAFAT{[̌ABPB͂t@CEVXeEIuWFNg)͍sꂸA͕hCȕԂɊւ炸ɐ܂Bł͉ʃCւ̃ANZX͔Aw肳ꂽt@CEVXeEIuWFNgNA()ÃAhXzɓo^邾łBPɓo^ς݂̃t@CEVXeEIuWFNgNAړIɂg܂BāAă{[ւ̃ANZXsꂽƂ̂ꂩł^̏ꍇ́Aۂ̃}Eg삪s܂B
+opt1w肷ƁAo^ɑă}Eg삪s܂B}EgɎsƑΉG[Ԃ܂Ao^͗LȂ̂ő{[ւ̃ANZXōĂу}Eg삪s܂B
+
ʃC̎チfBǍoT|[gȂ(disk_status()ɔfȂ)Ƃ́AAvP[V̓fBǍケ̊Ńt@CEVXeEIuWFNgIɃNAčă}Egɍs悤ɂKv܂B
+SĂ̍\Ŏgp\łB
+t@CI[v܂͍쐬܂B
++FRESULT f_open ( + FIL* fp, /* [OUT] ̃t@CEIuWFNg\̂ւ̃|C^ */ + const TCHAR* path, /* [IN] t@Cւ̃|C^ */ + BYTE mode /* [IN] [htO */ +); ++
l | Ӗ |
---|---|
FA_READ | ǂݏo[hŊJ܂BǂݏꍇFA_WRITEƋɎw肵܂B |
FA_WRITE | ݃[hŊJ܂BǂݏꍇFA_READƋɎw肵܂B |
FA_OPEN_EXISTING | ̃t@CJ܂Bt@CƂ̓G[ɂȂ܂B(ftHg) |
FA_OPEN_ALWAYS | ̃t@CJ܂Bt@CƂ̓t@C쐬܂BNjL̏ꍇ́A̕@ŃI[vAf_lseek()Ńt@C̍ŌɈړĂB |
FA_CREATE_NEW | t@C쐬܂B̃t@Cꍇ́AFR_EXISTŎs܂B |
FA_CREATE_ALWAYS | t@C쐬܂B̃t@Cꍇ́ATCY0ɂĂJ܂B |
+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 +
+̃t@CJAVt@C쐬܂Bƃt@CEIuWFNg쐬Aȍ~̃t@CɑANZXɎgp܂Bt@CƂ́Af_close()gp܂B炩̕ύXsꂽt@Č㐳ȂꍇÃt@Cjꍇ܂B
+ɊJĂt@CJKvꍇ́AdANZXQƂĂBÃt@Cɑ鏑݃[h܂ޏdI[v͏ɋ֎~łB
+t@CEANZXJnOɁAf_mount()gĂꂼ̘_hCuɃ[NEGA(t@CEVXeEIuWFNg)^Kv܂B̏̌A̘_hCuɑđSẴt@Cg悤ɂȂ܂B
+SĂ̍\Ŏgp\łB_FS_READONLY == 1̂Ƃ́AFA_WRITE, FA_CREATE_ALWAYS, FA_CREATE_NEW, FA_OPEN_ALWAYS̊etO̓T|[g܂B
++/* eLXgt@Cǂݏoĕ\ */ + +FATFS FatFs; /* _hCũ[NEGA(t@CEVXeEIuWFNg) */ + +int main (void) +{ + FIL fil; /* t@CEIuWFNg */ + char line[82]; /* sobt@ */ + FRESULT fr; /* ߂l */ + + + /* ftHgEhCuɃ[NGA^ */ + f_mount(&FatFs, "", 0); + + /* eLXgEt@CJ */ + fr = f_open(&fil, "message.txt", FA_READ); + if (fr) return (int)fr; + + /* 1sǂݏoĕ\ */ + while (f_gets(line, sizeof line, &fil)) + printf(line); + + /* t@C */ + f_close(&fil); + + return 0; +} ++
+/* hCu1̃t@C "file.bin" hCu0փRs[ */ + +int main (void) +{ + FATFS fs[2]; /* _hCũ[NGA(t@CEVXeEIuWFNg) */ + FIL fsrc, fdst; /* t@CEIuWFNg */ + BYTE buffer[4096]; /* File copy buffer */ + FRESULT fr; /* FatFs function common result code */ + UINT br, bw; /* File R/W count */ + + /* hCu0,1Ƀ[NEGA^ */ + f_mount(&fs[0], "0:", 0); + f_mount(&fs[1], "1:", 0); + + /* hCu1̃Rs[t@CJ */ + res = f_open(&fsrc, "1:file.dat", FA_OPEN_EXISTING | FA_READ); + if (fr) return (int)fr; + + /* hCu0ɃRs[t@C쐬 */ + res = f_open(&fdst, "0:file.dat", FA_CREATE_ALWAYS | FA_WRITE); + if (fr) return (int)fr; + + /* Rs[Rs[Ƀf[^] */ + for (;;) { + res = f_read(&fsrc, buffer, sizeof buffer, &br); /* Rs[炩ǂݏo */ + if (res || br == 0) break; /* G[t@CI[ */ + res = f_write(&fdst, buffer, br, &bw); /* Rs[ɏ */ + if (res || bw < br) break; /* G[fBXNt */ + } + + /* SẴt@C */ + f_close(&fsrc); + f_close(&fdst); + + /* [NEGAJ */ + f_mount(NULL, "0:", 0); + f_mount(NULL, "1:", 0); + + return (int)fr; +} ++
fBNgJ܂B
++FRESULT f_opendir ( + DIR* dp, /* [OUT] fBNgEuWFNg\̂ւ̃|C^ */ + const TCHAR* path /* [IN] fBNgւ̃|C^ */ +); ++
+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 +
+ +fBNgJ܂BIA쐬ꂽDIR\̂gẴfBNg̍ڂǂݏo܂B
+_FS_MINIMIZE <= 1̂Ƃgp\ɂȂ܂B
+t@Cɏ݂܂B
++int f_printf ( + FIL* fp, /* [IN] t@CEIuWFNg */ + const TCHAR* fmt, /* [IN] 䕶 */ + ... +); ++
ɏ܂ƁA܂ꂽԂ܂BfBXNt܂͂̑G[ɂ萳ɏ܂ȂƂ́A͎sEOF (-1)Ԃ܂B
+̊́Af_putc()f_puts()̃bp[łB@\CWCũTuZbgƂȂĂāA䕶͎Ɏ̂gp\łB
+_FS_READONLY == 0ŁA_USE_STRFUNC1܂2̂Ƃgp\ɂȂ܂B2̎́Ao͂Ɋ܂܂'\n''\r'+'\n'ɓWJăt@Cɏ܂܂B
+APIUnicodeI(_LFN_UNICODE1)ĂƂ́AfmtUnicodeɂȂ܂At@C̃GR[h́A_STRF_ENCODEIvVőIł܂BȊO͖̎ϊ(1oCg/1)ŏ݂܂B
++ 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); /* _͖T|[g */ ++
t@Cɕ݂܂B
++int f_putc ( + TCHAR chr, /* [IN] ޕ */ + FIL* fp /* [IN] t@CEIuWFNg */ +); ++
ɏ܂ƏԂ܂BfBXNt܂̓G[ɂ菑܂ȂƂEOF (-1)Ԃ܂B
+APIUnicodeI(_LFN_UNICODE1)ĂƂ́AchrUTF-16ɂȂ܂At@C̃GR[h́A_STRF_ENCODEIvVőIł܂BȊO͖̎ϊ(1oCg/1)ŏ݂܂B
+1t@Cɏ݂܂B̊f_write()̃bp[łB
+_FS_READONLY == 0ŁA_USE_STRFUNC 1܂ 2̂Ƃgp\łB2w肷ƁA'\n''\r'+'\n'ɓWJăt@Cɏ܂܂B
+t@Cɕ݂܂B
++int f_puts ( + const TCHAR* str, /* [IN] ޕ */ + FIL* fp /* [IN] t@CEIuWFNg */ +); ++
ɏ܂ƁA܂ꂽԂ܂BfBXNt܂̓G[ɂ菑݂fꂽƂEOF (-1)Ԃ܂B
+APIUnicodeI(_LFN_UNICODE1)ĂƂ́AstrUTF-16ɂȂ܂At@C̃GR[h́A_STRF_ENCODEIvVőIł܂BȊO͖̎ϊ(1oCg/1)ŏ݂܂B
+t@Cɏ݂܂B̊f_write()̃bp[łB
+_FS_READONLY == 0ŁA_USE_STRFUNC1܂2̂Ƃgp\łB2w肷ƁAɊ܂܂'\n''\r'+'\n'ɓWJăt@Cɏ܂܂B
+FatFsのAPIでは、一部の関数を除き結果に応じた共通のリザルト・コード(FRESULT型(enum))を返します。関数が成功した場合は0を返します。失敗した場合は0以外の値を返し、値はエラーの種類を示します。
+ +t@Cf[^ǂݏo܂B
++FRESULT f_read ( + FIL* fp, /* [IN] t@CEIuWFNg\ */ + void* buff, /* [OUT] ǂݏof[^i[obt@ */ + UINT btr, /* [IN] ǂݏooCg */ + UINT* br /* [OUT] ǂݏoꂽoCg */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_DENIED, +FR_INVALID_OBJECT, +FR_TIMEOUT +
+ǂݍ݊JnʒúÃ݂[h/CgE|C^ɂȂ܂B[h/CgE|C^͓ǂݍ܂ꂽoCgi݂܂BÍA*br̒l`FbNׂłB*brbtrƂ́AǂݍݒɃt@C̏I[ɒBƂĂ܂B
+SĂ̍\Ŏgp\łB
+fBNgڂǂݏo܂B
++FRESULT f_readdir ( + DIR* dp, /* [IN] fBNgEuWFNg\̂ւ̃|C^ */ + FILINFO* fno /* [OUT] t@C\̂ւ̃|C^ */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_INVALID_OBJECT, +FR_TIMEOUT, +FR_NOT_ENOUGH_CORE +
+fBNg̍(t@CƃfBNg)ǂݏo܂B̊JԂs邱Ƃɂ肻̃fBNg̑SĂ̍ڂǂݏoƂł܂Bt@C̏ڍׂɂĂ FILINFO\̂QƂĂBSĂ̍ڂǂݏoAǂݏoڂƂ́Afname[]oɃkԂ܂BfnoɃkE|C^w肷ƁÃfBNg̃[hECfbNX擪Ɋ߂܂B܂Å͎Ɏ悤Ɋ֘A\IvVɂ蓮삪ς܂B
+hbgEGg("."A"..")́ApXLȂƂ(_FS_RPATH >= 1)ɂ̂ݏo͂Ɍ܂B
+LFN@\LȎ́Å̌Ăяoɐ旧FILINFO\̂lfnamelfsizeLȒlŏĂȂȂ܂BlfnameLFNi[obt@ŁAlfsize͂̃obt@̗vfłBLFNǂݏoKvȂƂ́AlfnameɃkE|C^ZbgĂB̏ɈłYꍇ́ALFNi[obt@ɃkԂ܂B
+܂AfBNgڂLFN݂Ȃꍇ́Afname[]ɉp܂܂ꍇ܂B
+_FS_MINIMIZE <= 1̂ƂɎgp\łB
++FRESULT scan_files ( + char* path /* Jnm[h ([NGAƂĂgp) */ +) +{ + FRESULT res; + FILINFO fno; + DIR dir; + int i; + char *fn; /* Unicode\z */ +#if _USE_LFN + static char lfn[_MAX_LFN + 1]; + fno.lfname = lfn; + fno.lfsize = sizeof lfn; +#endif + + + res = f_opendir(&dir, path); /* fBNgJ */ + if (res == FR_OK) { + i = strlen(path); + for (;;) { + res = f_readdir(&dir, &fno); /* fBNgڂ1ǂݏo */ + if (res != FR_OK || fno.fname[0] == 0) break; /* G[܂͍ږ̂Ƃ͔ */ + if (fno.fname[0] == '.') continue; /* hbgGg͖ */ +#if _USE_LFN + fn = *fno.lfname ? fno.lfname : fno.fname; +#else + fn = fno.fname; +#endif + if (fno.fattrib & AM_DIR) { /* fBNg */ + sprintf(&path[i], "/%s", fn); + res = scan_files(path); + if (res != FR_OK) break; + path[i] = 0; + } else { /* t@C */ + printf("%s/%s\n", path, fn); + } + } + f_closedir(&dir); + } + + return res; +} ++
t@C܂̓TuEfBNg̖O̕ύX܂͈ړ܂B
++FRESULT f_rename ( + const TCHAR* old_name, /* [IN] ÂIuWFNg */ + const TCHAR* new_name /* [IN] VIuWFNg */ +); ++
+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 +
+t@C܂̓TuEfBNg̖OύX܂B܂Aɕʂ̃fBNgւ̈ړ\łAقȂhCuւ̈ړ͂ł܂BJĂIuWFNgɑĎgpĂ͂Ȃ܂B
+_FS_READONLY == 0ŁA_FS_MINIMIZE == 0̂ƂɎgp\łB
++ /* t@C܂̓TufBNg̖OύX */ + f_rename("oldname.txt", "newname.txt"); + + /* t@C܂̓TufBNg̖O̕ύXƕʂ̃fBNgւ̈ړ */ + f_rename("oldname.txt", "dir1/newname.txt"); ++
DIR\̂́Af_opendir(), f_readdir()̃[NEGAƂĎgp܂BAvP[V́A̍\̂̃oĂ͂Ȃ܂B
++typedef struct { + FATFS* fs; /* et@CEVXeEIuWFNgւ̃|C^ */ + WORD id; /* et@CEVXeEIuWFNg̃}EgID */ + WORD index; /* ɌJnfBNgECfbNXԍ */ + DWORD sclust; /* e[uJnNX^ (0:[g) */ + DWORD clust; /* ݂̃NX^ԍ */ + DWORD sect; /* ݂̃ZN^ԍ */ + BYTE* dir; /* ݂SFNGgւ̃|C^ */ + BYTE* fn; /* SFNobt@ւ̃|C^ (in/out) {file[8],ext[3],status[1]} */ +#if _FS_LOCK + UINT lockid; /* bNID */ +#endif +#if _USE_LFN + WCHAR* lfn; /* LFNobt@ւ̃|C^ (in/out) */ + WORD lfn_idx; /* LFNGg̐擪CfbNX (0xFFFF:) */ +#endif +} DIR; ++
{[Ƀ{[Exݒ肵܂B
++FRESULT f_setlabel ( + const TCHAR* label /* [IN] ݒ肷{[Exւ̃|C^ */ +); ++
+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 +
+̐擪ɃhCuԍ܂ޏꍇ́A̘_hCuɑĐݒ肳܂B܂܂Ȃꍇ́AftHgEhCuɐݒ肳܂B{[Ex폜Ƃ́Akw肵܂B{[Ex̃tH[}bǵAt@C(SFN)ƂقړłA̓_قȂ܂B
+_FS_READONLY == 0ŁA_USE_LABEL == 1̂ƂɎgp\łB
++ /* ftHgEhCuɃ{[Exݒ */ + f_setlabel("DATA DISK"); + + /* hCu2Ƀ{[Exݒ */ + f_setlabel("2:DISK 3 OF 4"); + + /* hCu2̃{[Ex폜 */ + f_setlabel("2:"); ++
FATFS\(t@CEVXeEIuWFNg)́AX̘_hCũ_Ci~bNE[NEGAێAf_mount()FatFsW[ɓo^܂Bs^C~ÓAf_mount()(}Egw)̎s܂̓fBǍ̍ŏ̃t@CEANZX̎łBAvP[V́A̍\̂̃oĂ͂Ȃ܂B
+ ++typedef struct { + BYTE fs_type; /* FAT^Cv */ + BYTE drv; /* hCuԍ */ + BYTE csize; /* NX^̃ZN^ (1,2,4,8,...,128)*/ + BYTE n_fats; /* FAT̑d (1,2) */ + BYTE wflag; /* win[]_[eBEtO */ + BYTE fsi_flag; /* FSINFOtO (b7:Disabled, b0:Dirty)*/ + WORD id; /* t@CEVXeE}EgID */ + WORD n_rootdir; /* [gEfBNg̃Gg (FAT12/16) */ +#if _MAX_SS != _MIN_SS + WORD ssize; /* ZN^ETCY (512, 1024, 2048 or 4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* IuWFNgID */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* FSINFO: ŌɊ蓖ĂꂽNX^ԍ */ + DWORD free_clust; /* FSINFO: NX^ */ +#endif +#if _FS_RPATH + DWORD cdir; /* JgEfBNg̃NX^ (0:[g) */ +#endif + DWORD n_fatent; /* FATGg (NX^ + 2) */ + DWORD fsize; /* FAT 1̃ZN^ */ + DWORD volbase; /* {[JnZN^ */ + DWORD fatbase; /* FAT̈JnZN^ */ + DWORD dirbase; /* [gEfBNg̈JnZN^(NX^) */ + DWORD database; /* f[^̈JnZN^ */ + DWORD winsect; /* win[]ɌĂZN^ԍ */ + BYTE win[_MAX_SS]; /* fBXNEANZXEEBhE */ +} FATFS; ++
FIL\(t@CEIuWFNg)́Af_open()ŏAȌセ̃t@C̏Ԃێ܂B܂Af_close()Ńt@CƖ܂BAvP[V́A̍\̂̃oĂ͂Ȃ܂(cltbl͗O)B^Cj[\ł́AɃZN^Eobt@mۂ̂ŁALTCYɒӂKvłB
+ ++typedef struct { + FATFS* fs; /* et@CEVXeEIuWFNgւ̃|C^ */ + WORD id; /* et@CEVXeEIuWFNg̃}EgID */ + BYTE flag; /* t@CEXe[^XEtO */ + BYTE err; /* G[ftO */ + DWORD fptr; /* t@Cǂݏ|C^ (t@C擪̃oCgEItZbg) */ + DWORD fsize; /* t@CETCY(oCgP) */ + DWORD sclust; /* t@CJnNX^ԍ (0:蓖Ė) */ + DWORD clust; /* ݂̃NX^ */ + DWORD dsect; /* ݂̃f[^EZN^ */ +#if !_FS_READONLY + DWORD dir_sect; /* ̃t@C̃fBNgEGĝZN^ */ + BYTE* dir_ptr; /* ̃t@C̃fBNgւ̃|C^ */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* t@C̃NX^ENւ̃|C^ (I[vNULLZbg) */ +#endif +#if _FS_LOCK + UINT lockid; /* t@CEbNID */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* t@CEvCx[gEf[^]obt@ */ +#endif +} FIL; ++
FILINFO\̂́Af_stat(), f_readdir()ŕԂt@Cێ܂B
++typedef struct { + DWORD fsize; /* t@CETCY */ + WORD fdate; /* ŌɍXVꂽt */ + WORD ftime; /* ŌɍXVꂽ */ + BYTE fattrib; /* Agr[g */ + TCHAR fname[13]; /* Zt@C (8.3tH[}bg) */ +#if _USE_LFN + TCHAR* lfname; /* t@C̃obt@ւ̃|C^ */ + int lfsize; /* t@C̃obt@̃TCY [] */ +#endif +} FILINFO; ++
t@C̃TCY擾܂B
++DWORD f_size ( + FIL* fp /* [IN] t@CEIuWFNg */ +); ++
oCgPʂ̃t@CETCYԂ܂B
+f_sizéArWł̓}NƂĎĂ܂B
+
+#define f_size(fp) ((fp)->fsize)
+
+Ɏgp\B
+t@C܂̓TuEfBNgׁ݂̑A܂̏擾܂B
++FRESULT f_stat ( + const TCHAR* path, /* [IN] IuWFNgւ̃|C^ */ + FILINFO* fno /* [OUT] t@C\̂ւ̃|C^ */ +); ++
+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 +
+w肳ꂽt@C܂̓TuEfBNgׂ݂̑܂B݂Ȃꍇ́AFR_NO_FILEA܂B݂ꍇFR_OKAAt@C\̂ɂւ(TCYA^CX^vAђZt@C)XgA܂B
+_FS_MINIMIZE == 0̂ƂɎgp\łB
+ݒ̃t@C̃LbVꂽtbV܂B
++FRESULT f_sync ( + FIL* fp /* [IN] t@CEIuWFNg\̂ւ̃|C^ */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_INVALID_OBJECT, +FR_TIMEOUT +
+̊f_close()Ɠs܂At@C͈Jꂽ܂܂ɂȂAǂݏsł܂BMOȂǁA݃[hŒԃt@CJĂAvP[VɂāAI܂̗͋ǂƂł̊gp邱ƂɂAsӂ̓dffBA̎Oɂ莸f[^ŏɂ邱Ƃł܂B̔wiɂẮAAvP[VEm[gQƂĂB
+ۂ̂ƂAf_close()ł͂̊Ăяot@CEIuWFNgĂ邾Ȃ̂ŁAf_close()Of_sync()uƂ͖ӖłB
+_FS_READONLY == 0̂ƂɎgp\łB
+݂̃[h/CgE|C^擾܂B
++DWORD f_tell ( + FIL* fp /* [IN] t@CEIuWFNg */ +); ++
݂̃[h/CgE|C^(t@C擪̃oCgPʂ̃ItZbg)Ԃ܂B
+f_telĺArWł̓}NƂĎĂ܂B
+
+#define f_tell(fp) ((fp)->fptr)
+
+Ɏgp\B
+t@Cl߂܂B
++FRESULT f_truncate ( + FIL* fp /* [IN] t@CEIuWFNgւ̃|C^ */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_DENIED, +FR_INVALID_OBJECT, +FR_TIMEOUT +
+t@C݂̒̃[h/CgE|C^ɐl߂܂B[h/CgE|C^Ƀt@C̏I[wĂƂ́Å͉̌ʂ܂B
+_FS_READONLY == 0ŁA_FS_MINIMIZE == 0̂ƂɎgp\łB
+t@C܂̓TuEfBNg폜܂B
++FRESULT f_unlink ( + const TCHAR* path /* [IN] IuWFNgւ̃|C^ */ +); ++
+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 +
+폜Ώۂ̃IuWFNg̏ɓĂ͂܂ꍇÃANZX͋ۂ͎s܂B +
_FS_READONLY == 0ŁA_FS_MINIMIZE == 0̂ƂɎgp\łB
+t@C܂̓TuEfBNg̃^CX^vύX܂B
++FRESULT f_utime ( + const TCHAR* path, /* [IN] IuWFNgւ̃|C^ */ + const FILINFO* fno /* [IN] ݒ肷t */ +); ++
+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 +
+IuWFNg̃^CX^vύX܂B
+
+FRESULT set_timestamp (
+ char *obj, /* t@Cւ̃|C^ */
+ 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ŁA_FS_MINIMIZE == 0̂ƂɎgp\łB
+t@CɃf[^݂܂B
++FRESULT f_write ( + FIL* fp, /* [IN] t@CEIuWFNg */ + const void* buff, /* [IN] ݃f[^ */ + UINT btw, /* [IN] ރoCg */ + UINT* bw /* [OUT] ܂ꂽoCg */ +); ++
+FR_OK, +FR_DISK_ERR, +FR_INT_ERR, +FR_NOT_READY, +FR_DENIED, +FR_INVALID_OBJECT, +FR_TIMEOUT +
+݊JnʒúA[h/CgE|C^̈ʒuɂȂ܂B[h/CgE|C^͎ۂɏ܂ꂽoCgi݂܂BIAvoCg܂ꂽǂ*bw`FbNׂłB*bwbtw菬Ƃ́AfBXNEtӖ܂BfBXNEtĂƂ܂͂ɋ߂Ƃ́A䂪A܂ŎԂꍇ܂B
+_FS_READONLY == 0̂ƂɎgp\łB
+