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
所示的结果。
在卸载模块之前,输入命令cat /proc/interrupts查看/proc/interrupts文件内容,出现如图B
所示的结果。
结果分析:
由图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( )是直接返回。