2017-06-08 2 views
1

私は、hid rawデバイスに定期的に問い合わせる必要のあるカーネルモジュールを作成しています。 私はhrtimerと簡単なタイマーを試しました。私はhid_hw_raw_requestと呼ぶたびに"BUG: scheduling while atomic"を得ました。カーネルモジュールで定期的にhid_hw_raw_requestを実行する方法は?

私のタイマー機能(例えばinit)の外で同じ機能を試しても、問題なく動作します(バグはありません)。

バグを発生させることなくこの機能を定期的に呼び出す方法はありますか?

答えて

0

hid_hw_raw_requestを遅延作業として発行するには、作業キューを使用する必要があります。これは、次の例のモジュールのように行うことができます。

#include <linux/kernel.h> 
#include <linux/module.h> 
#include <linux/workqueue.h> 

static void hid_work_handler(struct work_struct *hid_work); 

static struct workqueue_struct *hid_workqueue; 
static DECLARE_WORK(hid_work, hid_work_handler); 

static void hid_work_handler(struct work_struct *hid_work) 
{ 
     ... 
     hid_hw_raw_request(...); 
     ... 
} 

static int __init hid_work_init(void) 
{ 
     if (!hid_workqueue) 
       hid_workqueue = create_singlethread_workqueue("hid_workqueue"); 

     if (hid_workqueue) 
       queue_work(hid_workqueue, &hid_work); 

     return 0; 
} 

static void __exit hid_work_exit(void) 
{ 
     if (hid_workqueue) { 
       flush_workqueue(hid_workqueue); 
       destroy_workqueue(hid_workqueue); 
     } 
} 

module_init(hid_work_init); 
module_exit(hid_work_exit); 

MODULE_DESCRIPTION("hid_work_test"); 
MODULE_LICENSE("GPL"); 

注意実際の実装のためにあなたがキューイングされる含まのstruct work_structを使用して独自のデータ構造体を作成する必要がありますということ。このデータ構造体には、hiddev、バッファなどが含まれている可能性があります。hid_work_handlerが実際の転送を行う必要があります。詳細については、第7章を参照してください(コールの構文は古くなっていますが、基本的な説明はそのまま適用されます)。

+0

こんにちは、ありがとうございました詳細な回答!私は一生懸命お試しになりますが、私が探していたものと全く同じです! – AlexJ

関連する問題