request_irq函数功能描述:函数request_irq( )在实现过程中调用了函数request_threaded_irq( ),实现动态地申请注册一个中断。函数request_threaded_irq( )首先对传入的参数进行安全检查,根据传入的irq号获得数组irq_desc中以irq为下标的元素,然后动态地创建一个irqaction描述符,根据传入的参数初始化新生成的irqaction描述符,最后调用函数__setup_irq( )把该描述符加入IRQ链表中,完成中断的动态申请及注册。
request_irq文件包含
#include<linux/interrupt.h>
request_irq函数定义
在内核源码中的位置:linux-3.19.3/include/linux/interrupt.h
函数定义格式:
static inline int __must_check request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}
request_irq输入参数说明
函数输入参数与函数request_threaded_irq( )基本相同,参考函数request_threaded_irq( )。
request_irq返回参数说明
如果返回值是0则说明申请成功,如果申请不成功,则返回的值非零,一般为负数,可能的取值-16、-38,例如如果返回值是-16,则说明申请的中断号在内核中已被占用。
request_irq实例解析:
编写测试文件:request_irq.c
头文件引用及全局变量定义:
#include <linux/interrupt.h>
#include<linux/irq.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int irq=10; //16
中断处理函数定义:
// 自定义中断处理函数
static irqreturn_t irq_handler(int data, void *dev_id)
{
printk("the data is :%d\n", data); //data是对应中断的中断号
printk("in the interrupt handler function\n");
return IRQ_HANDLED;
}
模块加载函数定义:
static int __init request_irq_init(void)
{
int result=0;
printk("into request_irq_init\n");
/*调用函数request_irq( )申请中断,irq指中断编号,myhandler是中断处理函数,IRQF_DISABLED
是中断类型,“A_New_Device”指中断设备名,NULL指设备,设备为NULL说明设备不真实存在*/
result=request_irq(irq, irq_handler, IRQF_DISABLED, "A_New_Device", NULL);
printk("the result of the request_irq is: %d\n", result); //显示申请结果
printk("out request_irq_init\n");
return 0;
}
模块退出函数定义:
static void __exit request_irq_exit(void)
{
free_irq(irq, NULL); //释放申请的中断
printk("Goodbye request_irq\n");
return;
}
模块加载、退出函数调用:
module_init(request_irq_init);
module_exit(request_irq_exit);
实例运行结果及分析:
编译模块,执行命令insmod request_irq.ko插入模块,然后输入命令dmesg -c查看内核输出信息,出现如图A
所示的结果。
在模块卸载之前,输入命令cat /proc/interrupts查看文件/proc/interrupts的内容,出现如图B
所示的结果。
下面是另一种测试结果,在模块插入之前,内核中已经存在了对应中断号为16的中断,然后再插入模块,重新申请中断号为16的中断,会出现图C
所示的结果。
结果分析:
由图A
的输出信息可以判断动态申请中断是成功的,函数request_irq( )的返回结果是0;图B
的输出信息也同样说明了动态申请中断成功,因为中断号是10的中断信息出现在文件/proc/interrupts中,与图A
的输出信息互相吻合。
对于图C
是一种申请中断失败的情况,函数request_irq( )返回结果是负数,此时申请的中断对应的中断号在内核中已被占用,所以申请失败。