Linux内核API irq_set_irq_wake

irq_set_irq_wake函数功能描述:函数irq_set_irq_wake( )用于改变中断的状态及中断的唤醒深度,其对中断状态及中断唤醒深度的影响根据参数on不同会有不同的结果。如果on的值为0,函数将使中断处于睡眠状态,不能被唤醒,减少中断唤醒深度wake_depth的值;如果on的值为非0,函数将中断从睡眠状态唤醒,使中断处于唤醒状态,增加其唤醒深度wake_depth的值。

irq_set_irq_wake文件包含

#include<linux/interrupt.h>

irq_set_irq_wake函数定义

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

函数定义格式:

int irq_set_irq_wake(unsigned int irq, unsigned int on)

irq_set_irq_wake输入参数说明

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

参数on是用来选择执行的程序序列,可取任意的整数,一般取1、0。

irq_set_irq_wake返回参数说明

此函数的返回值是整数,代表执行的结果,可能的取值是-6、0。返回-6说明当前中断号对应的irq_desc[]数组中元素的chip字段的set_wake字段的值为NULL,此时函数的相应的功能无法实现,即函数既不改变中断唤醒的深度也不改变当前中断的状态。如果传递的第二个参数on的值为0,函数的返回结果是0,有两种情况:

  • 当前中断的唤醒深度是0,其函数功能没有实现,作用与返回-6相同;
  • 当前的唤醒深度是1,则其作用全部实现,即函数既减少中断的唤醒深度,也改变了当前中断的状态,使中断处于不可唤醒状态;如果传递的第二个参数on的值为1,函数返回结果是0,说明函数既增加了中断的唤醒深度,也改变了当前中断的状态,使中断处于唤醒状态。

irq_set_irq_wake实例解析

编写测试文件:irq_set_irq_wake.c

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

#include<linux/module.h>
#include<linux/interrupt.h>
MODULE_LICENSE("GPL");
static int irq=3;  //定义中断号

中断处理函数定义:

// 自定义中断处理函数,在此只有显示功能
static irqreturn_t irq_handler(int data, void *dev_id)
{
    printk("the data is :%d\n", data);  //显示中断号
    printk("in the interrupt handler function\n");
    return IRQ_NONE;
}

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

static int __init irq_set_irq_wake_init(void)
{
    int result=0, result1=0, result2=0;
    printk("into irq_set_irq_wake_init\n");
    result=request_irq(irq, irq_handler, IRQF_DISABLED, "A_New_Device", NULL);
                                          // 申请中断
    result1=irq_set_irq_wake(irq,0);      //使中断处于睡眠状态,减少唤醒深度
    result2=irq_set_irq_wake(irq,1);      //使中断处于唤醒状态,增加唤醒深度

    /*显示函数调用结果*/
    printk("the request_irq result is: %d\n", result);
    printk("the irq_set_irq_wake(irq,0) result is :%d\n", result1);
    printk("the irq_set_irq_wake(irq,1) result is :%d\n", result2);
    printk("out irq_set_irq_wake_init\n");
    return 0;
}

模块卸载函数定义:

static void __exit irq_set_irq_wake_exit(void)
{
    free_irq(irq, NULL);     //释放申请的中断
    printk("Goodbye irq_set_irq_wake\n");
    return;
}

模块加载及卸载函数调用:

module_init(irq_set_irq_wake_init);
module_exit(irq_set_irq_wake_exit);

实例运行结果及分析:

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

Linux内核API irq_set_irq_wake

结果分析:

由图可以看出函数request_irq( )的返回结果是0,说明中断申请成功,函数irq_set_irq_wake( )的第一次调用返回结果是0,第二次调用返回结果是0,两个调用函数的功能都没有实现。第一次调用的第二个参数是0,此时中断的唤醒深度为0,满足函数返回参数说明中on为0的第一种情况,此时函数无功而返;第二次调用时,第二个参数为1,此时动态申请的中断描述符的chip字段为NULL,函数也是无功而返。

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

评论 抢沙发

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