2017-01-26 2 views
1

i2cに接続された温度/圧力計のデバイスドライバを作成しています。ノンブロッキング低速サンプリングセンサードライバの正しいインタフェース

センサーを操作するには、最初に新しい読み取り値を要求します。センサーは、一定期間にわたって必要なサンプリングを行い、最後の読み取り値を報告します。このプロセスには時間がかかることが予想されます。

ユーザ空間は、ファイルベースのreadとおそらくioctlを使用してキャラクタデバイスインタフェースを使用してデバイスドライバに接続することが予想されます。

ユーザースレッドが読み取りを試み、センサーの読み取りを報告できるまでブロックされたままになっているブロッキングインターフェイスを簡単に作成できます。

サンプリングに時間がかかることが予想されるため、ドライバを非ブロッキングモードで動作させたいと考えています。ユーザースレッドは、サンプリングが完了するまで、他の処理を実行するか、poll/selectでブロックすることができます。

問題は、ドライバのサンプリングを開始するように指示するにはreadが必要ですが、サンプリングが完了してノンブロッキングモードになるまでドライバはreadを完了できず、ドライバはこれらの2つの間でスレッドをブロックできません状態。

さらに、この操作を実行するために呼び出されるカーネルコールの数を最小限に抑えたいと考えています。私はまた、貴重な力が不要なサンプリングで無駄にならないようにする必要があります。

これを実行するための正しいLinuxパターンは何ですか?

アップデート:私は実装の詳細には興味がありませんが、私が実際にやっているのは、良い習慣に従ったユーザー/カーネルインターフェイスの設計です。

+1

[LDD3](https://lwn.net/Kernel/LDD3/)、[チャプター6(PDF)](https://lwn.net/images/pdf/)でサンプルの文字ドライバーを確認しましたか? LDD3/ch06.pdf)特に?私は個人的に 'read()'や 'lseek()'がデータ収集を開始し、通常の 'read()'ブロッキングがその期間中ブロックされていることを示唆しています。 (呼び出したプロセスに何もする必要がないかもしれないので、これは自然かもしれません) 'O_NONBLOCK'の場合、データが利用可能になるまで、最初の読み込みは' -EWOULDBLOCK'を返します。 'SIGIO'とポーリングをサポートしています。 LDD3の本は、これらすべてを詳細に説明しています。 –

+0

どの湿度計センサーですか?あなたは完全なコードをどこかに投稿できますか(githubなど)?私は最近、この種のコードをたくさん書いていて、興味があります。 – stevieb

答えて

0

オープンメソッドでセンサー使用作業キューまたは他の非同期プリミティブに必要なサンプリングを行います。仕事関数では、デバイスにポーリングを通知するためにwait_queueを使用できます。

work_function() 
{ 
    /*perform the necessary sampling*/ 
    /*after done, use wait queue to notify poll the device is readable.*/ 
} 
DECLARE_WORK(name, work_function, data); 

static int open(struct inode *inode, struct file *filp) 
{ 
    /*do other stuff....*/ 
    queue_work(.......); 
} 

static unsigned int scull_p_poll(struct file *filp, poll_table *wait) 
{ 
    poll_wait(filp, &dev->outq, wait); 
    ....... 
    return mask; 
} 

LDD章7意志役立つ:openメソッドで

+0

あなたが言っているのは、私がオープンで測定を開始するということです。読み込み前に開いてから長い待ち時間がある場合、古いデータが出ている可能性があります。 – doron

+0

実際には、ポーリングもプロセスを待つだけで、複数のfdを監視できます。 SIGIOのほうが良い解決策@doron –

+0

投票のプロセスを開始するのはメリットがありますが、唯一の未解決の問題は古いデータについて何をするかです。 – doron

関連する問題