2018/10/13

デバイスドライバを書いてみよう01 デバイスドライバって何?

IoT的なものづくりをしていると簡単なものはGPIOなどから信号を出して制御するが、複雑になるとデバイスドライバを書いた方がいい場合がある。
規模が大きくなりがちなので、なんでもかんでもドライバを書くのはよくないのだが、必要な場合はある。

今回は、そもそもデバイスドライバって何?という疑問に対する説明をしたい。


デバイスドライバの説明としては
「デバイスを動かすためのソフトウェアである」
に尽きる。

でも実際のところどんなソフトウェアなのか?
どうやってドライバを作るのか?アプリと同じようにプログラムがかけるのか?という疑問が出てくる。
様々なOSに対して実装されるドライバだが、大体の構成は同じなので整理してみる。

構成


デバイスドライバの話をするのに厄介なのは、ソフトウェア構成とハードウェア構成が入り混じる点だ。
それぞれを整理する。



ハードウェアはPCとデバイスだが、もう少し細かくみると
  • CPU
  • メモリ
  • デバイス
となる。
まあ本当はマザーボードなんかもあるけど、今回はドライバに関係のある主要な部品に限る。



ソフトウェアは
  • OS(カーネル)
  • デバイスドライバ
  • アプリケーション
となる。
OSはWindowsとかLinuxとかだよね。
アプリケーションはWordとかPhotoShopとか、多くの人によって作られているOS上で動くソフトウェア。
あとは今回説明するデバイスドライバ。

PC部品やソフトウェアモジュールは他にもいろいろあるが、今回関係あるものだけ挙げた。

ハードとソフトの関係


そもそも、なんでデバイスドライバはアプリケーションと分けて語られるのだろうか?

アプリケーション用のAPIでは、ハードウェアを直接操作することはできない。
「え?メモリは操作できるよ?」と思うかもしれないが、あれも直接操作しているわけではなく、一度OSがそのアプリケーション用に切り分けたメモリ区画にOSを介してアクセスしている。その区画以外には操作ができない。操作しようとするとアプリケーションが異常終了する。
ハードウェアにつながるプログラムのエラーは割と致命的な問題になるので、OSがクラッシュしないように保護をする必要がある。そのため、このようなアクセス制限がかかっている。
アプリケーションの製作者は星の数ほどいるので、必然的に質の悪いものが含まれる可能性は高くなる。そのため、PCの他の機能に影響を与えないよう、個々のアプリケーションには制限や保護がなされている。

逆に言えば、ハードウェアを操作するドライバはアプリケーションと同じ枠組みでは実行されない。よりOSに近い部分で実行する必要がある。

少し語弊があるがアプリケーション開発者にわかりやすく例えると、下記のようになるだろうか。

  • OSはPC起動時に最初に実行される大きなプログラム
  • アプリケーションはOSというプログラム上の仮想環境で動くプログラム
    仮想環境上なので、おかしな操作をしても大元のプログラム(OS)は落ちない。
  • デバイスドライバは、OSに組み込むプラグイン
    プラグインなので、OSと同じプロセスで動く。ただクラッシュするとOSも落ちる。

まとめると
  1. OSはいろいろなハードウェアを直接操作できるが、クラッシュすると影響大(PCクラッシュなど)。
  2. アプリケーションはハードウェアを直接操作できないが、クラッシュしても影響小。
となる。

あっさり言ってしまうと、ドライバは上記1の範疇で動くプログラムを作ることができる、というものだ。
ちなみに1のようにOSの空間で動くプログラムは、「カーネルランド」や「カーネル空間」で動くプログラムと呼ばれ、2は「ユーザランド」「ユーザ空間」で動くプログラム、と呼ばれる。
アプリケーションプログラマはユーザ空間で動くプログラムを作っている、というわけだ。

できることとそれに伴うリスクはトレードオフ。ドライバはデバイスを操作できるがリスクが高い。
最近のドライバ開発環境はこの中間みたいになっているんだけど、原則的にはドライバとアプリケーションはこんな違いがある。

実際のデータのやり取り




アプリケーションはデバイスを直接操作できないので、デバイスドライバを介してデバイスを操作する。
アプリケーション側に公開されるデバイスドライバの関数群が、そのデバイスを扱うAPIとなるわけだ。

デバイスドライバとデバイスはUSBなどのインターフェースを通してデータを送受信する。
ゲームのコントローラを例に挙げてみよう。例えば、通常のコントロール操作ができて、かつコントローラにはLEDが付いており、ゲーム内で何かしらの異常があるとLEDは赤色に発色する、とする。まぁよくある仕様だ。
この場合、コントロール操作情報はデバイスからPCに送信される。LEDを光らせる命令は、PCからデバイスに送信される。つまり、デバイスとPCは双方向通信ができなければならない。
このデバイスとPCのデータのやり取りは結構複雑なのでまた後ほど説明したい。

アプリケーションからドライバとやり取りを行うにはOSのAPIを呼び出す。上の図にさらっと矢印が描いてあるが、アプリケーションから抽象化されたOSのAPIを呼び出すことで、色々なデバイスドライバとやり取りできるような設計になっている。
例えばコントローラの操作情報を読み取る場合はOSのread API、LEDを光らせるためにはwrite APIを呼び出し、対象にゲームコントローラのドライバを指定する、といった感じでデバイスを操作する。


今回はデバイスドライバの立ち位置や仕組みを簡単に説明した。
次回はもう少し細かいデータのやり取りなどを説明したい。



0 件のコメント:

コメントを投稿