disable_irq_nosync函数功能描述:函数disable_irq_nosync( )在实现过程中调用了函数__disable_irq( ),完成增加中断所处的深度和改变中断的状态,一般在中断处理之前调用它保证中断的安全和处理函数的正常运行。
disable_irq_nosync文件包含
#include<linux/interrupt.h>
disable_irq_nosync函数定义
在内核源码中的位置:linux-3.19.3/kernel/irq/manage.c
函数定义格式:
void disable_irq_nosync(unsigned int irq)
disable_irq_nosync输入参数说明
此函数的参数是int型变量,代表操作中断对应的中断号,与数组irq_desc中元素的下标相对应,根据它查找对应设备的中断服务例程,其取值范围是0~NR_IRQS-1,其中NR_IRQS的值是16640。
disable_irq_nosync返回参数说明
此函数的返回值类型是void类型变量,即函数不返回任何值。
disable_irq_nosync实例解析
编写测试文件:disable_irq_nosync.c
头文件引用及全局变量定义:
#include <linux/interrupt.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int irq=3; //定义中断号,并初始化为3
中断处理函数:
// 自定义中断处理函数,此处只显示参数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;
}
模块加载函数定义及验证函数调用:
static int __init disable_irq_nosync_init(void)
{
int result=0;
printk("into disable_irq_nosync_init\n");
/*申请一个新的中断,中断号对应的是3,中断处理函数是myhandler( ),中断类型是IRQF_
DISABLED,中断设备名是A_NEW_Device,设备编号是NULL(即不对应真实的设备)*/
result=request_irq(irq, irq_handler, IRQF_DISABLED, "A_New_Device", NULL);
disable_irq_nosync(irq); //调用disable_irq_nosync( )函数,使中断的深度增加1
enable_irq(irq); //调用enable_irq( )函数,使中断的深度减少1,同时触发中断处理函数执行
printk("the result of the request_irq is: %d\n", result); //输出中断申请的结果
printk("out disable_irq_nosync_init\n");
return 0;
}
模块退出函数定义:
static void __exit disable_irq_nosync_exit(void)
{
free_irq(irq, NULL); //释放中断
printk("Goodbye disable_irq_nosync\n");
return;
}
模块加载、退出函数调用:
module_init(disable_irq_nosync_init);
module_exit(disable_irq_nosync_exit);
实例运行结果及分析:
编译模块,输入命令insmod disable_irq_nosync.ko加载模块,然后输入命令dmesg -c查看内核输出信息,出现如图A
所示的结果。
在卸载模块之前,输入命令cat /proc/interrupts查看/proc/interrupts文件内容,出现如图B
所示的结果。
结果分析:
由图A
和图B
可以判断中断处理函数被调度执行了一次,并且对应的中断号为3。中断处理函数的执行归因于两个函数:disable_irq_nosync( )和enable_irq( ),如果缺少任何一个,中断处理函数都不能被调度执行。首先函数disable_irq_nosync( )将中断的深度增加,变为1,然后函数enable_irq( )检测到中断的深度是1,执行不同的路径,调度中断处理函数,然后将深度降低,变为0,只有这两个函数协同工作,才能出现图A
和图B
的效果。