Linux内核 irq_set_irq_type()

函数:irq_set_irq_type( )

文件包含:

        #include<linux/irq.h>

函数定义:

在内核源码中的位置:linux-3.19.3/kernel/irq/chip.c

函数定义格式:

int irq_set_irq_type(unsigned int irq, unsigned int type)

函数功能描述:

此函数用于设置中断处理函数触发的类型,被操作的中断描述符保存在数组irq_desc中,对应的下标为参数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在进程中查询

返回参数说明:

函数的返回结果是int型变量,返回0或者负数,如果返回结果是负数,说明设置中断触发类型失败;如果返回结果是0,有四种情况:

  • 设置中断触发类型成功;
  • 传入的中断触发类型参数是IRQ_TYPE_NONE,如果传入此参数,函数不会更改中断的触发类型;
  • 数组中与irq对应的元素的chip字段的值为NULL;
  • 数组中与irq对应的元素的chip字段的值不为NULL,但chip字段的set_type字段的值为NULL。

实例解析:

编写测试文件: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查看内核输出信息,出现如图所示的信息。

Linux内核 irq_set_irq_type()

结果分析:

由图可以看出函数irq_set_irq_type( )的返回值是0,并且中断处理函数执行一次。但返回0并不代表设置中断触发类型成功,因为动态申请的中断描述符其字段chip的值为NULL,所以返回0是必然。

如果想设置中断的类型成功,必须满足以下条件:

  • 中断描述符存在数组irq_desc中;
  • 参数type不是IRQ_TYPE_NONE;
  • 中断描述符的chip字段的值不为NULL;
  • 中断描述符的字段chip的字段set_type的值不为NULL。

但是满足以上条件,也不一定能设置成功,还需要看字段set_type代表的函数的实现。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!