在内核源码中的位置:linux-2.6.30/kernel/irq/manage.c 函数定义格式:int __must_check request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags, const char *name , void *dev)
函数request_threaded_irq( )首先对传入的参数进行正确性检查,根据传入的irq号获得数组irq_desc中以irq为下标的元素,然后动态的创建一个irqaction描述符,根据传入的参数初始化新生成的irqaction描述符,最后调用函数__setup_irq( )把该描述符加入到IRQ链表中,完成中断的动态申请及注册。
如果返回值是0则说明申请成功,如果申请不成功,则返回的值非零,一般为负数,可能的取值-16、-38。例如,如果返回值是-16,则说明申请的中断号在内核中已被占用。
实例解析:
编写测试文件:request_threaded_irq.c
头文件引用及全局变量定义
#include <linux/interrupt.h>
#include<linux/irq.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int irq=10; //中段号定义
static irqreturn_t irq_handler(int data,void *dev_id)
{
printk("<0>the data is :%d\n",data); //data是对应中断的中断号
printk("<0>in the interrupt handler function\n");
return IRQ_WAKE_THREAD; //触发中断线程函数执行
}
//自定义中断线程处理函数
static irqreturn_t irq_thread_fn(int data,void *dev_id)
{
printk("<0>the data is :%d\n",data); //data是对应中断的中断号
printk("<0>in the interrupt thread function\n");
return IRQ_HANDLED;
}
static int __init request_threaded_irq_init(void)
{
int result=0;
printk("<0>into request_threaded_irq_init\n");
/* 调用request_threaded_irq( )函数,irq是对应的中断编号,irq_handler是定义的中断处理函数,
irq_thread_fn是对应的中断线程处理函数,IRQF_DISABLED中断的类型*/
result=request_threaded_irq(irq,irq_handler,irq_thread_fn,IRQF_DISABLED,"A_New_Device",NULL);
printk("<0>the result of the request_threaded_irq is: %d\n",result); //显示函数调用结果
disable_irq(irq); //中断不可用
enable_irq(irq); //使能中断,触发中断处理函数的执行
printk("<0>out request_threaded_irq_init\n");
return 0;
}
static void __exit request_threaded_irq_exit(void)
{
free_irq(irq,NULL); //释放申请的中断
printk("<0>Goodbye request_threaded_irq\n");
return;
}
module_init(request_threaded_irq_init);
module_exit(request_threaded_irq_exit);
编译模块,执行命令insmod request_threaded_irq.ko插入内核模块,然后输入命令dmesg –c查看内核输出信息,出现如图
在模块卸载之前输入命令cat /proc/interrupts查看文件/proc/interrupts的内容,出现如图
在没有加载模块之前,输入命令cat /proc/interrupts查看文件/proc/interrupts的内容
具体分析请参考文献:《Linux内核API完全参考手册》邱铁,周玉,邓莹莹 编著,机械工业出版社 2011年1月1日出版