Linux内核API enable_irq

enable_irq函数功能描述:数enable_irq( )在实现过程中调用了函数__enable_irq( ),根据中断所处的深度和状态的不同,会有不同的执行结果,一般用于改变中断的状态,使中断处于唤醒状态,触发中断处理函数的执行及减少中断所处的深度,即改变字段depth的值。

enable_irq文件包含

#include<linux/interrupt.h>

enable_irq函数定义

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

函数定义格式:

void enable_irq(unsigned int irq)

enable_irq输入参数说明

此函数的参数是int型变量,代表操作中断对应的中断号,与数组irq_desc中元素的下标相对应,根据它查找对应设备的中断服务例程,其取值范围是0~NR_IRQS-1,其中NR_IRQS的值是16640。

enable_irq返回参数说明

此函数的返回值类型是void类型变量,即函数不返回任何值。

enable_irq实例解析

编写测试文件:enable_disable_irq.c

头文件引用及全局变量定义:

#include <linux/interrupt.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int irq=11;     //定义中断号,并初始化为11

中断处理函数:

// 自定义中断处理函数,此处只显示参数data的值与提示程序的执行位置
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");
    /*函数返回,返回值类型为irqreturn_t类型,可取值为IRQ_NONE、IRQ_HANDLED,此处两者皆可*/
    return IRQ_NONE;
}

C

模块加载函数定义及验证函数调用:

static int __init enable_disable_irq_init(void)
{
    int result=0;
    printk("into enable_disable_irq_init\n");
    /*申请一个新的中断,中断号对应的是11,中断处理函数是myhandler( ),中断类型是IRQF_
        DISABLED,中断设备名是A_NEW_Device,设备编号是NULL(即不对应真实的设备)*/
    result=request_irq(irq, irq_handler, IRQF_DISABLED, "A_New_Device", NULL);
    disable_irq(irq); //调用disable_irq( )函数,使中断的深度增加1
    enable_irq(irq); //调用enable_irq( )函数,使中断的深度减少1,同时触发中断处理函数执行
    printk("the result of the request_irq is: %d\n", result);    //输出中断申请的结果
    printk("out enable_disable_irq_init\n");
    return 0;
}

模块退出函数定义:

static void __exit enable_disable_irq_exit(void)
{
    free_irq(irq, NULL);    //释放中断
    printk("Goodbye enable_disable_irq\n");
    return;
}

模块加载、退出函数调用:

module_init(enable_disable_irq_init);
module_exit(enable_disable_irq_exit);

实例运行结果及分析:

编译模块,输入命令insmod enable_disable_irq.ko加载模块,然后输入命令dmesg -c查看内核输出信息,出现如图A所示的结果。

Linux内核API enable_irq

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

Linux内核API enable_irq

结果分析:

由图A和图B可以判断中断处理函数被调度执行了一次,并且对应的中断号为11。中断处理函数的执行归因于两个函数:disable_irq ( )和enable_irq( ),如果缺少任何一个,中断处理函数都不能被调度执行。首先函数disable_irq ( )将中断的深度增加,变为1,然后函数enable_irq( )检测到中断的深度是1,执行不同的路径,调度中断处理函数,然后将深度减少,变为0,只有这两个函数协同工作,才能出现图A和图B的效果。

函数比较:

函数disable_irq( )在实现过程中调用了函数disable_irq_nosync( ),实现改变当前中断的状态及改变中断的depth字段的值,但当函数disable_irq( )将一个中断置为不可用时,会阻塞自身,等待中断的唤醒,中断处理函数执行完毕后返回,而函数disable_irq_nosync( )是直接返回。

赞(1)
未经允许不得转载:极客笔记 » Linux内核API enable_irq
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址