ハード制御というと何やら難しいように思えるかもしれません。
しかしLinuxなどに付属しているデバイスドライバーのソース(例えばRS232Cシリアルドライバー等) を見てみるとたいていはC言語で数百行~数千行程度のプログラムで意外にシンプルな構成で 驚かれると思います。
ただし、コードをよく見るとソフトウェアアルゴリズム上で理解しにくいコードが含まれていて、 少々とっつきにくかったりもします。
特にデバイスドライバーのハード制御の部分に特化して説明したいと思います。
メモリマップドIOとポートマップドIO
ハード制御を行うにはハードレジスタに対してデータを入出力して制御指示を与える必要があります。 ハードレジスタに対するデータの入出力方法として、 メモリマップドIO方式とポートマップドIO方式の2つがあります。
1.メモリマップドIO
文字通り、メモリ空間に割り当てられたハードウェアレジスタに対してハード制御の指示を送る方式です。 C言語上ではポインタ変数に対するアクセスそのものであり、 アセンブラレベルで見ても処理上は単なるメモリに対するアクセスと区別がありません。
メモリ空間上のどのアドレスにハードレジスタを配置するのかはハード設計に依存します。 通常の開発プロジェクトではハード仕様書というものが用意されていて、 そこにハード制御用レジスタのマッピングアドレスやビットアサイン情報が網羅されています。
C言語のコード例
#define DMA_SEND_ADDR_REG (0x10000000) /*データ転送アドレス設定レジスタ*/
#define DMA_OPERATE_REG (0x10000004) /* DMA制御レジスタ */
#define DMA_LENGTH_REG (0x10000008) /* データ転送長設定レジスタ */
#define DMA_OPERATE_TYPE_RECV (0x1) /* 転送コマンド定義 */
static BYTE buf[1024];
*DMA_TRANSFER_REG = &buf[0]; // データ受信したいアドレスをセット
*DMA_LENGTH_REG = 1024; // データサイズを指示
*DMA_OPERATE_REG = DMA_OPERATE_TYPE_RECV; // デバイスへ指定メモリへデータ転送するように指示
データ転送完了は割り込みによって通知されるか、もしくはハードレジスタのステータスをポーリングして知ることができます。
とてもシンプルなC言語のポインタ変数アクセスでハード制御を実現できます。ただし、データ転送アドレスはハードウェアによって「物理アドレス=論理アドレス」のような制限があるかもしれませんので注意が必要です。多くの処理系ではハードレジスタのアドレス領域は特権モードでないとアクセスできない領域に配置されますので、一般アプリケーションで上記のようなコードを組むとメモリアクセス例外で落ちます。一般アプリケーションではなくデバイスドライバーを開発する必要があります。
2.ポートマップドIO
CPUに備わった専用のデバイス入出力ポートにアクセスすることでハード制御を行う方式です。アセンブラでは(Z80CPUの場合)IN/OUTといった専用の外部デバイスへの入出力命令が備わっており、その命令を実行することによりハード制御を行います。
ドライバー専用の開発環境ではインラインアセンブラでハードウェア制御を行うマクロ定義を使ったりしますが、あらかじめポート入出力の命令を予約語のように定義してくれているケースがあります。
そのため、通常はわざわざCPUのインストラクションセットを調べて、「このデバイスの制御命令は…?」のような調査をしなくても、定義済み予約語もしくはマクロを使ってデバイス制御を行えます。
ポート制御処理を予約語のように定義しているドライバー開発環境のコード例:
PM0 = 0x0000;
上記のアセンブラコード:MOV PM0, 0x0000
入出力ポート0番が汎用レジスタのように割り当てられており、アセンブラのMOV命令に解釈されてコンパイルされます。
入出力ポートの定義:PM0→全部大文字でマクロのように見えるのは、単なる変数と混同しないような工夫でしょうね。
- 特に2つの方式にソフト的な優劣はありませんが、メモリ空間が限られている小規模なアーキテクチャではポートマップドIOがよく使われます。
- 最近のCPUではメモリ空間が広くなり、メモリアドレス領域を圧迫することがないため、メモリマップド方式が主流となりました。しかし、まだまだポートマップドIO方式も健在です。
- 上記の説明やコード例でわかると思いますが、デバイス制御プログラムは極めてC言語との親和性が高いです。
ほとんどのデバイスドライバーはC言語で書かれているといっても過言ではないと思います(もしくはアセンブラか…)。まあ、HTMLでデバイスドライバーを開発する例はなさそうですね。
そもそもポインタを使って物理アドレスに直接アクセス可能な言語というものが他にないですから…。とてもニッチな市場ですが、一定の割合でC言語の開発業務は無くならないわけです。
ただし、スクラッチで新規開発というのは無くなり、過去コードの流用開発が増えていそうです。何をやっている処理なのかしっかり読めないと、これから先、年配技術者の引退によりメンテナンス不可のロストテクノロジーになってしまうかもしれません。少し話が長くなってしまいましたので、次回に続きます(3部作くらいになりそうです)。