irq_set_irq_type函数功能描述:此函数用于设置中断处理函数触发的类型,被操作的中断描述符保存在数组irq_desc中,对应的下标为参数irq的值,设置的中断触发类型为参数type所代表的类型。
irq_set_irq_type文件包含
#include<linux/irq.h>
irq_set_irq_type函数定义
在内核源码中的位置:linux-3.19.3/kernel/irq/chip.c
函数定义格式:
int irq_set_irq_type(unsigned int irq, unsigned int type)
irq_set_irq_type输入参数说明
- 参数
unsigned int irq
是对应的中断号,与数组irq_desc的下标相对应,数组的大小为16640。 - 参数
unsigned int type
是系统定义的中断触发类型,定义见文件linux-3.19.3/include/linux/irq.h,可能的取值定义如下:- IRQ_TYPE_NONE 0x00000000系统默认的没有明确指明类型的触发模式
- IRQ_TYPE_EDGE_RISING 0x00000001上升沿触发
- IRQ_TYPE_EDGE_FALLING 0x00000002下降沿触发
- IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)上升沿下降沿两种触发都行
- IRQ_TYPE_LEVEL_HIGH 0x00000004高电平触发
- IRQ_TYPE_LEVEL_LOW 0x00000008低电平触发
- IRQ_TYPE_SENSE_MASK 0x0000000f以上任何一种条件
- IRQ_TYPE_DEFAULT IRQ_TYPE_SENSE_MASK以上任何一种条件
- IRQ_TYPE_PROBE 0x00000010在进程中查询
irq_set_irq_type返回参数说明
函数的返回结果是int型变量,返回0或者负数,如果返回结果是负数,说明设置中断触发类型失败;如果返回结果是0,有四种情况:
- 设置中断触发类型成功;
- 传入的中断触发类型参数是IRQ_TYPE_NONE,如果传入此参数,函数不会更改中断的触发类型;
- 数组中与irq对应的元素的chip字段的值为NULL;
- 数组中与irq对应的元素的chip字段的值不为NULL,但chip字段的set_type字段的值为NULL。
irq_set_irq_type实例解析
编写测试文件:irq_set_irq_type.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 irq, void *dev_id)
{
printk("the irq is :%d\n", irq); //显示中断号
printk("in the interrupt handler function\n");
return IRQ_WAKE_THREAD; //触发中断线程处理函数执行
}
// 自定义中断线程处理函数
static irqreturn_t irq_thread_fn(int irq, void *dev_id)
{
printk("the irq is :%d\n", irq); //显示中断号
printk("in the thread handler function\n");
return IRQ_HANDLED;
}
模块加载函数定义:
static int __init irq_set_irq_type_init(void)
{
int result=-1, result1=-1;
int irqtype=1;
printk("into irq_set_irq_type_init\n");
/*申请中断*/
result=request_threaded_irq(irq, irq_handler, irq_thread_fn, IRQF_DISABLED, "A_NEW_DEVICE", NULL);
result1=irq_set_irq_type(irq, irqtype); //调用irq_set_irq_type( )函数设置中断类型
/*显示函数调用结果*/
printk("the request_threaded_irq result is: %d\n", result);
printk("the irq_set_irq_type result is:%d\n", result1);
printk("out irq_set_irq_type_init\n");
return 0;
}
模块退出函数定义:
static void __exit irq_set_irq_type_exit(void)
{
free_irq(irq, NULL);
printk("Goodbye irq_set_irq_type\n");
return;
}
模块加载、退出函数调用:
module_init(irq_set_irq_type_init);
module_exit(irq_set_irq_type_exit);
实例运行结果及分析:
编译模块,执行命令insmod irq_set_irq_type.ko插入内核模块,然后输入命令dmesg -c查看内核输出信息,出现如图所示的信息。
结果分析:
由图可以看出函数irq_set_irq_type( )的返回值是0,并且中断处理函数执行一次。但返回0并不代表设置中断触发类型成功,因为动态申请的中断描述符其字段chip的值为NULL,所以返回0是必然。
如果想设置中断的类型成功,必须满足以下条件:
- 中断描述符存在数组irq_desc中;
- 参数type不是IRQ_TYPE_NONE;
- 中断描述符的chip字段的值不为NULL;
- 中断描述符的字段chip的字段set_type的值不为NULL。
但是满足以上条件,也不一定能设置成功,还需要看字段set_type代表的函数的实现。