c - 无法释放键盘 irq 线路:设备或资源忙
问题描述
我正在编写一个示例 request_irq 代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
int irq = 1;
int dev = 0xaa;
static irqreturn_t keyboard_handler(int irq, void *dev)
{
static int counter = 0;
pr_info("Keyboard Counter:%d\n", counter++);
return IRQ_NONE;
}
static int test_interrupt_init(void)
{
pr_info("%s: In init\n", __func__);
return request_irq(irq, keyboard_handler, IRQF_SHARED,
"my_keyboard_handler", &dev);
}
static void test_interrupt_exit(void)
{
pr_info("%s: In exit\n", __func__);
synchronize_irq(irq);
free_irq(irq, &dev);
}
module_init(test_interrupt_init);
module_exit(test_interrupt_exit);
删除此模块时,我收到错误消息:
rmmod: ERROR: ../libkmod/libkmod-module.c:769 kmod_module_remove_module() could not remove 'interrupt': Device or resource busy
rmmod: ERROR: could not remove module interrupt: Device or resource busy
为什么我收到此错误,因为我正在使用 IRQF_SHARED 并在 request_irq 和 free_irq 中传递了 dev 参数
更新:从 dmesg,我在 rmmod 上看不到任何 printk 添加了 dmesg 日志:
[ 4007.223281] Keyboard Counter:884
[ 4007.560846] Keyboard Counter:885
[ 4007.670339] Keyboard Counter:886
[ 4008.240139] Keyboard Counter:887
[ 4008.275412] Keyboard Counter:888
[ 4008.359338] Keyboard Counter:889
[ 4008.425101] Keyboard Counter:890
[ 4008.433026] Keyboard Counter:891
[ 4008.501763] Keyboard Counter:892
[ 4008.579201] Keyboard Counter:893
[ 4008.653335] Keyboard Counter:894
[ 4008.682862] Keyboard Counter:895
[ 4008.733950] Keyboard Counter:896
$ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 1 0 0 0 IO-APIC 2-edge timer
1: 449 0 0 707 IO-APIC 1-edge i8042, my_keyboard_handler
6: 0 0 2 0 IO-APIC 6-edge floppy
7: 0 0 0 0 IO-APIC 7-edge parport0
8: 0 1 0 0 IO-APIC 8-edge rtc0
9: 0 0 0 0 IO-APIC 9-fasteoi acpi
解决方案
尝试这个:
static int irq = 1, dev = 0xaa;
您需要授予变量权限irq
,然后module_param()
像下面这样调用
module_param(irq, int, S_IRUGO);
示例代码
MODULE_LICENSE("GPL");
static int irq = 1, dev = 0xaa, counter = 0;
module_param(irq, int, S_IRUGO); /* give the permission to user space variable */
static irqreturn_t keyboard_handler(int irq, void *dev)
{
pr_info("Keyboard Counter:%d\n", counter++);
return IRQ_NONE;
}
/* registering irq */
static int test_interrupt_init(void)
{
pr_info("%s: In init\n", __func__);
if(request_irq(irq, keyboard_handler, IRQF_SHARED,"my_keyboard_handler", &dev)) {
return -1;
}
else
{
pr_info("success \n");
return 0;
}
}
static void test_interrupt_exit(void)
{
pr_info("%s: In exit\n", __func__);
synchronize_irq(irq); /* synchronize interrupt */
free_irq(irq, &dev);
}
module_init(test_interrupt_init);
module_exit(test_interrupt_exit);
推荐阅读
- javascript - 验证字符串的正则表达式是否被 HTML 标记包围
- laravel - Laravel 5.7 - 如何使用 axios.get 从 API 检索数据?
- react-native - react native如何在材质日期选择器中实现材质文本输入?
- dns - CNAME 记录是否公开
- ruby-on-rails - 收听另一个 rails actioncable 服务器
- c++ - C++ 方法中的静态变量
- laravel - 在 Laravel 中从模型中添加多个 Where 子句
- lstm - RuntimeError: Expected hidden[0] size (2, 20, 256), got (2, 50, 256)
- java - 删除所有不起作用的java换行符(如emacs所示)
- c - 以下代码如何出现堆栈粉碎错误?