faxdfjk
2022年12月28日 16時39分
デバイスドライバ内から別のデバイスを open() しようとするとコンパイルエラー(下記)がでてしまいます。
#inclide は入れています。
error: implicit declaration of function ‘open’ [-Werror=implicit-function-declaration]
if( 0 < (fd = open(device, O_RDWR))){
^~~~
Q1 ドライバ内から別のドライバは扱えるのでしょうか。
Q2 可能ならインクルードさきはどのように指定すると良いのでしょうか。
以上よろしくお願いいたします。
コメント
faxdfjk
at_ohsawa
デバイスドライバを書くモチベーションとしては、他のプロセスへのスケジュールや
割り込みを止めてでもアクセスタイミングを守りたい場合や、PCIeやMIIのように下層の
バスのデバイスドライバに対してユーザー空間からのアクセスがしずらかったり
ネットワークインターフェース等の標準的なインターフェースがあるので、そこに機能を
提供したい場合だと思います。
i2c, uart, spi, usb等はユーザー空間からアクセスする便利なデバイスファイルや
ライブラリもあるので、内々でユーザーランドのソフトを書くようなプロダクトの場合は、
必ずしもデバイスドライバにする必要は無いことが多いです。
(むしろユーザーランドならバグを入れてもカーネルがクラッシュせず動作継続するので、
エラー確認してリトライやrebootする処理を後付けするなど対処可能になり、システムの安定が良くなります。)
学習には、個人的には他のデバイスドライバのコードを読むことと、先述のカーネルソースコード
ツリー内のDocumentationディレクトリの文書を読むのが一番確実な情報だと思っています。
書籍は20年近く前でかなり古く、既にインターフェースが異なりますが
オライリーの「Linuxデバイスドライバ 第3版」が日本語翻訳を読んだことがあります。
また、デバイスドライバ開発を扱った書籍は存在しているので、そういったものを一読
された方が全体像や、できる・できないことが総覧しやすいと思います。
(先のタイミングの話以外にも、注意すべき点が多数ありすぎて個別には回答できないため
そういう面で書籍は良い選択だと思います)
ただし、構造やAPIはkernelの世代によって異なるため書籍は間違いなく追いつきません、
やはり既存のコードとDocumentationの参照は必要です。
at_ohsawa
2022年12月28日 16時52分
> デバイスドライバ内から別のデバイスを open() しようとするとコンパイルエラー(下記)がでてしまいます。
> #inclide は入れています。
>
> error: implicit declaration of function ‘open’ [-Werror=implicit-function-declaration]
> if( 0 < (fd = open(device, O_RDWR))){
> ^~~~
>
> Q1 ドライバ内から別のドライバは扱えるのでしょうか。
> Q2 可能ならインクルードさきはどのように指定すると良いのでしょうか。
そもそもopen()はファイルシステム上のファイルを開くAPIなので
ユーザーランド上でやることで、デバイスドライバでやることではありません。
デバイスドライバで別のデバイスドライバにアクセスしたい場合は、
別のデバイスドライバをincludeしてアクセスすることになります。
drivers/i2cとそれを使うdrivers/i2c/chipの関係をみると分かると思います。
ただし、その”別のドライバ”の仕様次第でアクセスして良いタイミング
(参照できないシーケンスに入っているときにポインタに触ると当然
メモリ参照エラーでクラッシュします)や型の仕様を守る必要があります。
当然ですがuserlandでopenするのと異なり、kernelが止まるので、
再現性の悪いミスをするとデバッグが困難になります。
本当にデバイスドライバを書く必要があるか検討してみてください。
他にincludeしたいドライバがあるのであれば、そのドライバによって
既にdevice fileが存在しているはずで、そこにアクセスする普通の
アプリケーションを書けば十分ではないでしょうか?