読者です 読者をやめる 読者になる 読者になる

Tech と Culture

テクノロジーとカルチャー

デバイスドライバ

AHBインターフェースが、現在のもので良いのか分からないため、デバイスドライバの勉強をしていました。

O'Reilly の Linux デバイスドライバ 第3版 を分からないなりに必死になって読みました。
なんとなくデバイスドライバというものがどういうものなのか程度は見えつつあります。以下は素人なりに感じた所。

デバイスドライバの開発が通常のアプリケーション開発とは全然異なるというのは、平行動作を意識したプログラムを行う必要があるためのようです。
例えば、あるデバイスに書き込む関数内で、デバイスが準備できていないときには、準備ができるまで自分自身をスリープして、他のプロセスにCPUを渡したりします。割り込み、または他のデバイスドライバがスリープから目覚めさせます。ここら辺をきちんと設計しないと、二度とプロセスが起きることがなくなりデッドロックを起こします。またスリープしている時に他のプロセスがデバイスにアクセスする可能性があります。この時に整合性をとる必要があります。

これまでの自分の感覚では、ハードウェアは平行動作なので、徹底的に机上でミスの無いように検討しつくして設計しますが、ソフトウェアは順序良く動作が流れていくので、ハードウェア程深く検討せずにコーディングしながら考えたりしていました。
しかし、デバイスドライバは想像していない平行状態や競合状態が発生しそうで、かつ発生した時にデッドロックや暴走で終わってしまう模様です。
これは相当やっかいなしろものだなと感じました。

しかし、motionJPEGの開発では、デバイスにアクセスするアプリが一つですので、難しい状態は発生しないと考えられます。
そうすると考慮するべき点は以下のことかなーと思っています。
(1) ハードウェアが直接メモリを書き換える部分でのメモリの内容とキャッシュの整合性
(2)プログラム側の仮想アドレスとメモリの物理アドレスの変換
(3)性能

1,2をしっかりすれば、とりあえず動くものはできるはずです。
性能については、本を読んでいるとデバイスドライバに制御が移った時にコンテキストスイッチが発生するそう(当たり前か)。そうすると、1pixel毎にデバイスドライバをコールしていると相当な性能劣化が起きてしまいそうです。ある程度FIFOの容量をとって、まとめて送るべき。
また、データをモジュールに送ることは実はデバイスドライバを書かずともできるらしい。最初はここからコーディングしていくのが正攻法のような気がしました。

未だに良く分からないのが、割り込みの使い方。
バッファをもつデバイスに書き込む時は、書き込めないときはスリープして書き込める状態になったら割り込みで起こしてもらうのが常套手段の模様(これをブロック動作と呼ぶらしい。書き込めない時にエラーを返すのが非ブロック動作。どちらか選べる)。
とりあえずはアプリケーション側でポーリングしてもmotionJPEGしか動いていないので問題はないのですが、、、、、、
アプリケーションプログラム側でポーリングするとシステム設計の勉強にならない気がします。
しかし、モジュールがメモリに書き出すバスも同じ周波数で動いているAHBですので、いちいち割り込みかける方がオーバーヘッドが大きすぎる気もする。
割り込み線を不法アクセスに使っていますが、FIFO EMPTYに使うべきなのだろうか???

ここら辺の感覚が未だ分からず、、、、、
まあ、ここら辺の感覚とバス構造の設計を掴むのがシステム開発の肝だと思いますので、それを勉強したくてやっているので当たり前です。

(そもそもmotionJPEGにLinux自体が必要ないですし、本当はプロセッサも必要ないような気もします。)