Linux kernel 在内核模块中定期隐藏硬件原始请求,如何?
我正在编写一个内核模块,需要定期询问hid原始设备。 我尝试了hrtimer和一个简单的计时器,每次调用hid_hw_raw_请求时,我都会遇到一个BUG:原子时调度 如果我在计时器函数之外尝试相同的函数,例如在init中,它可以正常工作,没有bugLinux kernel 在内核模块中定期隐藏硬件原始请求,如何?,linux-kernel,scheduling,atomic,Linux Kernel,Scheduling,Atomic,我正在编写一个内核模块,需要定期询问hid原始设备。 我尝试了hrtimer和一个简单的计时器,每次调用hid_hw_raw_请求时,我都会遇到一个BUG:原子时调度 如果我在计时器函数之外尝试相同的函数,例如在init中,它可以正常工作,没有bug 如何定期调用此函数而不产生任何错误?您需要使用工作队列来发出hid\u hw\u raw\u请求作为延迟工作。这可以在以下示例模块中完成: #include <linux/kernel.h> #include <linux/mod
如何定期调用此函数而不产生任何错误?您需要使用工作队列来发出hid\u hw\u raw\u请求作为延迟工作。这可以在以下示例模块中完成:
#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");
请注意,对于真正的实现,您需要创建自己的数据结构,其中包含要排队的结构work\u struct。此数据结构可能包含hiddev、缓冲区等,hid_work_处理程序需要这些数据结构来执行实际传输。有关更多详细信息,请参见LDD3第7章,尽管调用的语法已经过时,但基本解释仍然适用 您需要使用工作队列将hid_hw_raw_请求作为延迟工作发出。这可以在以下示例模块中完成:
#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");
请注意,对于真正的实现,您需要创建自己的数据结构,其中包含要排队的结构work\u struct。此数据结构可能包含hiddev、缓冲区等,hid_work_处理程序需要这些数据结构来执行实际传输。有关更多详细信息,请参见LDD3第7章,尽管调用的语法已经过时,但基本解释仍然适用 您好,非常感谢您详细的回答!我会尽快尝试,但它看起来正是我所寻找的!您好,非常感谢您详细的回答!我会尽快尝试,但它看起来正是我所寻找的!