はじめに
デバイスドライバはハードウェアを制御するソフトウェアです。C言語だけを学んだ方は、ハードウェアを制御するとしてもライブラリ等を使用するので、その実態を知らない状態だと思っています。本章ではデバイスドライバが、どのようにハードウェアを制御しているかを説明します。
ハードウェアを制御する仕組み
C言語で記載したソースコードをコンパイルすれば、アセンブラの機械が理解できるコードになります。ただし、このアセンブラに、全てのデバイスを制御する為の命令セットが用意されている訳ではありません。それでは制御できるデバイスを増やす度に、命令セットを追加する必要があり複雑になりすぎます。その為、多くのCPUは、メモリマップドI/Oという手法を用いて、デバイスの制御を行います。32bitのCPUであれば2の32乗である4Gbyteのメモリ空間をRead/Write可能です。メモリ空間にRAMを割り当てCPUはアクセスしますが、RAM以外にもデバイスを制御する為のレジスタを割り当て、RAMにアクセスするのと同じようにレジスタにアクセスし、デバイスを制御します。
例えば、0x10000000番地に、1を書き込むと、デバイスのA機能を有効にできる。0x10000004番地を読み込むと、デバイスのA機能が有効になっているか分かる等になります。このレジスタが、ソフトウェアとハードウェアを分けた時の分かれ目で、ハードウェアから提供されるソフトウェアへのインターフェースになります。
蛇足になりますが、昔の32bitのCPUを使用しているパソコンは、2の32乗である4Gbyteでは無く、3Gbyte程度以上のRAMを認識できませんでした。これは、4Gbyteのメモリ空間を、すべてRAMに割り当てることはできず、レジスタ等に割り当てる必要があった為です。
接続デバイスを制御する仕組み
次に、レジスタに全てのデバイスを制御する為のインターフェースが用意されているのか。これは、SoC(System on a Chip)の観点から考えると正しいと言えるかもしれません。SoCは、CPUを含んだシステムの動作に必要な機能を、1つの部品に入れ込んだ部品です。SoCの機能は基本的にレジスタのRead/Writeで制御可能です。しかし、SoCの外に接続するデバイス、例えば照度センサデバイスを制御する為のレジスタが、全て用意されている訳ではありません。接続できるデバイスは無数にあり、レジスタにそれらの制御を全て追加していくのは不可能です。
では、SoC上で動くデバイスドライバは、どうやって外に接続しているデバイスを制御しているのでしょうか。この答えは、バスを通して信号を送り01のデータを送ることで、デバイスに命令して制御しているになります。パソコンを使用している方の、もっとも身近なバス規格は、USB(ユニバーサル・シリアル・バス)だと思います。USBのように、電子機器の中には、SoCと多くのデバイスがコネクタで繋がっており、データをやり取りをすることで動作しています。デバイスドライバはレジスタをRead/Writeすることによって、SoCから信号を出すことで、接続しているデバイスを制御しているのです。このバス規格は、大きく調歩同期式とクロック同期式に分かれます。USBは調歩同期式、今回読み解くセンサドライバとの接続方式であるI2Cはクロック同期式となります。以下に「1010」のデータを送っているイメージ図を示します。
クロック同期式では、クロック信号でタイミングを合わせて、その時にデータ信号がどうなっているかで、データが0か1かを判断します。
コメント