MochiOS@仮想ファイルシステムの作成part10
前提知識無しで作るなんちゃって仮想ファイルシステムpart10。
開発日記です。独り言です。
これまでのあらすじ
part | 内容 |
---|---|
0 | 仮想ファイルシステムを作りたい宣言をする。 |
1 | ざっくり仮想ファイルシステムの機能を決める。 が、機能呼出し先の仮想ファイルシステムのタスクIDをどう取得するかという問題に気付く。 |
2 | カーネルにタスク名登録機能を実装した。 これでタスク名からタスクIDを取得する事が出来る様になるハズ、なので試したいが試す方法が無い事に気付き、ログ出力タスクの開発を宣言する。 |
3 | ログ出力の為に使うvsnprintf()の仕様を調べる。 |
4 | ログ出力タスクを開発してタスク名からタスクIDの取得機能が正しく動いている事が確認できた。 |
5 | mount機能を実装した。たぶんできてる。 |
6 | FDどうやって管理しようかー。メッセージのやり取り制御を状態遷移で制御しようかー。とか考えて、open機能を実装した。たぶんできてる。 |
7 | openと同じようなシーケンスなので、メッセージとちょっとやる事変えて簡単にwrite機能を実装できちゃった。 |
8 | writeと同じようなシーケンスなので、メッセージとちょっとやる事変えて簡単にread機能を実装できちゃった。 |
9 | readと同じようなシーケンスなので、メッセージとちょっとやる事変えて簡単にclose機能を実装できちゃった。 |
応用
これまでmount、open~closeまでさくっと何も考えずに実装してきた。(そういえばunmount実装してないな。まいいか)
全てはドライバとアプリ間のインタフェースを作ることがひとまずの目的だったので、ドライバを作ってみなければ。
というわけでns16550ドライバを作った。
ns16550は所謂、RS-232C、COMポート、シリアルポート、UARTなどと呼ばれているハードウェアで、割りと制御が簡単。
それぞれ16byteの転送バッファと受信バッファがあって、書き込む(VfsWrite)時は転送バッファがフルでなければ1byteづつ書き込んでフルの時は転送バッファ空割り込みが来るまで待つ。読み込む時は受信割り込みが来たときに1byteづつ読み込んでいたデータを返すだけ。
MochiKernelのメッセージパッシングはキューがなく、即座にメッセージ受信をしないと仮想ファイルサーバがブロックされてシステムの性能が悪くなってしまうので、メインと受信と転送用に1プロセス3スレッド構成に。
(MochiKernelにスレッド機能なんて無かったので、作った。)
とまぁ、これだけでかなりのネタになるんだけれど、割愛。
⇂がコミットログ。
https://github.com/MasterMochi/drv-ns16550/commit/a09994d07188ec84b663b902f6dbc07509cc44de
本題はこれから。
ttyサーバを作りたいが…
tty「サーバ」って書くと???になるのだけれど、要はttyドライバです。MochiOSではサーバープロセスとしてttyファイルを提供するので「サーバ」にしているだけです。
そんで考えたのだけれど、次のシーケンスで悩みが出てくる。
- ユーザアプリがttyサーバに行読込み(cockedモード)
- ttyサーバがドライバからデータ読込み
- 受信データ無しのため、読込サイズ0で応答。
(シーケンス図では、仮想ファイルサーバは省略。それぞれのインタフェースは仮想ファイルサーバ上で行われる。そのためVfsRead…Readのような形式で記載。上位からはReadを起動し、それを受け取って仮想ファイルサーバから下位へVfsReadが起動される。)
ttyサーバは行データが揃うまでユーザアプリへRead要求を返さない。行データが揃うまで、ドライバから文字を読み続けなければいけないわけだけど、ドライバは受信データが無い(EOF)ので直ぐに読込サイズ0でReadを返す。
(ところが上のコミットではドライバがブロックする設計ミス。。。修正する。)
今、実装済みの機能でこれを実現するには、ttyサーバはドライバへのReadを繰り返すしかない。
これは、もう、CPU100%一直線。
Select/VfsReady機能を追加する
説明しなくても大体わかると思うけど、selectです。指定したファイルディスクリプタの読み込みまたは書き込みが出来るまで待ち合わせます。
VfsReadyはファイルの読み込みまたは書き込み準備が出来た事を意味する通知。
いちいちSelectで指定した全てのFDに対応するMountプロセスにレディ状態を問い合わせると、メッセージのやり取りが増えて待ち合わせ状態の管理や時間がかかるので、レディ状態は仮想ファイルシステムでも保持する仕様にした。その為、VfsRead応答に最新のレディ状態を含める様に修正する。
以下、メッセージ仕様。
■ Select要求メッセージ
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0009 | Select |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0000 | 要求 |
0x08 | 4 | 読込監視グローバルFD数 | 0~1024 | - |
0x0C | 4 | 書込監視グローバルFD数 | 0~1024 | - |
0x10 | 4 | 読込監視グローバルFD[0] | 任意 | - |
… | … | 読込監視グローバルFD[…] | … | … |
可変 | 4 | 書込監視グローバルFD[0] | 任意 | - |
… | … | 書込監視グローバルFD[…] | … | … |
■ Select応答メッセージ
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0009 | Select |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0001 | 応答 |
0x08 | 4 | 処理結果 | 0x0000_0000 0x0000_0001 |
成功 失敗 |
0x0C | 4 | 読込レディグローバルFD数 | 0~1024 | - |
0x10 | 4 | 書込レディグローバルFD数 | 0~1024 | - |
0x14 | 4 | 読込レディグローバルFD[0] | 任意 | - |
… | … | 読込レディグローバルFD[…] | … | … |
可変 | 4 | 書込レディグローバルFD[0] | 任意 | - |
… | … | 書込レディグローバルFD[…] | … | … |
■ VfsReady通知メッセージ
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0008 | vfsClose |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0002 | 通知 |
0x08 | 4 | グローバルFD | 任意 | - |
0x0C | 4 | Ready対象 | 0bit目: read 1bit目: write |
読込みレディ 書込みレディ |
■ vfsRead応答メッセージ(改造)
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0006 | vfsRead |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0001 | 応答 |
0x08 | 4 | グローバルFD | 任意 | - |
0x0C | 4 | 処理結果 | 0x0000_0000 0x0000_0001 |
成功 失敗 |
0x10 | 4 | 読込レディ状態 | 0x0000_0000 0x0000_0001 |
非レディ レディ |
0x14 | 4 | 読込み実施サイズ | 0~24,064 | - |
0x18 | 0~24,064 | データ | 任意 | - |
■ vfsWrite応答メッセージ(改造)
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0004 | vfsWrite |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0001 | 応答 |
0x08 | 4 | グローバルFD | 任意 | - |
0x0C | 4 | 処理結果 | 0x0000_0000 0x0000_0001 |
成功 失敗 |
0x10 | 4 | 書込レディ状態 | 0x0000_0000 0x0000_0002 |
非レディ レディ |
0x10 | 4 | 書込み実施サイズ | 0~24,064 | - |
実装してみた
ttyプロセスが、select->read->writeを無限に繰り返す様にお試し。COM1で「1234567890Select!」を入力してみた。上のウィンドウは画面でデバッグログを、下のウィンドウはCOM1。端っこ切れてる。。
深く説明はしないけど、まぁCPU100%にならずに読込み待ちできたって感じです。
ここで問題発生
これまで、突貫で適当に作りすぎてて、機能毎に複数の要求を扱えない。
なので、ttyファイルをReadするとその先のドライバファイルのReadが行えない状況に。。。
直さねば。全体的に大改造なので、次回の更新はいつになるかな。
コメント
コメントを投稿