Linux内核API request_irq

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所示的结果。

Linux内核API request_irq

在模块卸载之前,输入命令cat /proc/interrupts查看文件/proc/interrupts的内容,出现如图B所示的结果。

Linux内核API request_irq

下面是另一种测试结果,在模块插入之前,内核中已经存在了对应中断号为16的中断,然后再插入模块,重新申请中断号为16的中断,会出现图C所示的结果。

Linux内核API request_irq

结果分析:

由图A的输出信息可以判断动态申请中断是成功的,函数request_irq( )的返回结果是0;图B的输出信息也同样说明了动态申请中断成功,因为中断号是10的中断信息出现在文件/proc/interrupts中,与图A的输出信息互相吻合。

对于图C是一种申请中断失败的情况,函数request_irq( )返回结果是负数,此时申请的中断对应的中断号在内核中已被占用,所以申请失败。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程