NORTi File System
Version 4
ユーザーズガイド

2021 年 5 月 第 12 版

株式会社ミスポ第12版(本版)で改訂された項目

ページ

内容

7

未実装だった第 2FAT のサポートを特長から削除

10"NORTi File System Version 4 補足説明書"を"リリースノート"に訂正

12

デバッグ情報なしライブラリの廃止に伴い、その説明や SuperH での
例を削除

13

nofshpc.h/.c と noftide.h/.c の廃止や trueide.h/.c の追加に伴う見直し

15

チェックディスク機能の詳しい説明と、fspsubr.c を追加

16

SH7750 でのサンプルプログラムのファイルの例を削除

49

rename()に漏れていたディレクトリ名変更の説明を追加

第11版で改訂された項目

ページ

内容

13,14

｢2.3 デバイスドライバ｣を全面修正

16｢2.5 サンプルプログラム｣ 付属ファイルの説明や例を修正

17｢2.6 コンフィグレーション｣ FTP サーバが使用するリソース追記

18

サンプルでは nonecfg.c がコンフィグレーションヘッダをインクルードする役目であると明記

21,22

File System Ver.1 からの移行手順を追記

23,24

File System Ver.2 からの移行手順を追記

25｢2.10 Windows FAT ファイルシステムとの互換性｣を追加

73｢ATA ドライバの移植｣を「PC カードアクセス関数の移植」に改名

73,74

インターフェース形式毎にどのように関数を実装すべきかの記述を追加。記述漏れの関数の説明を追加

第10版で改訂された項目

ページ
8

内容
ANSI 準拠の API に fgetpos,fsetpos を追加

19

未実装の ANSI 準拠 API から fsetpos,fgetpos を削除

36

2 ギガバイトを超えるファイルの位置決めについての補足を追記

37

2 ギガバイトを超えるファイルの位置取得についての補足を追記

38-39

fsetpos,fgetpos についての記述を追加

62

補足を追加 dformat をサポートする/しないドライバについて----「サーバー」→「サーバ」、「割込み」→「割り込み」「下さい」→「ください」など表記のバラつきを統一

第9版で改訂された項目

ページ

内容

18,52

年の指定は1980年ではなく1900年からの年数であると訂正

52

年の値は80以上の値を指定する必要があることを注記

第8版で改訂された項目

ページ

内容

----

改訂項目を新しい順に並べ替え

9

ドキュメントについてのお願いを追記

12

MR-SHPC は SuperH 専用であることを注記

22,23

disk_ini に、disk_mount 時の全セクタチェック指定を追加

22

複数ドライブでは cycid=0 と指定できない制限について追記

46

readdir で取得できる direntx 構造体のエンディアンの説明を追記

62

ディスクドライバ関数のパラメータ説明漏れを修正

第7版で改訂された項目

ページ

内容

19

誤植を修正(fread を追加)

18,46

誤植を修正(1900 を 1980 に)2

第6版で改訂された項目

ページ

内容

11

SH-2 リトルエンディアン用ライブラリを追加

45,47

誤植を修正(fopen から opendir へ)

61

エラーコード EV_FILEFULL/EV_FREESECT を追加

第5版で改訂された項目

ページ

内容

6

チェックディスク機能の追加予定を削除

10

ALL マクロの説明を変更

14

チェックディスク機能の未サポートの記述を削除

34

fflush(NULL)の未サポートの記述を削除

第4版で改訂された項目

ページ

内容

6

CompactFlash のサンプルドライバの付属を削除

20

ATA ドライバに関する記述を削除

第3版で改訂された項目

ページ

内容

6

NFS 対応予定から予定を削除

9

サンプルボード名称を MS7709A から MS7750S に変更
コンパイラ略称例を SHC7 から SHC9 に変更

15

SHC5/6/7 から SHC7/8/9 に変更

17

LFS_UNICODE マクロの未サポートの記述を削除

3

目 次
第 1 章 概要................................................................. 7
1.1 特長 ................................................................... 7
1.2 ファイルシステムのバージョン ........................................... 7
1.3 ファイルシステム API 一覧 ............................................... 8初期化用の API............................................................. 8ANSI 準拠の API ............................................................ 8POSIX 準拠の API ........................................................... 8
独自拡張の API............................................................. 8
未実装の ANSI 準拠 API...................................................... 9
標準ライブラリとの関係 .................................................... 9
1.4 ファイル名の指定方法と最大長 ........................................... 9
第 2 章 導入................................................................ 10
2.1 ファイル構成 .......................................................... 10
フォルダ構造 ............................................................. 10
ドキュメント ............................................................. 10
2.2 ファイルシステム本体 .................................................. 11
ヘッダファイル ........................................................... 11
ソースファイル ........................................................... 11
ライブラリ ............................................................... 12
2.3 デバイスドライバ ...................................................... 13
ATA ドライバ.............................................................. 13
記録メディアへのアクセス ................................................. 14
RAM ディスクドライバ...................................................... 14
2.4 ユーティリティ ........................................................ 15
マルチセッション版 FTP サーバ ............................................. 15
チェックディスク機能 ..................................................... 15
2.5 サンプルプログラム .................................................... 16
CompactFlash 使用の有無(CF マクロ) ........................................ 16
ファイルシステムのバージョン(NOFILE_VER マクロ) ........................... 16
FTP サーバが使用するリソース.............................................. 16
2.6 コンフィグレーション .................................................. 17
コンフィグレーションヘッダのインクルード ................................. 17
ファイルシステムが使うリソース ........................................... 17
ファイルシステムのタスク優先度(LFS_TSKPRI マクロ) ......................... 17
ディスク書込み遅延時間(LFS_WRTDLY マクロ) ................................. 18
Shift-JIS/Unicode 変換テーブルの削減(LFS_UNICODE マクロ) .................. 18
コンフィグレーションの例 ................................................. 18
その他のコンフィグレーション ............................................. 18
2.7 現在日時の取得関数の実装 .............................................. 19
2.8 File System Ver.1 との互換性 ........................................... 20
File System Ver.1 の API .................................................. 20
File System Ver.1 のファイル構成 .......................................... 20
File System Ver.1 からの移行手順 .......................................... 20
2.9 File System Ver.2 との互換性 ........................................... 22
File System Ver.2 の API .................................................. 22
File System Ver.2 のファイル構成 .......................................... 22
File System Ver.2 からの移行手順 .......................................... 22
File System Ver.2 からの移行手順(HTTPD) ................................... 23
2.10 Windows FAT ファイルシステムとの互換性 ................................ 24
第３章 ファイルシステム API 解説 ........................................... 25
4

file_ini - ファイルシステムの初期化 ........................................ 25
disk_ini - ディスクドライバの初期化 ........................................ 26
disk_cache - ディスクキャッシュの設定 ...................................... 28
fopen - ファイルのオープン ................................................. 30
fclose - ファイルのクローズ ................................................ 31
fgetc - ファイルから１文字読出し ........................................... 32
fputc - ファイルへ１文字書込み ............................................. 33
fgets - ファイルから１行分の文字列読出し ................................... 34
fputs - ファイルへ 1 行分の文字列書込み ..................................... 35
fread - ファイルからブロック読出し ......................................... 36
fwrite - ファイルへブロック書込み .......................................... 37
fflush - ファイルのフラッシュ .............................................. 38
fseek - ファイル読み書き位置の移動 ......................................... 39
ftell - 現在のファイル読み書き位置を取得 ................................... 40
fsetpos - ファイル読み書き位置の移動 ....................................... 41
fgetpos - 現在のファイル読み書き位置を取得 ................................. 42
feof - ファイルの終わりを検出 .............................................. 43
ferror - エラー情報の取得 .................................................. 44
clearerr - エラー情報のリセット ............................................ 45
remove - ファイルの削除 .................................................... 46
rename - ファイル名やディレクトリ名の変更 .................................. 47
mkdir - ディレクトリの作成 ................................................. 48
rmdir - ディレクトリの削除 ................................................. 49
opendir - ディレクトリのオープン ........................................... 50
closedir - ディレクトリのクローズ .......................................... 50
readdir - ディレクトリ情報の読出し ......................................... 51
fgetattr - ファイルの属性を取得 ............................................ 54
fsetattr - ファイルの属性を変更 ............................................ 54
fgetsize - ファイルサイズの取得 ............................................ 55
fsetsize - ファイルサイズの変更 ............................................ 56
fgetmtime - ファイルまたはディレクトリの作成時刻を取得 ..................... 57
fsetmtime - ファイルまたはディレクトリの作成時刻を変更 ..................... 58
returnname - ファイル名を返す .............................................. 59
getdiskfree - ディスクの残容量を取得(4GB 未満) .............................. 60
getdiskfreex - ディスクの残容量を取得(4GB 以上) ............................. 61
getdisksize - ディスクの容量を取得 ......................................... 62
disk_mount - マウント ...................................................... 63
disk_unmount - アンマウント ................................................ 64
dformat - ディスクのフォーマット ........................................... 65
qformat - ディスクのクイックフォーマット ................................... 66
第４章 エラーコード一覧 ................................................... 67
第５章 ドライバ・インターフェース ......................................... 68
5.1 ディスクドライバ関数 .................................................. 68
5.2 コマンド一覧 .......................................................... 68
5.3 ディスクドライバの例 .................................................. 69
第６章 状態変化通知用コールバック関数 ..................................... 70
6.1 概要 .................................................................. 70
6.2 機能一覧 .............................................................. 70
6.3 コールバック関数の例 .................................................. 71
第７章 PC カードアクセス関数の実装 ......................................... 72
ER PCCard_init(void) ....................................................... 72
5

ER PCCard_check(void) ...................................................... 72
ER PCCard_end(void) ........................................................ 72
void PCCard_open(void) ..................................................... 73
UB PCCard_atr_readb(UW addr) ............................................... 73
void PCCard_atr_writeb(UW addr, UB data) ................................... 73
UB PCCard_io_readb(UW addr) ................................................ 73
void PCCard_io_writeb(UW addr, UB data) .................................... 74
UH PCCard_io_readw(UW addr) ................................................ 74
void PCCard_io_writew(UW addr, UH data) .................................... 74

6

第 1 章 概要
1.1

特長
NORTi File System は、不意な電源断からディスクのデータ破損を極力回避できる機能を盛り込んだ、組み込みシステム専用の DOS 互換ファイルシステムです。
μITRON 仕様リアルタイム OS「NORTi」、および、他の NORTi 用ソフトウェアコン
ポーネントと「NORTi File System」との組み合わせは、組み込みシステム開発に高い効率と自由度とをもたらします。
• DOS 互換 FAT12/16/32 に対応• ロングファイル名(VFAT)をサポート• 階層ディレクトリをサポート• ANSI 準拠のファイル入出力関数、および、POSIX 準拠のディレクトリ操作関数• FAT のキャッシュとキャッシュの自動保存機能により、高速性と安全性を両立• チェックディスク(chkdsk)による FAT とディレクトリエントリの修復機能• CRC でバックアップデータの正当性チェックを行う RAM ディスクドライバ付属• ATA コマンドを利用した CompactFlash 用のドライバが付属• 対応プロセッサ/対応コンパイラ別の動作確認済みライブラリで提供• 全ソースコードが付属• プロジェクトライセンス制で組み込みロイヤリティフリー※ CompactFlash および CF はサンディスク社の商標です。
※ CompactFlash 以外のメディアへの対応は、別途、有償にて承ります。
※ ボード上に実装された Flash メモリをディスクとする機能には非対応です。

1.2

ファイルシステムのバージョン
ミスポからは、次の３種類のファイルシステムがリリースされており、本書では、Ver.1、Ver.2、Ver.4 と呼んで、これらを区別します。
Ver.1：NORTi 付属サンプルファイルシステム
Ver.2：HTTPd for NORTi 付属 File System
Ver.4：NORTi File System Version 4 (本ファイルシステム)「File System Ver.1」は、NORTi Version 4、および、NORTi Simulator にサンプルとして標準で付属しており、次の仕様となっています。
• DOS 互換 FAT12/16 に対応• ロングファイル名(VFAT)非サポート、階層ディレクトリ非サポート• FAT のキャッシュなし• RAM ディスクの CRC チェックや、chkdsk による修復機能無し「File System Ver.2」は、HTTPd for NORTi に標準で付属しており、Ver.1 に対して階層ディレクトリのサポートが追加されています。

7

1.3

ファイルシステム API 一覧
アプリケーション・インターフェース(API)の一覧を以下に示します。

初期化用の API
file_ini
disk_ini
disk_cache

ファイルシステムの初期化
ディスクドライバの初期化
ディスクキャッシュの設定

ANSI 準拠の API
fopen
fclose
fgetc
fputc
fgets
fputs
fread
fwritefflush
fseek
ftell
feof
ferrorclearerr
removerenamefgetpos
fsetpos

ファイルのオープン
ファイルのクローズファイルから１文字読出し
ファイルへ１文字書込み
ファイルから１行分の文字列読出し
ファイルへ１行分の文字列書込み
ファイルからブロック読出し
ファイルへブロック書込み
ファイルのフラッシュ
ファイル読み書き位置の移動
現在のファイル読み書き位置を取得
ファイルの終わりを検出
エラー情報の取得
エラー情報のリセット
ファイルの削除
ファイル名やディレクトリ名の変更
ファイル読み書き位置の取得
ファイル読み書き位置の設定

POSIX 準拠の API
mkdir
rmdir
opendir
closedir
readdir

ディレクトリの作成
ディレクトリの削除
ディレクトリのオープン
ディレクトリのクローズ
ディレクトリ情報の読出し

独自拡張の API
fgetattr
fsetattr
fgetsizefsetsize
fgetmtimefsetmtime
returnname
getdiskfree
getdiskfreex
getdisksize
disk_mountdisk_unmount

ファイルの属性を取得
ファイルの属性を変更
ファイルサイズの取得
ファイルサイズの変更
ファイルまたはディレクトリの作成時刻を取得
ファイルまたはディレクトリの作成時刻を変更
ファイル名を返す
ディスクの残容量を取得(4GB 未満)
ディスクの残容量を取得(4GB 以上)
ディスクの容量を取得
マウント
アンマウント8

dformatqformat

ディスクのフォーマット
ディスクのクイックフォーマット

未実装の ANSI 準拠 API
fprintf
fscanffreopenrewindsetbufsetvbuf

フォーマットデータをファイルに書込む
ファイルからフォーマットデータを読出す
ファイルの再オープン
ファイル読み書き位置を先頭に移動
入出力バッファの設定
モード指定による入出力バッファの設定

標準ライブラリとの関係
各 API は、C の標準ライブラリと名前が衝突しないよう、実際には、頭に my_ という 3 文字が付いています。それを、nofile.h のマクロ定義によって、my_ の付かない関数名に置き換えています。
(例) FILE *my_fopen(const char *, const char *);#define fopen(f,m) my_fopen(f,m)
したがって、nofile.h のインクルードを忘れた場合には、関数名の置き換えが行われず、C の標準ライブラリ関数の方がリンクされます。
nofile.h をインクルードしてある場合でも、未実装の API を記述すると、C の標
準ライブラリ関数がリンクされてしまいます。リンクエラーになりませんが、機能しませんので注意してください。

1.4

ファイル名の指定方法と最大長ディレクトリの情報を含むファイル名をパス名と呼びますが、本ファイルシステ
ムは相対パスに対応しておらず、"d:\aaaa\bbbb\nnnnnnnn.eee"形式の絶対パス(フルパス)での指定だけをサポートしています。
ディレクトリ名の区切りは'\'ですが、Ｃ言語のコーディングでは'\'はエスケー
プ文字なので、実際には'\'を２つ重ねて"d:\\aaaa\\bbbb\\nnnnnnnn.eee"のように記述してください。重ねた'\'はパス名の長さには含まれません。
ファイル名の長さに関して、本ファイルシステムでは次のマクロ名と値を定義しています。いずれも文字列の終わりを示す null 文字('\0')までを含んだ長さなので、実際に指定できる文字数は、これらの値－１となります。
MAX_PATH260
絶対パスの最大長
MAX_FNAME
255
ファイル名の部分の最大長(.拡張子を含まず)
MAX_DIR
247
ディレクトリ名の部分の最大長
MAX_EXT
255
拡張子の部分の最大長
MAX_PATH の制限により、ルートディレクトリには拡張子を含んで 256 文字のファ
イル名のファイルを置けますが、ディレクトリ階層が深くなるに従って、扱える
ファイル名は短くなります。

9

第 2 章 導入
2.1

ファイル構成フォルダ構造本ファイルシステムの標準的なフォルダ構造は、次のとおりです。
NORTi├ NOFILE│ ├ DOC ·············│ ├ DRV ·············│ │ ├ INC
│ │ └ SRC
│ ├ INC ·············│ ├ SRC ·············│ ├ LIB ·············│ │ └ XXX
│ │
├ YYY
│ │
└ YYY
│ └ UTL ·············
│
├ INC
│
└ SRC
└ SMP ·················
└ XXX
├ BBB
└ BBB

ドキュメントデバイスドライバ
ファイルシステム本体のヘッダファイル
ファイルシステム本体のソースファイル
ファイルシステム本体のライブラリ

ユーティリティ
評価ボード用サンプルプログラム

上記の XXX は対応 CPU コア略称、YYY は対応コンパイラ/バージョン略称、 BBB
は評価ボード略称です。実際のフォルダ名は、DOC フォルダのリリースノートをご覧ください。

ドキュメントNOFILE\DOC フォルダには、次のファイルが収められています。
nofile.pdf ··············· NORTi File System Version 4 ユーザーズガイド
NOFILE_xxx_yyy_nnn.txt ･･･ リリースノート
nofile.pdf(本書)は、各処理系(各プロセッサや各コンパイラ)で共通のマニュアルです。NORTi File System Version 4 を利用するための基本的な事項から各 APIの詳細な解説までが記載されています。
NOFILE_xxx_yyy_nnn.txt には、対応 CPU/対応コンパイラに依存するフォルダ/
ファイル構成等の説明、および、更新履歴が記載されています。ファイル名の_xxx_yyy の部分は、対応 CPU/対応コンパイラによって、_nnn の部分はバージョンによって異なります。

10

2.2

ファイルシステム本体

ヘッダファイル
NOFILE\INC フォルダには、次のヘッダファイルが収められています。
nofile.h ······
nofcfg.h ······
nofsys.h ······
nofutbl1.h ·····
nofutbl2.h ·····

ファイルシステムのメインヘッダ
ファイルシステムのコンフィグレーションヘッダ
ファイルシステム内部定義ヘッダ
Shift-JIS/Unicode 変換テーブル 1
Shift-JIS/Unicode 変換テーブル 2

nofile.h を、ファイルシステムの API を使用する全てのソースファイルでインクルードしてください。nofile.h には、各 API の関数宣言と、その関数コールに必要な構造体や定数等の定義が記述されています。
nofcfg.h には、ファイルシステムが使う各種リソースの情報が定義されています。
ユーザー作成のソースファイルの１つ(通常は、カーネルや TCP/IP スタックのコ
ンフィグレーションを記述してあるソースファイル)でインクルードしてください。nofcfg.h を２ヶ所以上でインクルードすると、二重定義のコンパイルエラーとなります。
nofsys.h、nofutbl1.h、nofutbl2.h は、ファイルシステムの内部定義であり、通常、ユーザー作成のソースファイルからインクルードする必要はありません。

ソースファイル
NOFILE\SRC フォルダには、ファイルシステム本体のソースファイルが収められています。ファイルシステム本体はライブラリ化されていますので、通常は、これらのソースファイルをコンパイルしてユーザープログラムにリンクする必要はありません。
nofile.c ······
nofsj2uc.c ····
nofas2uc.c ····
noftime.c ·····

ファイルシステム本体
S-JIS/UNICODE 変換処理
ASCII/UNICODE 変換処理
現在日時取得ダミー関数

noftime.c については、「2.7 現在日時の取得関数の実装」の節も参照してください。
使用されるコンパイラに対応したファイルシステムのライブラリが株式会社ミスポから提供されていない場合には、これらのソースファイルをコンパイルしてユーザープログラムにリンクしてください。(ただし、株式会社ミスポで動作を確認していないコンパイラでの使用は動作保証対象外となります。)
なお、nofile.c は、各 NOF_xxxxx マクロによってコンパイルする部分が選択されるようになっており、機能別にコンパイルを繰り返してライブラリへ結合してあります。こうすることによって、使用しない機能がユーザープログラムへリンクされるのを防いでいます。コンパイルオプションで ALL マクロを定義することで、nofile.c のファイル全体、つまり、全機能をまとめてコンパイルすることもできます。その他、適切なプロセッサコアやエンディアンを指定するコンパイル
オプションを付けてください。

11

ライブラリ本ファイルシステムはライブラリとして提供されるので、実際に使用する機能のみがユーザープログラムにリンクされ、コードやデータのサイズを自動的に節約することができます。
NOFILE\LIB フォルダには、対応 CPU コア略称、その下に対応コンパイラ略称のサ
ブフォルダがあり、そこに、ファイルシステム本体のライブラリと、それを生成するためのメイクファイル等が収められています。複数のバージョンのコンパイ
ラに対応している場合には、対応バージョン別にサブフォルダが用意されています。
同じ CPU シリーズでも、複数の CPU コアに対応している場合には、コア別の異なるライブラリ名またはフォルダ名に。ビッグとリトルの両エンディアンに対応している場合は、エンディアン別の異なる次のようなライブラリ名になっています。
f4n????b.lib：ビッグエンディアン用ライブラリ
f4n????l.lib：リトルエンディアン用ライブラリ
ライブラリ名の????の部分は、対応 CPU コアやモード等によって異なります。コンパイラによっては、.lib 以外の拡張子の場合もあります。

12

2.3

デバイスドライバ
デバイスドライバとしては、ATA コマンドを使用する ATA ドライバ、それを
TrueIDE モード専用としたドライバと、RAM ディスクドライバが付属します。
ATA ドライバは、ハードウェアに依存する PC カードアクセス関数を用意することにより、PC カードインターフェースでメディアにアクセスすることができます。
CompactFlash, IDE-USB ブリッジ、HDD 等で使える TrueIDE 用ドライバは、ヘッダのカスタマイズのみで、アクセス関数を実装する必要はありません。
RAM ディスクドライバは、通常の RAM をディスク代わりに使えるようにするドライバです。メモリ空間を使用するだけなのでハードウェアには依存しません。
NOFILE\DRV\INC\
nofata.h ····· ATA ドライバのヘッダ
nofpccd.h ····· PC カードアクセス関数のヘッダ
trueide.h ····· TrueIDE 用ドライバのヘッダ
NOFILE\DRV\SRC\
nofata.c ····· ATA ドライバのソース
nofgtfrm.c ···· ディスク情報取得関数のソース
trueide.c ····· TrueIDE 用ドライバのソース
nofram.c ····· RAM ディスクドライバのソース

ATA ドライバ
nofata.h と nofata.c は、ATA コマンドを使用して PC カードにアクセスする「ATAドライバ」です。I/O アドレスやレジスタアクセス方法等、使用するハードウェ
アに合わせて PC カードアクセス関数を実装してください。そのポイントについて
は第 7 章で説明します。
nofgtfrm.c には、ATA ドライバ nofata.c からコールされるディスク情報取得関数が定義されています。この nofgtfrm.c は、カスタマイズ不要です。

13

記録メディアへのアクセス記録メディアへのアクセス方法は、おおむね次の 3 種類に分類されます。

(1) PC カードインターフェース(PCMCIA コントローラ経由)
本格的なコントローラを搭載していて、アドレス空間のマッピングまで行わなけ
ればならないものです。設定が面倒ですが、活線挿抜に必要なカード電源の制御まで対応している場合があります。
(2) PC カードインターフェース(簡易型)
ハード的に I/O 空間やアトリビュート空間を割り当てていて、ハード的に決まっている空間をアクセスするだけで良い簡易的な PC カードインターフェースを搭載しているものを指します。ハードウェアの設計者により独自に簡易化されているため、活線挿抜に必要なカード電源の制御までは行えない場合があります。
(3) TrueIDE モード
最も簡単なインターフェースです。(2)よりさらに単純化されていますが、規格上抜き差しを前提としたものではないため、通常は挿入検知はダミー関数として対応しますが、ハードによっては独自に検知方法を追加されている場合があります。

RAM ディスクドライバ
nofram.c は、普通の RAM をディスクに見立てる RAM ディスクドライバです。バッ
テリーバックアップされた SRAM に RAM ディスク領域を割り当てることで、電源断でもディスクの内容が保持されます。nofram.c は、カスタマイズ不要です。
この RAM ディスクドライバでは、
512 バイト当たり 4 バイトの CRC 領域が RAM ディ
スク領域から割当てられます。例えば、1M バイトの RAM ディスクでは、そのうちの 8K バイトが CRC 領域となります。
RAM ディスクドライバの初期化では RAM ディスク領域のクリアを行っていません
が、配列変数として定義した領域を RAM ディスク領域とすると、C のスタートアッ
プルーチンでゼロクリアされてしまいます。バックアップが必要な場合には、プ
ログラムで使用していない RAM 領域を絶対アドレスで指定してください。
キャッシュを備えたプロセッサで、電源断でも保持されるようにしたい場合は、キャッシュスルー(非キャッシュ)領域のアドレスとしてください。
RAM ディスクドライバの初期化では、全セクタの CRC チェックを行い、異常が検出された場合には、エラーを返します。エラーの場合でも自動的に RAM ディスク
領域のクリアは行われませんので、dformat()によって明示的に RAM ディスクのフォーマットを行ってください。
RAM ディスクは簡単に複数ドライブ化できるようにしてあり、一方をワーク用、もう一方をバッテリバックアップされたドライブのように使い分けることが可能
です。

14

2.4

ユーティリティNOFILE\UTL フォルダには、ファイルシステムに関連したアプリケーションのソー
スファイルが収められています。
NOFILE\UTL\INC\nofftpd.h ·····
nofchkd.h ·····NOFILE\UTL\SRC\
nofftpd.c ·····
nofchkd.c ·····
fspsubr.c ·····

マルチセッション版 FTP サーバのヘッダ
チェックディスク機能のヘッダ
マルチセッション版 FTP サーバのソース
チェックディスク機能のソース
ファイルシステムの API の使用例

マルチセッション版 FTP サーバ
nofftpd.h と nofftpd.c は、本ファイルシステムの機能に合わせ、階層ディレク
トリやロングファイル名に対応した FTP サーバです。また、同時に複数の FTP セッ
ションを実行でき、GUI ベースの FTP クライアントや、複数の FTP クライアント
からの同時接続にも対応しています。NORTi にサンプルとして標準で付属の FTP
サーバの代わりに使用してください。

チェックディスク機能
ディスクへデータを書込んでいるタイミングでシステムがダウンすると、FAT の情報とディレクトリエントリの情報の整合がとれなくなる場合があります。この
チェックと修復を行うのがチェックディスク機能です。
具体的には、ディレクトリエントリのサイズ情報を超えて FAT チェーンが続く場
合は、それを未使用として切り離した上でデータを FOUND***ファイルへ移動します(***は 3 桁の数字)。
ディレクトリエントリのサイズ情報よりも FAT チェーンが短かった場合は、ディレクトリエントリの方を FAT チェーンに合わせて書き換え、データを FOUND***
ファイルへ移動します。いずれも元のファイルは削除となるので、不整合は修復されますが、ファイルを復元できる訳ではないことに注意してください。
さらに FAT チェーンの重複のチェックも行っていて、重複していた場合は、先にチェックした方を正常なファイルとし、後からチェックした方を FOUND***ファイ
ルにします。
なお、CompactFlash 等の記録メディアを使用していて、その内部で書き換えが行われている最中の電源断でメディア自体が破損した場合は、チェックディスクによる不整合の修復を行えません。
RAM ディスクでは、電源断からバックアップへの移行にハードウェア上の問題がない限り、チェックディスクによる不整合の修復は有効です。

15

2.5

サンプルプログラム
NORTi の SMP フォルダに収められているサンプルプログラムのソースは、マクロ定義やリンクするファイルを変更するだけでファイルシステムのサンプルとしても動作するように作られています。そのため、File System の SMP フォルダには、
NORTi の SMP フォルダに対して追加となるプロジェクトファイルだけが格納されています。そのまま NORTi の同名フォルダへ上書きコピーしてください。

CompactFlash 使用の有無(CF マクロ)通常のサンプルプログラムは、RAM 上にドライブ"A:"として RAM ディスクを作成します。CompactFlash ソケットを備えた評価ボード用のサンプルプログラムでは、
コンパイル時に CF マクロを 1 に定義することにより、ドライブ"B:"としてCompactFlash へもアクセスできるようになります。この場合、CompactFlash がデフォルトのドライブとなりますので、RAM ディスクへは、ドライブ名 "A:"を明示してアクセスしてください。
この CF マクロと下記の NOFILE_VER マクロは、サンプルプログラムのメインの
ソース net???.c とコンフィグレーション用の nonecfg.c に対して定義してください。メインのソースファイル名の???の部分は、CPU によって異なります。

ファイルシステムのバージョン(NOFILE_VER マクロ)「1.2 ファイルシステムのバージョン」に記載のとおり、3 種類のファイルシス
テムがリリースされており、サンプルプログラムでは、次の NOFILE_VER マクロによって各ファイルシステムの非互換の部分に対応できるようになっています。
NOFILE_VER = 4：本ファイルシステム NORTi File System Version 4 に対応
NOFILE_VER = 3：未使用
NOFILE_VER = 2：HTTPd for NORTi 付属の File System Version 2 に対応
NOFILE_VER = 1：NORTi 付属サンプルの File System Version 1 に対応
あくまでもサンプルプログラム側の対応であり、ファイルシステム本体の動作を別バージョンに合わせたりするようなものではありません。

FTP サーバが使用するリソース
サンプルプログラムでは、本ファイルシステムに付属するマルチセッション版
FTP サーバを使用しています。セッション数は NFTP マクロで指定でき、未指定の場合のデフォルトは 1 です。
セッション数を増加させる場合は、セッション毎にタスクが 1 個、TCP 通信端点が 1 個使用されますで、カーネルや TCP/IP スタックのコンフィグレーション値が不足しないよう注意してください。

16

2.6

コンフィグレーション

コンフィグレーションヘッダのインクルード
ファイルシステム本体のコンフィグレーションを行うには、ファイルシステムが使うリソースの情報が定義されている nofcfg.h を、ユーザープログラムの１つでインクルードしてください。このインクルードの前に、コンフィグレーション用のマクロを定義することで、ユーザーのシステムに合わせたファイルシステムの構築を行うことができます。
サンプルプログラムでは nonecfg.c がその役目を担っています。その中でマクロ定義をしてコンフィグレーションの変更を行ってください。
この方法は File System Ver.4 でのみ設けられており、File System Ver.1 や Ver.2
から移行の際には、nofcfg.h のインクルードの追加が必要であることに注意してください。

ファイルシステムが使うリソース
本ファイルシステムでは、OS のリソース(オブジェクト)として、タスクを１個、メールボックスを１個、周期ハンドラを１個使用しています。
nofcfg.h には、ファイルシステムで使用するオブジェクトの個数として、以下のマクロが定義されていますので、システム全体のオブジェクト個数の集計を行う
場合に利用してください。
#define LFS_NTSK#define LFS_NSEM#define LFS_NFLG#define LFS_NMBX#define LFS_NMBF#define LFS_NPOR#define LFS_NMPL#define LFS_NMPF#define LFS_NDTQ#define LFS_NMTX#define LFS_NISR#define LFS_NCYC#define LFS_NALM

1
0
0
1
0
0
0
0
0
0
0
1
0

タスク個数
セマフォ個数
イベントフラグ個数
メールボックス個数
メッセージバッファ個数
ランデブ用ポート個数
可変長メモリプール個数
固定長メモリプール個数
データーキュー個数
ミューテックス個数
割り込みサービスルーチン個数
周期ハンドラ個数
アラームハンドラ個数

ファイルシステムのタスク優先度(LFS_TSKPRI マクロ)
ファイルシステム本体は、ユーザープログラムとは独立したタスクとして実装されています。このファイルシステムのタスク優先度は、LFS_TSKPRI マクロを定義することによって指定できます。LFS_TSKPRI を定義しない場合、あるいは、
LFS_TSKPRI が 0 の場合には、最初にファイルシステムの API を発行したタスクの優先度を引き継ぎます。
ファイルシステムのタスク優先度を高く(値では小さく)した場合、ファイル入出力動作は高速となりますが、それより優先度の低いタスクの実行が待たされます。

17

ディスク書込み遅延時間(LFS_WRTDLY マクロ)
本ファイルシステムでは、高速化のために、ディスクのセクタの割当てを管理している FAT(File Allocation Table)情報を RAM 上にキャッシュすることができます。また、オープンしたファイル毎に入出力バッファを持っていて、fputc()やfwrite()でこのバッファが一杯となるか、fclose()や fflush()が発行されるまではディスクへの書込みを行いません。
このキャッシュや入出力バッファの内容をディスクへ反映するタイミングを、
LFS_WRTDLY マクロを定義することによって調整できます。バッファの大きさには無関係に動作します。具体的には、LFS_WRTDLY マクロで指定された時間だけファ
イルシステムの API が発行されなかった場合に、キャッシュされている FAT の内容や、全ファイルの未書込みデータがディスクへ書込まれ、ディレクトリのファ
イルサイズ情報も更新されます。
LFS_WRTDLY に小さな値を定義すると、キャッシュや入出力バッファとディスクの内容が直ぐに一致するため、不意なシステムダウンでのファイル破損の可能性が小さくなりますが、システムの負荷が増大します。
LFS_WRTDLY の設定値の単位はシステムクロックの割り込み回数で、1 以上の値を定義してください(ファイルシステムのタスク優先度が最低の場合にのみ、0 も設定可能)。LFS_WRTDLY を定義しない場合は、20/MSEC となります。
LFS_WRTDLY に TMO_FEVR を指定すると、遅延時間を待ってのディスク書込みは行
われません。この場合、fclose()あるいは fflush()を行う前のデータは、不意なシステムダウンで失われます。

Shift-JIS/Unicode 変換テーブルの削減(LFS_UNICODE マクロ)
ロングファイル名をサポートする VFAT では、ファイル名が全て Unicode で表現
されています。一方、C の文字列は、半角文字が ASCII で、全角文字が Shift-JIS
で表現されるため文字コードの変換が必要です。
日本語のファイル名をサポートする必要が無い場合、LFS_UNICODE マクロを 0 に定義することで、ファイルシステムのライブラリに含まれる Shift-JIS/Unicode
変換テーブルが削除され、
コードサイズを、約 31KB だけ節約することができます。
LFS_UNICODE を定義しない場合、あるいは、LFS_UNICODE が 1 の場合には、ファイル名の Shift-JIS/Unicode 変換が行われます。

コンフィグレーションの例#define LFS_TSKPRI#define LFS_WRTDLY#define LFS_UNICODE#include "nofcfg.h"

660/MSEC0/* ファイルシステムタスク優先度 *//* 書込み遅延時間 *//* 日本語ファイル名を使用しない *//* コンフィグレーションヘッダ */その他のコンフィグレーション
ファイルシステムのタスク ID、メールボックス ID、周期ハンドラ ID は、空いている大きな ID 番号から自動割当てされます。各 ID 番号を自動割当てでなく固定したい場合には、ファイルシステム初期化関数 file_ini()とディスクドライバ初期化関数 disk_ini()で指定できます。

18

2.7

現在日時の取得関数の実装
NOFILE\SRC フ ォ ル ダ に あ る noftime.c に は 、 現 在 の 日 時 を 取 得 す る 関 数
fs_get_tm がダミー定義されています。ファイルの作成や更新の際に日付と時刻の情報(タイムスタンプ)を付加する必要がある場合には、fs_get_tm 関数を、ユー
ザープログラム側に実装してください(ユーザープログラムで fs_get_tm 関数を定義することにより、ファイルシステムのライブラリに含まれるダミーの
fs_get_tm 関数はリンクされなくなります)。
ボード上に、
RTC(時計 IC)が搭載されている場合には、そのデータを読出して ANSI
互換の tm 構造体に年月日時分秒の情報を返すように実装してください。
int fs_get_tm(struct tm *ts){
RTC から年月日時分秒をリード;
if (異常)return 0; /* エラー */ts->tm_sec = 秒(0～59);
ts->tm_min = 分(0～59);
ts->tm_hour = 時(0～23);
ts->tm_mday = 日(1～31);
ts->tm_mon = 月(0～11, 0 が 1 月);
ts->tm_year = 年(1900 年からの年数);
ts->tm_wday = 0;
ts->tm_yday = 0;
ts->tm_isdst = 0;
return 1; /* 正常 */}tm 構造体の tm_wday(曜日)、tm_yday(1 月 1 日からの日数)、tm_isdst(夏時間フラグ)は、設定する必要がありません。
本関数がユーザープログラムに定義されない場合、ダミーの fs_get_tm 関数がコールされ、ファイルのタイムスタンプは、常に“1980 年 1 月 1 日 0 時 0 分 0 秒”となります。本関数がエラーを返した場合にも、この日時となります。ユーザー
プログラムへエラーは通知されません。

19

2.8

File System Ver.1 との互換性

File System Ver.1 の API
NORTi Version 4、および、NORTi Simulator 付属サンプルの「File System Ver.1」
では、以下の API のみが実装されています。
file_ini, disk_ini, fopen, fclose, fseek, fgetc, fputc,
fgets, fputs, fread, fwrite, ftell, feof, remove, rename, dformat
File System Ver.4 の API は、File System Ver.1 に対して、file_ini と disk_ini
を除き完全な上位互換性を保っています。

File System Ver.1 のファイル構成
File System Ver.1 は、次のファイルのみから構成されます。
NETSMP\INC\nonfile.h ····· ファイルシステムのヘッダファイル
NETSMP\SRC\
nonfile.c ····· ファイルシステムのソースファイル
nonramd.c ····· RAM ディスクドライバのソースファイル

File System Ver.1 からの移行手順
ヘッダファイルの変更
インクルードするヘッダファイルを下記のように変更してください。
#include “nonfile.h” → #include “nofile.h"

プロジェクトファイルの変更
プロジェクトファイルから nonfile.c を削除して、ビルドの対象外にしてください。ライブラリ指定に本ファイルシステムのライブラリを追加してください。

RAM ディスクドライバの変更
プロジェクトファイルから nonramd.c を削除して、ビルドの対象外にしてください。プロジェクトに nofram.c を追加して、ビルドの対象にしてください。
※nonramd.c をそのまま使うことも可能ですが、初期化時に CRC チェックを行っていないので、バックアップのチェック機能がありません。disk_ini でドライバを初期化する場合は、ゼロクリア済み領域を、RAM ディスク領域として渡してください。

API の差異を修正
disk_ini()の引数の個数が増えています。「第 3 章 ファイルシステム API 解説」
を参照して、呼び出し箇所を修正してください。
file_ini()と disk_ini()をコールしていないソースファイルについては、API に互換性がありますので、ファイルシステム内部のデータを直接参照していない限
り、"#include nonfile.h"のままとしておいても構いませんが、なるべくインク20

ルードするヘッダファイル名は修正してください。
NETSMP\SRC フォルダの FTP クライアントサンプル nonftpc.c や、TFTP サーバサン
プル nontftp.c は、NOFILE_VER=4 と定義してコンパイルすると、nofile.h をイン
クルードするようになっています。

非互換 API の修正
API のうち、以下の使用方法については互換性がありませんので、代替となる APIに修正してください。
API を使用する場面

Ver.1 の API

Ver.4 の API

ディレクトリのオープン

fopen(".", "r")opendir()

ディレクトリ情報の読出し

fread()

readdir()

ディレクトリのクローズ

fclose()closedir()

コンフィグレーション項目の設定「2.6 コンフィグレーション」を参照し、コンフィグレーション用のマクロ定義と、nofcfg.h のインクルードを追加してください。サンプルプログラムでは
nonecfg.c というソースでコンフィグレーションの設定を行っています。
このファイルは NOFILE_VER=4 の場合にも対応しています。

インクルードパスの追加
プロジェクトのインクルードパスの設定に下記のディレクトリを追加してくだ
さい。
C:\NORTi\NOFILE\INC
C:\NORTi\NOFILE\DRV\INC

21

2.9

File System Ver.2 との互換性

File System Ver.2 の API
HTTPd for NORTi に付属の「File System Ver.2」では、前ページの Ver.1 の APIに加え、以下の API が追加されています。
disk_ini2, disk_mount, disk_unmount, makedir, removedir, dirlist,
getdiskfree, alloc_sbuf
上記のうち、disk_mount と disk_unmount 以外の API は、本ファイルシステムと互換性がありません。

File System Ver.2 のファイル構成
File System Ver.2 は、次のファイルから構成されます。
NONFILE\DOC
nonfile.pdf ···NONFILE\INC\nonfile.h ·····
time.h ········NONFILE\SRC\
nonfile.c ·····
get_tm.c ······
nonramd.c ·····

ユーザーズガイド
ファイルシステムのヘッダファイル
時刻構造体の定義
ファイルシステムのソースファイル
現在日時取得ダミー関数
RAM ディスクドライバのソースファイル

File System Ver.2 からの移行手順
HTTPd for NORTi で使用している場合に、ファイルシステムを Ver.4 に移行する
方法については別項目で説明します。
基本的な移行手順と注意点は、File System Ver.1 から移行の場合と同じです。
disk_ini()については、Ver.2 と Ver.4 は互換ですので修正は不要です。
下記の互換性のない API を使用している箇所は、修正をお願いします。
API を使用する場面

Ver.2 の API

Ver.4 の API

ディスクドライバの初期化

disk_ini2

disk_ini()

ディレクトリの生成

makedir()

mkdir()

ディレクトリの削除

removedir()rmdir()

ディレクトリのオープン

fopen(".", "r")opendir()

ディレクトリ情報の読出し

fread()

readdir()

ディレクトリのクローズ

fclose()closedir()getdiskfree()によりディスクの空き容量を取得している場合は、引数と戻値が異なりますので修正してください。
alloc_sbuf()に相当する機能はありません。

22

File System Ver.2 からの移行手順(HTTPD)
HTTPd for NORTi は、ユーザープログラムと共にコンパイルされることを前提にしています。そのコンパイルの際に、NOFILE_VER=4 を定義することにより、Ver.4
対応の API が使用されます。

・コンフィグレーション項目の設定「2.6 コンフィグレーション」を参照し、コンフィグレーション用のマクロ定
義と、nofcfg.h のインクルードを追加してください。
HTTPd に付属するサンプルプログラムでは httpcfg.c というソースでコンフィ
グレーションの設定を行っています。
このファイルは NOFILE_VER=4 の場合にも対応しています。
・インクルードパスの変更
プロジェクトに設定されているインクルードパスのうち、ファイルシステムに関連するものを下記のように変更・追加してください。
C:\NORTi\NONFILE\INC → C:\NORTi\NOFILE\INC
C:\NORTi\NOFILE\DRV\INC

23

2.10

Windows FAT ファイルシステムとの互換性
ファイル名として使用可能な文字や、長いファイル名(LFN)、短いファイル名(SFN)についての決まりは Microsoft Windows に従います。
Windows の FAT 仕様については、正確には Windows 98 の仕様と Windows NT 系の仕様(Windows XP を含む)がありますが、本ファイルシステムは Windows 98 仕様
で実装されています。作成されたファイルは、WindowsXP 等の NT 系 OS でも問題なくアクセスすることができます。
SFN ではファイル名に小文字が含まれていることを禁止しているため、それらの文字が含まれる場合は、文字数としては SFN の 8.3 形式に収まっていても、SFN上では大文字に変換し、LFN を生成します。(LFN に小文字のファイル名が入ります) また、LFN から SFN を作成するときに、名前が衝突しないように、ファイル名の一部を～(チルダ)と複数桁の数字に置き換えます。
NT 系 Windows では、小文字が含まれていても、すべてが小文字の SFN の場合は、
LFN のディレクトリエントリを生成しないように修正が加えられています。 1
NT 系 Windows にも名前の衝突防止を考慮した SFN の生成が同様に実装されていま
すが、こちらはアルゴリズムが改訂されていて Windows 98 と同じファイル名にはなりません。またそのアルゴリズムについても Windows NT 系のものは公開されていません。
これらの事情から、本ファイルシステムでは、正式に公開されている Windows 98
仕様で実装しています。

1

NT 系ではシステムファイルに小文字だけのファイルが多く、それによるディレクトリエントリの浪費を嫌っての変更と言われています。

24

第３章

ファイルシステム API 解説

file_ini - ファイルシステムの初期化
形 式

int file_ini(T_FILE *f, int nfile, ID tskid, ID mbxid);

引 数

f
nfile
tskid
mbxid

解 説

ファイルシステムの初期化を行います。全てのファイルシステム API の発行に先だって、1 回だけ file_ini()をタスクからコールしてください。

T_FILE 構造体配列へのポインタ
同時にオープンするファイル数
ファイルシステムで使用するタスクの ID
ファイルシステムで使用するメールボックスの ID

f には T_FILE 構造体配列へのポインタを指定してください。nfile には同時にオープンできるファイル数を指定してください。つまり T_FILE 構造体配列の要素数と同じ値を指定してください。
ファイルシステムの初期化ではタスクを 1 個生成します。タスク ID を明示したい場合には、その ID 番号を tskid に指定してください。tskid が 0 の場合は、自動的に ID が割り当てられます。
ファイルシステムの初期化ではメールボックスも 1 個生成します。メールボック
ス ID を明示したい場合には、その ID 番号を mbxid に指定してください。
mbxid が0 の場合は、自動的に ID が割り当てられます
戻 値

正常終了の場合は E_OK を返します。
エラーの場合は NORTi のシステムコールのエラーコードを返します。主なエラー
は、タスク生成やメールボックス生成に伴うメモリ不足や ID 割り当ての失敗です。

例

disk_cache()の例を参照してください。

補 足File System Ver.1 と Ver.2 では、file_ini()の第４引数がメールボックス ID ではなくセマフォ ID です。
本ファイルシステムからファイル入出力を独立したタスクで行うようになってセマフォによる排他制御が不要となり、その代わりにタス
ク間通信用のメールボックスが使用されるようになりました。第４引数の意味は異なりますが、本ファイルシステムへ移行のためには、0 のまま修正不要です。

25

disk_ini - ディスクドライバの初期化
形 式

int disk_ini(T_DISK *d, const char *drv, DISK_FP func, UW addr, UW param,
DISK_CALLBACK callback, ID cycid, int opt);

引 数

dT_DISK 構造体へのポインタ
drv
ドライブ名("A:", "B:", …)
func
ドライバ関数へのポインタ
addr
ドライバ依存のパラメータ(アドレス等)
param
ドライバ依存のパラメータ(サイズ等)
callback 状態変化通知用コールバック関数へのポインタ
cycid
周期ハンドラ ID
opt
オプション指定

解 説

ディスクにアクセスするためのデバイスドライバを初期化します。複数のドライブがある場合には、引数を変えて disk_ini()をドライブ数分だけコールしてくだ
さい。
ドライバの作業領域である T_DISK 構造体をユーザープログラム定義し、d に、そのポインタを指定してください。複数のドライブがある場合、それぞれ異なる
T_DISK 構造体を指定してください。
drv にはドライブレター文字列を指定してください。
"A:", "B:", …のように"A:"から開始して連続している必要はありません。任意のアルファベットが使用できます。大文字と小文字の区別はありません。
func にはドライバとする関数へのポインタを指定してください。付属の RAM ディ
スクドライバ(nofram.c)の場合は ramdisk、付属の CompactFlash 用の ATA ドライバ(nofata.c)の場合は flash_ATA となります。
addr と param はドライバにより指定方法が異なります。付属の RAM ディスクドラ
イバでは、RAM ディスクとする領域の先頭アドレスとサイズを指定してください。
付属の ATA ドライバでは未使用なので、0, 0 を指定してください。addr と paramの内容はファイルシステム本体では関知していないので、ドライバとの取り決め
で自由に使用できます。
ディスクのアクセスや挿抜などによる状態変化で、callback に指定したユーザー
定義の関数が、ドライバの周期ハンドラからコールされます。このコールバック
関数は「第７章 状態変化通知用コールバック関数」を参照して作成してください。
この関数でアクセスランプを点滅させたり、ディスクが抜かれた場合の警告を出したりすることができます。コールバック関数を使用しない場合は NULL を指定してください。付属の RAM ディスクドライバでは未使用なので、NULL となります。
コールバック関数を用いる場合は、ドライバが周期ハンドラを生成します。周期ハンドラ ID を明示したい場合には、その ID 番号を cycid に指定してください。
cycid が 0 の場合は、自動的に ID が割り当てられます。複数の CF/HDD ドライブが存在し、disk_ini を複数回コールする場合は、明示的に周期ハンドラ ID を指定して各ドライブを初期化してください。本バージョンでは、1 個の周期ハンド
ラで複数ドライブに対応する機能には対応しておりません。
付属の RAM ディスクドライバでは未使用なので、0 を指定してください。

26

opt には、下記の指定が可能です。
Bit1: disk_mount 時の全セクタチェック指定
0 を指定した場合、disk_mount 時に全セクタを読み出せるかのチェックを行います。1 を指定した場合、このチェックを省略します。
全セクタの読み出しには時間がかかりますので、大容量メディアを使用される場
合は、1 を指定してチェックを省略することをお勧めします。
Bit0: 取り外し可能メディア指定
ディスクが取り外し可能ならば 1 を、取り外し不可能なら 0 を指定してください。
0 を指定したときは、disk_ini 呼び出し時に disk_mount まで自動的におこないます。1 を指定したときは、挿入を検知して、disk_mount をコールしていただく
必要があります。

戻 値

正常終了の場合は E_OK を返します。
エラーの場合はドライバの戻値を返します。

例

disk_cache()の例を参照してください。

補 足File System Ver.1 では、disk_ini()の第６引数以降 callback, cycid, opt がありません。File System Ver.1 は RAM ディスクにのみ対応していますので、本ファイルシステムへ移行のためには、第６引数以降には、NULL, 0, 0 を指定してください。
File System Ver.2 では第７引数(cycid)の用途が異なりますが、未使用(0)でしたので、本ファイルシステムへ移行のためには、0 のまま修正不要です。

27

disk_cache - ディスクキャッシュの設定
形 式

int disk_cache(T_DISK *d, void *buf, int ncache);

引 数

dT_DISK 構造体へのポインタ
buf
キャッシュバッファへのポインタ
ncache キャッシュの個数

解 説

ファイルシステムを高速化するためには、頻繁にアクセスされるディスクの FAT
領域を RAM 上にキャッシュすることが望ましいです。そのためのバッファを割り当て、キャッシュの使用を有効にます。
d には、先に disk_ini の第１引数 d として指定した T_DISK 構造体へのポインタを指定してください。
ユーザープログラムにキャッシュバッファ領域を T_CACHE 構造体配列として定義し、その領域へのポインタを、buf に指定してください。
ncache には T_CACHE 構造体配列の要素数を指定してください。最大個数は 255 で、255 を超える数を指定した場合、255 個に強制的に補正されます。推奨値は 5 から10 です。
T_CACHE 構造体１つのサイズは、520 バイトです。T_CACHE 型を使用せずに任意の領域をキャッシュバッファとして buf に指定することも可能です。その場合、キャッシュバッファはロングワード境界のアドレスで開始し、520 バイトの整数
倍のサイズとしてください。ncache にはキャッシュバッファ領域の総サイズを520 で割った数を指定してください。
複数のドライブがある場合には、それぞれ異なる領域をキャッシュバッファとして指定してください。キャッシュバッファの領域や個数を途中で変更することはできません。なお、RAM ディスクの場合は、ディスクキャッシュの効果がありませんので、disk_cache()の実行は行わない方が良いです。

戻 値

正常終了の場合は E_OK を返します。エラー(キャッシュバッファサイズ不足)の場
合は-1 を返します。

28

例

ファイルシステムと RAM ディスクドライバと CompactFlash 用の ATA ドライバを初期化し、CompactFlash へだけディスクキャッシュを割り当てます。
#define NFILE
6/* 同時オープンするファイル数 */#define NCACHE
5/* ディスクキャッシュ個数 */#define RAMDISK
0xAC200000/* RAM ディスク領域のアドレス */#define RAMDISKSZ 0x100000/* RAM ディスク領域のサイズ */T_FILE file[NFILE];
T_DISK disk[2];
T_CACHE cache[NCACHE];
void test(void){
int r;/* ファイルシステム初期化 */r = file_ini(file, NFILE, 0, 0);
if (r != E_OK) {/* error */}/* RAM ディスクドライバ初期化 */r = disk_ini(&disk[0], "A:", ramdisk, RAMDISK, RAMDISKSZ, NULL, 0, 0);
if (r != E_OK) {/* error */}/* CompactFlash 用 ATA ドライバ初期化 */r = disk_ini(&disk[1], "B:", flash_ATA, 0, 0, NULL, 0, 0);
if (r != E_OK) {/* error */}/* CompactFlash にディスクキャッシュを割り当て */r = disk_cache(&disk[1], cache, NCACHE);
if (r != E_OK) {/* error */}}例では２つの T_DISK 構造体を配列として定義していますが、配列として連続している必要はなく、RAM ディスクと CompactFlash とで別々の名前の構造体を定義することでも構いません。
RAM ディスク領域が、プログラムで使用している領域と重ならないように注意してください。キャッシュを内蔵したプロセッサで RAM ディスク領域をバックアッ
プする場合には、キャッシュスルー(非キャッシュ)領域のアドレスを指定してく
ださい。

29

fopen - ファイルのオープン
形 式

FILE *fopen(const char *path, const char *mode);

引 数

path
mode

解 説

path には、"d:\aaaa\bbbb\nnnnnnnn.eee"形式のドライブ名やルートからのディレクトリ名を含むフルパスでファイル名を指定してください。path の最大長はMAX_PATH で規定されます。ディレクトリ名の区切りは'\'ですが、Ｃ言語のコーデ ィ ン グ で は '\' は エ ス ケ ー プ 文 字 な の で 、 実 際 に は '\' を ２ つ 重 ね て"d:\\aaaa\\bbbb\\nnnnnnnn.eee"のように記述してください。

パス名(フルパス指定)
ファイルアクセスモード"d:"はドライブ名で、"A:"、"B:"、"C:"等を指定してください。ドライブ名("d:"または"d:\")を省略した場合は、最初に disk_ini()で初期化されたディスクが選択されます。path の長さは、省略したドライブ名を補った形式で計算されます。
本ファイルシステムはカレントディレクトリの管理を行っていないので、相対パスによる指定はできません。
mode には、アクセスの種類を文字列で指定してください。
"r"

読出しモードでオープンします。指定されたファイルが存在しない場合はエラーになります。
"w" 書込みモードで空のファイルを開きます。指定されたファイルが既に存在する場合は、そのファイルの内容を破棄します。
"a" 追加書込み用にオープンします。指定されたファイルの末尾から書込みます。指定されたファイルが存在しない場合は、新規に作成します。
"r+" 読出しと書込みの両方のモードで開きます。指定されたファイルが存在しない場合はエラーになります。
"w+" 読出しと書込みの両方のモードで空のファイルを開きます。指定されたファイルが既に存在する場合は、そのファイルの内容を破棄します。
"a+" 読出しと追加の両方のモードで開きます。指定されたファイルが存在しない場合は、新規に作成します。
上記のアクセスの種類に加え、一般的なファイルシステムは、変換モードとして"b"(バイナリモード)か"t"(テキストモード)かを指定できますが、本ファイルシ
ステムはテキストモードをサポートしていません。すなわち、ファイル入出力時に CL+LF⇔LF 変換は行われません。"b"を省略した場合には、バイナリモードと見なされます。"r+b"と"rb+"のように、"b"は先頭以外のどちらへでも記述できます。
"rt"や"wt"のようにテキストモードでオープンしようとするとエラーとなります。
戻 値

オープンしたファイルを管理する構造体へのポインタ(ファイルポインタ)を返します。以降のファイル操作では、このポインタでファイルを指定してください。
エラーの場合は NULL が返ります。

30

fclose - ファイルのクローズ形 式

int fclose(FILE *fp);

引 数

fp

解 説

fp で指定されたファイルをクローズします。

戻 値

正常終了の場合は 0 を返します。
エラーの場合は EOF(-1)を返します。

例

ファイルを"w"モードでオープンし、１バイトのデータを書込み、ファイルをク
ローズします。

ファイルポインタ

void test(void){
FILE *fp;
if ((fp = fopen("A:\\test.txt", "w")) != NULL) {fputc('Z', fp);
fclose(fp);}}31

fgetc - ファイルから１文字読出し
形 式

int fgetc(FILE *fp);

引 数

fp

解 説

fp で指定されたファイルから１バイトのデータを読出します。

戻 値

読出した１バイトのデータを符号拡張せずに int へ変換した値を返します。
ファイルの終わり、またはエラーの場合は EOF(-1)を返します。

例

ファイルを"r"モードでオープンし、10 バイトのデータを読出してバッファに格納します。途中でファイルの終わりを検出した場合は、読出しを中止します。

ファイルポインタ

void test(void){
FILE *fp;
int n, c;char buf[10];if ((fp = fopen("A:\\test.txt", "r")) == NULL)
return; /* error */for (n = 0; n < 10; n++) {c = fgetc(fp);if (c == EOF)
break;
buf[n] = c;}fclose(fp);}補 足

実際には、fgetc 関数をループ処理して複数回発行するよりも、fread 関数を使用した方が高速に読出すことができます。

32

fputc - ファイルへ１文字書込み
形 式

int fputc(int c, FILE *fp);

引 数

c
fp

解 説

fp で指定されたファイルへ char 型に変換した c を書込みます。

戻 値

正常終了の場合は c を返します。エラーの場合は EOF(-1)を返します。

例

ファイルを"w"モードでオープンし、10 バイトの文字列を書込みます。

書込む文字
ファイルポインタ

void test(void){
FILE *fp;
int n, c;char *str = "0123456789";
if ((fp = fopen("A:\\test.txt", "w")) == NULL)
return; /* error */for (n = 0; n < 10; n++) {c = fputc(str[n], fp);
if (c == EOF) /* error */break;}
fclose(fp);}補 足

実際には、fputc 関数をループ処理して複数回発行するよりも、fwrite 関数を使用した方が高速に書込むことができます。

33

fgets - ファイルから１行分の文字列読出し
形 式

char *fgets(char *buf, int n, FILE *fp);

引 数

buf
n
fp

解 説

fp で指定されたファイルから文字列を読出し、buf で指定されたバッファへ格納します。改行文字(’\n’)を読出すまで、または、読出した文字数が n - 1 に等しくなるまで、あるいは、ファイルの終端に達するまで読出します。改行文字も buf
へ格納されます。
buf へ格納した文字列の最後に null 文字('\0')が付加されます。

戻 値

正常終了の場合は buf を返します。ファイルの終わりに達し、かつ buf に１文字も格納されていない場合は NULL を返します。エラーが発生した場合も NULL を返します。

例

ファイルを"r"モードでオープンし、文字列を 1 行読出して、バッファに格納します。

読出した文字列を受け取るバッファ
バッファのサイズ
ファイルポインタ

void test(void){
FILE *fp;
char *p;char buf[80];if ((fp = fopen("A:\\test.txt", "r")) == NULL)
return; /* error */p = fgets(buf, sizeof(buf), fp);
if(p == NULL) {/* error */}fclose(fp);}
補 足

この例のように auto 変数にバッファを定義する場合には、タスクのスタックオー
バーフローに注意してください。

34

fputs - ファイルへ 1 行分の文字列書込み
形 式

int fputs(const char *buf, FILE *fp);

引 数

buf
fp

解 説

fp で指定されたファイルへ buf に格納されている文字列を書込みます。文字列を終端する null 文字('\0')は、ファイルへ書込まれません。

戻 値

正常に文字列を書込めた場合は、非負の値(本ファイルシステムでは 0)を返します。書込めなかった場合は EOF(-1)を返します。

例

ファイルを"w"モードでオープンし、"abcdefg\n"という文字列を書込みます。

書込む文字列が格納されているバッファ
ファイルポインタ

void test(void){
FILE *fp;
int c;
if (fp = fopen("A:\\test.txt", "w")) == NULL)
return; /* error */c = fputs("abcdefg\n", fp);
if (c == EOF) {/* error */}fclose(fp);}35

fread - ファイルからブロック読出し
形 式

size_t fread(void *buf, size_t size, size_t n, FILE *fp);

引 数

buf
size
n
fp

解 説

fp で指定されたファイルから size×n バイトのデータを読出し、buf へ格納します。

戻 値

読出したブロック数を返します。正常終了の場合は n と等しい値を返します。ファ
イルの終わり、またはエラーの場合は n より小さい値を返します。size または nに 0 を指定した場合は何も読出さずに 0 を返します。

例

ファイルを"r"モードでオープンし、100 バイトのデータを読出しバッファに格納します。

データを格納するバッファのアドレス
１ブロックのバイト数
読出すブロックの数
ファイルポインタ

void test(void){
FILE *fp;
unsigned long n;char buf[100];if ((fp = fopen("A:\\test.txt", "r")) == NULL)
return; /* error */n = fread(buf, 1, 100, fp);
if (n < 100) {/* error */}fclose(fp);}
補 足size_t 型は stdio.h か stdef.h に定義されていて、コンパイラによって、longの場合と short の場合があります。総バイト数が size×n のため、size_t が shortの処理系でも、long サイズのデータを一度に扱うことが可能です。また、size = 1と指定すれば、n と戻値をブロック数でなく総バイト数と見なすことができます。

36

fwrite - ファイルへブロック書込み
形 式

size_t fwrite(const void *buf, size_t size, size_t n, FILE *fp);

引 数

buf
size
n
fp

解 説

fp で指定されたファイルへ、buf に格納されている size×n バイトのデータを書
込みます。

戻 値

書込んだブロック数を返します。正常終了の場合は n と等しい値を返します。エラーの場合は n より小さい値を返します。

例

ファイルを"w"モードでオープンし、バッファのデータを 100 バイト書込みます。

書込みデータバッファのアドレス
１ブロックのバイト数
書込むブロックの数
ファイルポインタ

void test(void){
FILE *fp;
unsigned long n;char buf[100];if ((fp = fopen("A:\\ test.txt", "w")) == NULL)
return; /* error */n = fwrite(buf, 1, 100, fp);
if (n < 100) {/* error */}fclose(fp);}
補 足fread の補足を参照してください。

37

fflush - ファイルのフラッシュ形 式

int fflush(FILE *fp);

引 数

fp

解 説

fp で指定されたファイルの、バッファされているデータをディスクへ書込みます。
fflush()の実行後も、指定されたファイルはオープンのままで、引き続き読み書
きが行えます。

戻 値

正常終了の場合は 0 を返します。
エラーの場合は EOF(-1)を返します。

例

ファイルを"w"モードでオープンし、100 バイトのデータを、1 バイトずつフラッ
シュしながら書込みます。

ファイルポインタ

void test(void){
FILE *fp;
int i, c;if ((fp = fopen("A:\\test.txt", "w")) == NULL)
return; /* error */for (i = 0; i < 100; i++) {c = read_some_data(); /* 何らかのデータ入力関数 */fputc(c, fp);
fflush(fp);}fclose(fp);}
補 足本ファイルシステムでは、コンフィグレーションで設定される書込み遅延時間を待って fflush()と同じ動作が自動的に繰り返されますが、その機能を使用しない
場合や、より明示的にファイルのフラッシュを行いたい場合には、fflush()によって FAT キャッシュや入出力バッファの内容とディスクの内容を一致させ、不意なシステムダウンに備えてください。

38

fseek - ファイル読み書き位置の移動
形 式

int fseek(FILE *fp, long offset, int origin);

引 数

fp
ファイルポインタ
offset 基準点からの移動バイト数
origin 基準点の種類

解 説

fp で指定されたファイルの読み書き位置を、origin で指定された基準点からoffset で指定されたバイト数だけ移動します。
origin には、次のマクロを指定してください。
SEEK_SETSEEK_CURSEEK_END

ファイルの先頭
現在位置
ファイルの終わり

SEEK_SET 指定時はファイルの先頭から offset バイト先の位置へ移動します。この場合、offset には 0 または正の値を指定してください。SEEK_CUR 指定時はファ
イルの現在の読み書き位置から offset バイト先の位置へ移動します。この場合、offset で指定する値が正ならばファイルの後尾へ、負ならばファイルの先頭へ向かって移動します。SEEK_END 指定時はファイルの終わりからの移動なので、offset には 0 または負の値を指定してください。
戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

ファイルを"w"モードでオープンし、ファイルポインタをファイルの先頭から 100
バイト目に移動します。
void test(void){
FILE *fp;
int r;
if ((fp = fopen("A:\\test.txt", "w")) == NULL)
return; /* error */r = fseek(fp, 100, SEEK_SET);
if (r != 0) {/* error */}fclose(fp);}補 足

FAT32 では 4 ギガバイトまでのファイルを操作できますが、fseek の offset パラ
メータは long 型のため、2 ギガまでの値しか指定できません。2GB を超えるファイルの位置決めには fsetpos 関数を使用してください。

39

ftell - 現在のファイル読み書き位置を取得
形 式

long ftell(FILE *fp);

引 数

fp

解 説

fp で指定されたファイルの現在の読み書き位置を返します。値はファイル先頭からのバイト数です。

戻 値

正常終了で現在位置を返します。エラーの場合は-1 を返します。

例

ファイルを"r"モードでオープンし、オープン直後のファイルポインタの位置を調べます。さらに 100 バイト読出し後のファイルポインタの位置を調べます。

ファイルポインタ

void test(void){
FILE *fp;
long pos;char buf[100];if ((fp = fopen("A:\\test.txt", "r")) == NULL)
return;/* error */pos = ftell(fp);/* pos には 0 が入ります */fread(buf, 1, 100, fp);
pos = ftell(fp);/* pos には 100 が入ります */fclose(fp);}補 足

FAT32 では 4 ギガバイトまでのファイルを操作できますが、ftell 関数の型は long型のため、2 ギガまでの値しか表現できません。2 ギガを超える位置は負の数となってしまい、エラーと見分けが付きません。2 ギガを超える位置が返される可能性がある場合は、fgetpos 関数を使用してください。

40

fsetpos - ファイル読み書き位置の移動
形 式

int fsetpos(FILE *fp, const fpos_t *pos);

引 数

fp
pos

解 説

fp で指定されたファイルの読み書き位置を、*pos で指定された値に設定します。

戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

ファイルを"w"モードでオープンし、ファイルポインタをファイルの先頭から 100
バイト目に移動します。

ファイルポインタ
読み書き位置の格納アドレス

void test(void){
FILE *fp;
fpos_t pos;if ((fp = fopen("A:\\test.txt", "w")) == NULL)
return; /* error */pos = 100;
r = fsetpos(fp, &pos);if (r != 0) {/* error */}fclose(fp);}補 足

fpos_t は一般的には stdio.h で定義されていますが、本ファイルシステム用に
nofile.h において unsigned long で再定義してあり、4GB までのファイル位置を操作できます。fpos_t の実装は ANSI で規定されておらず、コンパイラによって異なるので、fsetpos/fgetpos を使用したソースを移植する際は互換性に注意してください。

41

fgetpos - 現在のファイル読み書き位置を取得
形 式

int fgetpos(FILE *fp, fpos_t *pos);

引 数

fp
*pos

解 説

fp で指定されたファイルの現在の読み書き位置を取得し、*pos に返します。

戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

ファイルを"r"モードでオープンし、オープン直後のファイルポインタの位置を調べます。さらに 100 バイト読出し後のファイルポインタの位置を調べます。

ファイルポインタ
読み書き位置の格納アドレス

void test(void){
FILE *fp;
Int r;
fpos_t pos;char buf[100];if ((fp = fopen("A:\\test.txt", "r")) == NULL)
return;/* error */r = fgetpos(fp, &pos); /* pos には 0 が入ります */if (r != 0) {/* error */}fread(buf, 1, 100, fp);
r = fgetpos(fp, &pos); /* pos には 100 が入ります */if (r != 0) {/* error */}fclose(fp);}補 足

fpos_t は一般的には stdio.h で定義されていますが、本ファイルシステム用に
nofile.h において unsigned long で再定義してあり、4GB までのファイル位置を操作できます。fpos_t の実装は ANSI で規定されておらず、コンパイラによって異なるので、fsetpos/fgetpos を使用したソースを移植する際は互換性に注意してください。

42

feof - ファイルの終わりを検出
形 式

int feof(FILE *fp);

引 数

fp

解 説

fp で指定されたファイルの読み書き位置がファイルの終わりか否かを調べます。

戻 値

ファイルの終わりでは無い場合は 0 を返します。ファイルの終わりを検出した場合は非 0 の値(本ファイルシステムでは１)を返します。

例

ファイルを"r"モードでオープンし、データを 100 バイト読出し、ファイルの終わりを調べます。

ファイルポインタ

void test(void){
FILE *fp;
char buf[100];if ((fp = fopen("A:\\test.txt", "r")) == NULL)
return; /* error */fread(buf, 1, 100, fp);
if (feof(fp)) {/* ファイルの終わり */}fclose(fp);}43ferror - エラー情報の取得
形 式

int ferror(FILE *fp);

引 数

fp

解 説

fp で指定されたファイルの入出力で発生したエラーの詳細なエラーコードを返します。ファイルシステム内部で保持されているエラーコードは、clearerr()をコールするまではクリアされません。多重にエラーが発生している場合には、新しい方のエラーコードを返します。

戻 値

エラーが発生していない場合は 0 を返します。エラーが発生していた場合は 0 以
外の値を返します。具体的な値は、第 4 章“エラーコード一覧”を参照してください。

例fwrite()の戻値が指定サイズより小さい場合に、エラーコードを参照します。

ファイルポインタ

void test(void){
FILE *fp;
char buf[100];
int size, err;if ((fp = fopen("A:\\test.txt", "w")) != NULL) {size = fwrite(buf, 1, 100, fp);
if (size < 100) {err = ferror(fp);if (err == EV_DISKFULL) {/* ディスクフルで書込み中断 */}}fclose(fp);}}
補 足ferror 関数自体は ANSI 準拠ですが、エラーコードは、本ファイルシステム独自のものです。ANSI 準拠のコーディングを行うためには、0(正常)か 0 以外(エラー)かの判断のみを行ってください。

44

clearerr - エラー情報のリセット
形 式

void clearerr(FILE *fp);

引 数

fp

解 説

ファイルシステム内部に保持されているエラーコードをクリアします。

戻 値

なし

例

fwrite()の戻値が指定サイズより小さい場合に、エラーコードを参照 し、エラーをクリアします。

ファイルポインタ

void test(void){
FILE *fp;
char buf[100];
int size, err;if ((fp = fopen("A:\\test.txt", "w")) != NULL) {size = fwrite(buf, 1, 100, fp);
if (size < 100) {err = ferror(fp);if (err == EV_DISKFULL) {/* ディスクフルで書込み中断 */clearerr(fp);}}fclose(fp);}}45

remove - ファイルの削除
形 式

int remove(const char *path);

引 数

path

解 説

path で指定されたファイルを削除します。path は、fopen()と同じようにフルパスで指定してください。フルパス指定の詳細については fopen()の解説を参照してください。

削除するファイルのパス名(フルパス指定)

path にワイルドカード('*'や'?')を使うことはできません。オープンしているファイルを path に指定するとエラーになります。path で指定されたファイルが存在しない場合もエラーになります。
戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ファイルを削除します。
void test(void){
int r;
r = remove("A:\\test.txt");
if (r == -1) {/* error */}}46

rename - ファイル名やディレクトリ名の変更
形 式

int rename(const char *oldname, const char *newname);

引 数

oldname 旧ファイル名またはディレクトリ名(フルパス指定)
newname 新ファイル名またはディレクトリ名(パス指定なし)

解 説

oldname で指定されたファイルまたはディレクトリの名前を newname で指定された名前に変更します。
oldname は、fopen()の path と同じようにフルパスで指定してください。存在しないファイルやオープン中のファイル、または存在しないディレクトリを指定す
るとエラーになります。
newname はファイル名またはディレクトリ名のみを指定してください。パスを付けるとエラーになります。すでに存在するファイル名またはディレクトリ名を指定するとエラーとなります。
oldname と newname にワイルドカードを使うことはできません。

戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

ディレクトリ"A:\dir"の下にある"old.c"というファイルを"new.c"というファイル名に変更します。
void test(void){
int r;
r = rename("A:\\dir\\old.c", "new.c");if (r != 0) {/* error */
}
}

補 足

他のファイルシステムに比較しての制限として、newname にパスを指定して別のディレクトリへファイルを移動することはできません。

47

mkdir - ディレクトリの作成
形 式

int mkdir(const char *dirname);

引 数

dirname 作成するディレクトリ名(フルパス名)

解 説

dirname で指定されたディレクトリを作成します。dirname は fopen()で解説したパス名から最後のファイル名を取り除いたものです。
最下層以外のディレクトリが、呼び出し時に存在していない場合、本関数はエラーになります。たとえば 3 階層目のディレクトリを作成する場合、すでに
A:\AAAAA\BBBBBというディレクトリが存在する状態でmkdir("A:\\AAAAA\\BBBBB\\CCCCC");のように指定してください。

戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ディレクトリ"A:\dir"を作成します。
void test(void){
int r;
r = mkdir("A:\\dir");
if (r == -1) {/* error */}}48

rmdir - ディレクトリの削除
形 式

int rmdir(const char *dirname);

引 数

dirname 削除するディレクトリ名(フルパス名)

解 説

dirname で指定されたディレクトリを削除します。dirname は fopen()で解説したパス名から最後のファイル名を取り除いたものです。
ディレクトリの削除はディレクトリ内が空でない場合、エラーになります。そのため、多階層のディレクトリを削除する場合は下層側から順に削除しなければなりません。ルートディレクトリは指定できません。

戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ディレクトリ"A:\dir"を削除します。
void test(void){
int r;
r = rmdir("A:\\dir");
if (r == -1) {/* error */}}49

opendir - ディレクトリのオープン
形 式

DIR *opendir(const char *dirname);

引 数

dirname オープンするディレクトリ名(フルパス指定)

解 説

dirname で指定されたディレクトリをオープンします。オープン後は readdir()でディレクトリ情報を読出すことができます。
存在しないディレクトリ名を指定するとエラーになります。

戻 値

正常にオープンできた場合には、ディレクトリを管理する構造体へのポインタ(ディレクトリポインタ)を返します。以後、ディレクトリに対する操作はこのポインタを指定してください。エラーが発生した場合は NULL を返します。

例

readdir()の例を参照してください。

closedir - ディレクトリのクローズ形 式

int closedir(DIR* dp);

引 数

dp

解 説

dp で指定されたディレクトリをクローズします。opendir()の戻値を dp に指定してください。

戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

readdir()の例を参照してください。

ディレクトリポインタ

50

readdir - ディレクトリ情報の読出し
形 式

struct dirent *readdir(DIR *dp);

引 数

dp

解 説

dp で指定されたディレクトリの情報(ディレクトリエントリ)を、１つずつ順に読出します。

ディレクトリポインタ

POSIX 準拠の dirent 構造体は、次の形式となっています。POSIX の場合の
NAME_MAX の値は 128 ですが、本ファイルシステムでは 256 に拡張してあります。
struct dirent{
long d_ino;
unsigned short d_namlen;
char d_name[NAME_MAX+1];};/* inode 番号(未使用:不定) *//* ファイル名の長さ(null 文字含まず) *//* ファイル名(null 文字'\0'で終端) */戻 値

正常に読出せた場合は、dirent 構造体へのポインタを返します。最後の情報に達していた場合やエラーの場合は、NULL を返します。

例

ディレクトリ"A:\dir"をオープンしてこのディレクトリ下にあるディレクトリとファイルの情報を取得し、ディレクトリ名またはファイル名を出力します。
void test(void){
DIR *dp;
struct dirent *p;if ((dp = opendir("A:\\ dir ")) == NULL)
return; /* error */for (;;) {p = readdir(dp);if (p == NULL)
break;
puts(p->d_name);}closedir(dp);
}

51

補 足

本ファイルシステムの独自拡張として、dirent 構造体を direntx 構造体へキャスト(型変換)することによって、より詳細なディレクトリエントリ情報を取得することが可能です。独自の direntx 構造体は、次の形式となっています。
struct direntx{
T_DIRENTRY *direntry;/* ディレクトリエントリ詳細情報 */unsigned short d_namlen;/* ファイル名の長さ(null 文字含まず) */char d_name[NAME_MAX+1];/* ファイル名(null 文字'\0'で終端) */};direntx 構造体の direntry メンバーでポイントされる独自の T_DIRENTRY 構造体
は、次の形式となっています。
typedef struct t_direntry {unsigned char name[8+3];
char attr;
char rsv;
unsigned char mktimems;
unsigned short mktime;
unsigned short mkdate;unsigned short access;unsigned short up_clusno;
unsigned short time;
unsigned short date;unsigned short clusno;
unsigned long size;} T_DIRENTRY;

ファイル名、ディレクトリ名
属性
予約(値 0x00)
作成時刻(10ms 単位)
作成時刻
作成日付
アクセス日付上位 FAT エントリ No.
更新時刻
更新日時
下位 FAT エントリ No
ファイルサイズ(バイト単位)※上記の構造体は、ディスク上にリトルエンディアン並びで格納されている値そのものです。ビッグエンディアンの CPU で参照する際は、エンディアン変換が必要です。
attr のビット構成
7

6

5

4

3

2

1

ビット 0：読出し専用ファイル
ビット 1：隠しファイル
ビット 2：システムファイル0
ビット 3：ディスクドライブボリュームラベル
ビット 4：ディレクトリ
ビット 5～7：未使用

mktime、time のビット構成
15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

時：０～２３
分：０～５９秒：０～２９注)秒は 2 秒単位です。例えば、40 秒の場合は 20 が格納されます。
mkdate、date、access のビット構成
15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

年：０～１２７
月：１～１２
日：１～３１注)年は 1980 を起点とします。例えば、2004 年では 24 が格納されます(2004-1980=24)。
52

例ディレクトリ"A:\dir"をオープンしてこのディレクトリ下にあるディレクトリとファイルの情報を取得し、ファイル名とファイルサイズを出力します。
void test(void){
DIR *dp;
struct direntx *p;
char s[11];if ((dp = opendir("A:\\ dir ")) == NULL)
return; /* error */for (;;) {p = (struct direntx *)readdir(dp);if (p == NULL)
break;
print(p->d_name); print(" ");ltod(s, p->direntry->size, 10);puts(s);}closedir(dp);}53

fgetattr - ファイルの属性を取得
形 式

int fgetattr(const char *path);

引 数

path

解 説

path で指定されたファイルの属性値を取得します。path は、fopen()と同じようにフルパスで指定してください。ファイルの属性値は fsetattr()の解説を参照してください。本ファイルシステムでは、ディレクトリの属性は取得できません。

戻 値

正常終了の場合は属性値を返します。エラーの場合は-1 を返します。

パス名(フルパス指定)

fsetattr - ファイルの属性を変更
形 式

int fsetattr(const char *path, int attr);

引 数

path
attr

解 説

path で指定されたファイルの属性値を attr で指定された値に変更します。
ファイルの属性値は１バイトで、各ビットの意味は次のようになります。

パス名(フルパス指定)
属性値

bit0
bit1
bit2
bit3
bit4
bit5
bit6
bit7

読出し専用ファイル
ATTR_READONLY
隠しファイル
ATTR_HIDDEN
システムファイル
ATTR_SYSTEM
ディスクドライブボリュームラベル ATTR_VOLUME
ディレクトリ
ATTR_DIRECTORY
アーカイブ
ATTR_ARCHIVE
未使用
未使用

上記以外に全ビットが 0 の ATTR_NORMAL が定義されています。本ファイルシステ
ムでは、ディレクトリの属性は変更できません。ATTR_VOLUME や ATTR_DIRECTORYは定義されていますが、指定するとエラーとなります。
戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ファイルの属性値を取得し、読出し専用ビット(bit0)を ON に変更します。
void test(void){
int r, attr;
attr = fgetattr("A:\\test.txt");r = fsetattr("a:\\test.txt", (attr | ATTR_READONLY));
if (r == -1) {/* error */}}54

fgetsize - ファイルサイズの取得
形 式

int fgetsize(FILE *fp, unsigned long *size);

引 数

fp
size

解 説

fp で指定されたファイルのサイズを取得します。取得したファイルサイズは、バ
イト単位で、size で指定された変数へ格納されます。

戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ファイルのファイルサイズを取得します。

ファイルポインタ
ファイルサイズ格納先のポインタ

void test(void){
FILE *fp;
unsigned long size;
int r;
if ( (fp = fopen("A:\\test.txt", "r")) != NULL) {r = fgetsize(fp, &size);if (r == 0) {/* size に"A:\\test.txt"のファイルサイズが格納されます */} else {/* error */}fclose(fp);}}55

fsetsize - ファイルサイズの変更
形 式

int fsetsize(FILE *fp, unsigned long size);

引 数

fp
size

解 説

fp で指定されたファイルのサイズを、size で指定されたサイズへ変更します。

ファイルポインタ
変更後のファイルサイズ

現在のファイルサイズより大きいサイズを指定した場合は、追加となるデータとして、null 文字('\0')が書込まれます。小さいサイズを指定した場合は、切り捨
てられる部分のデータが失われます。"r"モードでオープンしている場合はエラーを返します。
戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ファイルを空にします。
void test(void){
FILE *fp;
int r;
if ((fp = fopen("A:\\test.txt", "r+")) != NULL) {r = fsetsize(fp, 0);
if (r != 0) {/* error */}fclose(fp);}}56

fgetmtime - ファイルまたはディレクトリの作成時刻を取得
形 式

int fgetmtime(const char *path, struct tm *mtime);

引 数

path
mtime

解 説

path で指定されたファイルやディレクトリの作成時刻(タイムスタンプ)を mtimeで指定された変数へ格納します。path は fopen()と同様にフルパスで指定してください。

ファイルまたはディレクトリ名(フルパス指定)
時刻情報格納先へのポインタ

tm 構造体については、fsetmtime()の解説を参照してください。
戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ファイルのタイムスタンプを取得します。
void test(void){
struct tm ts;
int r;
r = fgetmtime("A:\\test.txt", &ts);
if (r == 0) {/* ts に"A:\\test.txt"のタイムスタンプが格納されます*/} else {/* error */
}
}

補 足

Unix 系のファイルが持つ時刻としては、mtime：ファイルが作成/修正された(Modified)時刻、atime：最後にアクセスされた(Accessed)時刻、ctime：属性が変更された(Changed)時刻の３つが存在します。本ファイルシステムでは、このう
ち、mtime のみの取得と変更をサポートしています。

57

fsetmtime - ファイルまたはディレクトリの作成時刻を変更
形 式

int fsetmtime(const char *path, struct tm *mtime);

引 数

path
mtime

解 説

path で指定されたファイルまたはディレクトリの作成時刻(タイムスタンプ)を変更します。時刻情報を tm 構造体へ代入し、そのポインタを mtime に指定してください。

ファイルまたはディレクトリ名(フルパス指定)
時刻情報へのポインタ

月は、1 月を 0 として計算されます。2 月は 1、3 月は 2、…、12 月は 11 という指定になりますので注意してください。
年は 1900 年を 0 として計算されます。ディスク上には 1980 年以降の値しか保存できないので、必ず 80 以上(1980 年以降)を指定してください。
秒の値は偶数秒に丸められます。
戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

タイムスタンプを「2004 年 8 月 9 日 10 時 20 分 30 秒」にセットします。
void test(void){
struct tm ts;
ts.tm_sec = 30;/* 30 秒 */ts.tm_min = 20;/* 20 分 */ts.tm_hour = 10;/* 10 時 */ts.tm_mday = 9;/* 9 日 */ts.tm_mon = 8 - 1;/* 8 月(1 月を 0 とした値) */ts.tm_year = 2004 - 1900; /* 2004 年(1900 年を 0 とした値) */ts.tm_wday = 0;/* 未使用 */ts.tm_yday = 0;/* 未使用 */ts.tm_isdst = 0;/* 未使用 */fsetmtime ("A:\\test.txt", &ts);}

58

returnname - ファイル名を返す
形 式

const char *returnname(FILE *fp);

引 数

fp

解 説

fp で指定されたファイルのパス前を、"d:\aaaa\bbbb\nnnnnnnn.eee"形式のフルパスで返します。

戻 値

パス名が格納されている領域へのポインタを返します。

例

オープンしてあるファイルのタイムスタンプを取得します。

ファイルポインタ

void test(void){
FILE *fp;
struct tm ts;
if ((fp = fopen("A:\\test.txt", "r")) == NULL)
return; /* error */fgetmtime(returnname(fp), &ts); /* fp をパス名に変換 */fclose(fp);}補 足

ファイルポインタでなくパス名でファイルを指定するタイプの API を、オープン
中のファイルに対しても簡単に利用できるように用意されている独自の API です。

59

getdiskfree - ディスクの残容量を取得(4GB 未満)
形 式

int getdiskfree(const char *drv, unsigned long *size);

引 数

drv
size

解 説

drv で指定されたドライブの残容量を求め、size で指定された先へ結果を格納します。容量の単位はバイトです。結果が 32 ビットで表現できる最大値を超えた場
合(4GB 以上の場合)は、0xffffffff を size で指定された先へ格納します。

戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

ドライブ"A:"のディスク残容量を求めます。

ドライブ名("A:", "B:", …)取得した残容量の格納先へのポインタ

void test(void){
unsigned long size;
int r;
if ((r = getdiskfree("A:", &size)) != 0) {/* error */}}補 足

サイズが４GB を超える場合は getdiskfreex()を使用してください。

60

getdiskfreex - ディスクの残容量を取得(4GB 以上)
形 式

int getdiskfreex(const char *drv, unsigned long *h_size, unsigned long*l_size);

引 数

drv
ドライブ名("A:", "B:", …)
h_size 残容量上位 32bit の格納先へのポインタ
l_size 残容量下位 32bit の格納先へのポインタ

解 説

drv で指定されたドライブの残容量を求め、h_size、l_size で指定された先へ結果を格納します。容量の単位はバイトです。結果の上位 32bit は h_size で指定された先へ格納され、下位 32bit は l_size で指定された先へ格納されます。

戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

ドライブ"A:"の残容量を調べます。
void test(void){
unsigned long h_free, l_free;
int r;
r = getdiskfreex ("A:", &h_free, &l_free);if (r != 0) {/* error */}if (h_free > 0) {/* 残容量は 4GB 以上です */}}61

getdisksize - ディスクの容量を取得
形 式

int getdisksize(const char *drv, unsigned long *size);

引 数

drv
size

解 説

drv で指定されたドライブの容量を求め、size で指定された先へ取得したディスク容量を格納します。容量の単位はメガバイト(MB)です。

戻 値

正常終了の場合は 0 を返します。エラーの場合は非 0 の値(本ファイルシステムでは-1)を返します。

例

ドライブ"A:"の総容量を調べます。

ドライブ名("A:", "B:", …)
ディスク容量の格納先へのポインタ

void test(void){
unsigned long total;
int r;
r = getdisksize("A:", &total);
if (r != 0) {/* error */}}62

disk_mount - マウント
形 式

int disk_mount(T_DISK *d);

引 数

d

解 説

ディスクドライブを使用可能にします。d には disk_ini()の第 1 引数 d で指定した T_DISK 構造体へのポインタを指定してください。disk_ini()で取り外し可能(リムーバブル)を指定しなかった場合には、マウント処理を行う必要はありません 。(行っても害はありません)

戻 値

正常終了の場合は E_OK を返します。エラーの場合はドライバの戻値を返します。

例

disk_unmount()の例を参照してください。

T_DISK 構造体へのポインタ

63disk_unmount - アンマウント
形 式

int disk_unmount(T_DISK *d);

引 数

d

解 説

ディスクドライブの使用を終了します。d には disk_ini()の第 1 引数 d で指定した T_DISK 構造体へのポインタを指定してください。

戻 値

正常終了の場合は E_OK を返します。エラーの場合はドライバの戻値を返します。

例

ドライブ"A:"をリムーバブルなディスクとして初期化し、マウント、アンマウン
トします。

T_DISK 構造体へのポインタ#define NCACHE 5
T_DISK disk[1];
T_CACHE cache[NCACHE];
int test(void){
int r;
r = disk_ini(disk, "A:", flash_ATA, 0, 0, NULL, 0, 1);
if (r != E_OK) {return -1; /* error */}disk_cache(disk, cache, NCACHE);
r = disk_mount(disk);
if (r != E_OK) {return -1; /* error */}/* この間でファイル入出力 */r = disk_unmount(disk);
if (r != E_OK) {return -1; /* error */}}64

dformat - ディスクのフォーマット
形 式

int dformat(const char *drv, const long param);

引 数

drv
param

解 説

指定されたディスクを完全に初期化します。

ドライブ名("A:", "B:", …)
ディスクドライバ依存のパラメータ

drv にはフォーマットするドライブのドライブレター文字列を指定してください。
param にはドライバによって決められたパラメータを指定してください。
RAM ディ
スクの場合は未使用で、0 を指定してください。
本関数を使用する場合はドライバがフォーマット機能をサポートしている必要があります。
戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

補 足

付属の ATA ドライバは本機能をサポートしていません。
RAM ディスクドライバは本機能をサポートしています。

65

qformat - ディスクのクイックフォーマット
形 式

int qformat(const char *drv);

引 数

drv

解 説

drv で指定されたディスクのファイルを全て削除します。

ドライブ名("A:", "B:", …)

すでに FAT ファイルシステムでフォーマットされているディスクのみに使用できます。ディスクの BPB(BIOS Parameter Block)は書き換えません。
戻 値

正常終了の場合は 0 を返します。エラーの場合は-1 を返します。

例

ドライブ"A:"に対してクイックフォーマットを行います。
void test(void){
int r;
r = qformat("A:");if (r == -1) {/* error */
}
}

66

第４章

エラーコード一覧

本ファイルシステムのエラーコードは次のようになります。
エラーコード名
EV_FNAME
EV_FSAME
EV_NOFILE
EV_NODIR
EV_FMODE
EV_NOOPEN
EV_OPENED
EV_DISKRD
EV_DISKWR
EV_NFILE
EV_DISKFULL
EV_DRVNAMEEV_FPAR
EV_EOF
EV_DIRENT
EV_FNOSPTEV_DISKINI
EV_FILEINIEV_UNMOUNTEV_NOEMPTY
EV_DRVINI
EV_MOUNT
EV_CACHESZ
EV_FATS
EV_FILEFULL
EV_FREESECT
EV_FERR

エラー
コード値
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-128

エラー内容
指定ファイル名、指定ディレクトリ名が異常同一ファイル名、同一ディレクトリ名が存在する
指定ファイルが存在しない
指定ディレクトリが存在しない
指定モードが異常ファイルがオープンされていない
指定ファイルが既にオープンされているデバイスリードエラー
デバイスライトエラー
可能な同時オープンファイル数を超えた
ディスクフル
指定ドライブ名が異常指定パラメータが異常ファイルの終端に達した可能な同時オープンディレクトリ数を超えたサポートされていない
初期化(disk_ini)されていない
初期化(fsys_ini)されていない
マウントされていない
空でないディレクトリを削除しようとした
デバイス初期化エラー
デバイスマウントエラー
キャッシュサイズ不足
FAT エラー2GB 以上のファイルを作成しようとした
空き容量に設定されている値が異常
その他

67

第５章
5.1

ドライバ・インターフェース

ディスクドライバ関数
ディスクドライバは、
本ファイルシステムにデバイスの read/write または formatなどの機能を提供します。ディスクドライバのエントリは 1 ドライブにつき１個の関数です。ディスクドライバの初期化 disk_ini()の引数 func にこの関数名を指定することにより、ファイルシステムとディスクドライバが関連付けられます。
ディスクドライバ関数はディスクによって異なり、そのの名前は自由ですが、本書では diskdrive として説明します。ディスクドライバ関数は、次の形式をしています。
ER diskdrive(T_DISK *d, FN fncd, UW sectno, VP parm, UH snum);
T_DISK 構造体へのポインタ d へは、ディスクドライバの初期化 disk_ini()の引数 dで指定された値が渡ります。fncd へは、ディスクドライバへのコマンドが指定されます。sectno は、読み書きするセクタの番号です。param はコマンドによって意味が変わります。snum は連続した複数セクタの読み書きを指示する場合のセクタ数を指定します。
ディスクドライバ関数の戻値はエラーコードで、正常終了の場合は E_OK が返り
ます。

5.2

コマンド一覧
ディスクドライバのコマンドの体系は ATA コマンドをベースにしています。ファイルシステム本体からディスクドライバへ渡されるコマンドには次のものがあります。
TFN_READ_SECTOR
TFN_WRITE_SECTOR
TFN_IDENTIFY
TFN_FORMATTFN_HARDWARE_INIT
TFN_HARDWARE_RESETTFN_MOUNTTFN_UNMOUNTTFN_MEDIACHK

指定セクタを読出し(param = 入力バッファ)指定セクタへ書込み(param = 出力バッファ)
パラメータ情報の取得
フォーマット(param = dformat()の第 2 引数)
ハードウェアの初期化
ハードウェアのリセット
マウント
アンマウント
挿入チェック68

5.3

ディスクドライバの例
ER diskdrive(T_DISK *d, FN fncd, UW sectno, VP parm){ER ercd;
switch (fncd) {case TFN_READ_SECTOR:
if ( d->callback != (DISK_CALLBACK)NULL )d->callback( d, TFN_DISK_READING );ercd = read_sector(d, sectno, (UB **)parm);if ( d->callback != (DISK_CALLBACK)NULL )d->callback( d, TFN_DISK_STOPPED );return ercd;
case TFN_WRITE_SECTOR:
if ( d->callback != (DISK_CALLBACK)NULL )d->callback( d, TFN_DISK_WRITING );ercd = write_sector(d, sectno, (UB *)parm);if ( d->callback != (DISK_CALLBACK)NULL )d->callback( d, TFN_DISK_STOPPED );return ercd;
case TFN_IDENTIFY:
ercd = identify(d);return ercd;
case TFN_FORMAT:
ercd = format(d);return ercd;
case TFN_HARDWARE_INIT:
ercd = hardware_init(d);return ercd;
case TFN_HARDWARE_RESET:
return E_OK;
case TFN_MOUNT:
ercd = mount(d);if ( d->callback != (DISK_CALLBACK)NULL )d->callback( d, TFN_DISK_MOUNTED );return ercd;
case TFN_UNMOUNT:
ercd = unmount(d);if ( d->callback != (DISK_CALLBACK)NULL )d->callback( d, TFN_DISK_UNMOUNTED );return ercd;
case TFN_MEDIACHK:
ercd = ref_drv(d);return ercd;
default:
return E_NOSPT;
}
}

69

第６章
6.1

状態変化通知用コールバック関数

概要
状態変化通知用コールバック関数は本ファイルシステムがユーザーにディスクの状態を通知するための関数です。本関数を使用すれば、アクセス中にメディアをロックする、またはアクセスランプをつけることなどが可能になります。また、
コンパクトフラッシュの挿入や抜取の検出時も本関数がコールされます。挿抜の検出時に、本コールバック関数の中から NORTi のシステムコールを使用して任意のタスクに挿抜の検出を通知することが可能です。ただし、挿抜の検出は周期起動ハンドラで行っているので、呼び出せるシステムコールには制限があります。

6.2

機能一覧
状態変化通知用コールバック関数の機能一覧は次のようになります。
TFN_DISK_READING
TFN_DISK_WRITINGTFN_DISK_STOPPEDTFN_DISK_DETECTED
TFN_DISK_REMOVED
TFN_DISK_MOUNTED
TFN_DISK_UNMOUNTED
TFN_DISK_ERROR

読出し開始の通知
書込み開始の通知
読出しまたは書込み終了の通知
メディア挿入の通知
メディア抜取の通知
マウントの通知
アンマウントの通知
エラーの通知70

6.3

コールバック関数の例
コールバック関数のエントリは 1 ドライブにつき 1 個です。関数 disk_ini の引
数 callback にエントリのポインタを指定してください。関数名は自由ですが、本書ではコールバック関数のエントリ名を disk_callback として、その例を示します。例では、各タイミングで書込み中や読出し中を示すＬＥＤを点灯しています。
#define LED_RD
0x8000#define LED_WR
0x4000#define LED_DET
0x2000#define LED_MOUNT 0x0100
void led_set(unsigned short c);void led_clr(unsigned short c);
ER disk_callback(T_DISK *d, FN fncd){
switch(fncd) {case TFN_DISK_READING:
led_set(LED_RD);
return E_OK;
case TFN_DISK_WRITING:
led_set(LED_WR);
return E_OK;
case TFN_DISK_STOPPED:
led_clr(LED_RD|LED_WR);
return E_OK;
case TFN_DISK_DETECTED:
led_set(LED_DET);
return E_OK;
case TFN_DISK_REMOVED:
led_clr(LED_DET);
return E_OK;
case TFN_DISK_MOUNTED:
led_set(LED_MOUNT);
return E_OK;
case TFN_DISK_UNMOUNTED:
led_clr(LED_MOUNT);
return E_OK;
case TFN_DISK_ERROR:
return E_OK;
default:
return E_NOSPT;
}
}

71

第７章

PC カードアクセス関数の実装

本ファイルシステムに付属する ATA ドライバが、コンパクトフラッシュ等のレジスタをアクセスする為に呼び出す関数を、PC カードアクセス関数と呼びます。これらはハードウェ
ア依存であり、ハードにあわせての移植作業が必要です。本章では、そのポイントを関数ごとに記述します。
なお ATA ドライバは ATA(IDE)の各レジスタにバイトアクセス可能で、データレジスタはワードアクセス可能であることを前提に実装されています。これらを満たさない場合はnofata.c の変更が必要になります。DMA と割り込みは使用していないので、それに関する移植作業は考慮する必要がありません。

ER PCCard_init(void)
解 説

PC カード挿入の確認後、ドライバの関数 mount()から呼ばれます。
正式な PCMCIA(PC カード)手順の場合は、カードの種別を確認し、適切な VCC(3.3V
または 5V)を与えます。安定待ちのために最後に一定時間のウェイトを行います。
PC カード挿入を確認できない場合は異常終了します。
PC カード挿入と同時に、自動的に電源が ON になるようなハードウェアの場合、本関数はウェイトのみの実装で構いません。
PC カード準拠でも常時電源 ON である簡易型接続や、TrueIDE での接続の場合は、すでに電源 ON ですので正常終了だけで構いません。

ER PCCard_check(void)
解 説

PC カード挿入チェック関数です。
PC カードが挿入されている場合は E_OK を、挿入されていない場合は E_OBJ を返してください。
もともと活線挿抜に対応していない TrueIDE や、簡易型の PC カードの場合は挿抜が検知できない場合が多いので、E_OK を返してください。

ER PCCard_end(void)
解 説

PC カード電源(VCC)を OFF にします。電源を ON/OFF する機能がない場合は、何もしないでリターンさせてください。

72void PCCard_open(void)解 説 PC カードの挿入の確認後、関数 mount()から PCCard_init()の後に呼ばれます。
PC カードの各空間(コモン、アトリビュート、I/O)をそれぞれ別々のアドレスに割り当てる為の設定を、PC カードコントローラに対して行う必要がある場合は、
ここで行います。
設定を行わなくても、PC カードの各空間をアクセスできるようなハードウェアの場合は、その設定は不要です。
上記はいずれも PC カード仕様なので、ATA レジスタを I/O 空間でアクセスする為に、CompactFlash を I/O モードに設定する必要があります。
カードコンフィグレーションレジスタに Index=1 を書込んで、ContiguousI/O モードに設定してください。(PCCard_atr_writeb 関数を使用)
TrueIDE の場合はこの処理は不要です。

UB PCCard_atr_readb(UW addr)
解 説

PC カードのアトリビュート空間を読み出してカードのタプル情報を取得する場
合に実装してください。
アトリビュート空間のベースアドレスにオフセット(addr)を加算したアドレスか
らデータをバイトアクセスで読出し、戻値として返します。
ドライバではタプル情報の活用をしていないので、省略可能です。TrueIDE の場
合は、そもそも不要です。

void PCCard_atr_writeb(UW addr, UB data)
解 説

PC カードの、アトリビュート空間のベースアドレスにオフセット(addr)を加算したアドレスへデータをバイトアクセスで書込みます。
CompactFlash カードを I/O カードモードに設定するために、アトリビュート空間
内のカードコンフィグレーションレジスタへの書き込みが必要ですが、その為だけに使用されます。PC カード用カードアクセス関数のソース内でしか使用しないので、直接アドレスを指定してコンフィグレーションレジスタへの書き込みを記述するならば、この関数は不要です。
TrueIDE の場合はアトリビュート空間が無いので、そもそも不要です。

UB PCCard_io_readb(UW addr)
解 説

PC カードでは、I/O 空間のベースアドレスにオフセット(addr)を加算したアドレスからデータをバイトアクセスで読出し、戻値として返します。
TrueIDE の場合は、TrueIDE のレジスタ群のベースアドレスに対し、オフセット(addr)を加算したアドレスからデータをバイトアクセスで読み出し、戻値として返します。データレジスタ以外のレジスタを読み出す為に使用します。

73void PCCard_io_writeb(UW addr, UB data)
解 説

PC カードでは、I/O 空間のベースアドレスにオフセット(addr)を加算したアドレスへデータ(data)をバイトアクセスで書込みます。
TrueIDE の場合は、TrueIDE のレジスタ群のベースアドレスに対し、オフセットを加算したアドレスへデータをバイトアクセスで書き込みします。データレジスタ
以外のレジスタへ書き込む為に使用します。

UH PCCard_io_readw(UW addr)
解 説

PC カードでは、I/O 空間のベースアドレスにオフセット(addr)を加算したアドレスからデータをワードアクセスで読み出し、戻値として返します。
TrueIDE の場合は、TrueIDE のレジスタ群のベースアドレスに対し、オフセットを加算したアドレスからデータをワードアクセスで読み出し、戻値として返します。
データレジスタを読み出す為に使用します。

void PCCard_io_writew(UW addr, UH data)
解 説

PC カードでは、I/O 空間のベースアドレスにオフセット(addr)を加算したアドレスへデータ(data)をワードアクセスで書き込みます。
TrueIDE の場合は、TrueIDE のレジスタ群のベースアドレスに対し、オフセット(addr)を加算したアドレスへデータ(data)をワードアクセスで書き込みます。
データレジスタへ書き込む為に使用します。

74

NORTi File System ユーザーズガイド
Copyright (c) 2000-2021, NEWRAL Co., Ltd. All rights reserved.
Copyright (c) 2003-2021, MiSPO Co., Ltd. All rights reserved.

株式会社ミスポ http://www.mispo.co.jp/〒222-0033 神奈川県横浜市港北区新横浜 3-20-8 BENEX S-3 12F
一般的なお問い合せ sales@mispo.co.jp
技術サポートご依頼 norti@mispo.co.jp