Linux内核API irq_set_chip_data

irq_set_chip_data函数功能描述:此函数是为irq_desc(结构体变量irq_desc的定义参见文件linux-3.19.3/include/linux/irqdesc.h)数组中对应下标为irq的元素设定字段chip_data的值,chip_data是一个void类型的指针,那么其类型就是不确定的了,一般此字段代表提供给字段chip中的函数的数据,供字段chip中函数共享,即提供一个共享数据区。

irq_set_chip_data文件包含

#include<linux/irq.h>

irq_set_chip_data函数定义

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

函数定义格式:

int irq_set_chip_data(unsigned int irq, void *data)

irq_set_chip_data输入参数说明

  • 参数 irq 是设备对应的中断号,对应数组irq_desc中元素的下标,此数组的大小为16640。
  • 参数data对应的是一个函数,其目的是为irq_desc数组中元素的chip字段中的函数提供一个私有的数据区,以实现chip字段中函数的共享执行。

irq_set_chip_data返回参数说明

此函数的返回结果是int型的变量,可能的取值是0、-22,如果返回0说明设置字段chip_data成功,如果返回-22说明设置字段chip_data失败,可能的原因有两个:

  • 参数irq超过数组irq_desc的范围,数组越界;
  • 与参数irq对应的irq_desc数组中的元素的chip字段为NULL。

irq_set_chip_data实例解析

编写测试文件:irq_set_chip_data.c头文件引用及全局变量定义:

#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int irq=10;      //中断号定义,可将irq更改为1000进行错误验证

中断处理函数及中断线程处理函数定义:

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

// 自定义中断线程处理函数
static irqreturn_t irq_thread_fn(int irq, void *dev_id)
{
    printk("the irq is :%d\n", irq);  //显示中断号
    printk("in the thread handler function\n");
    return IRQ_HANDLED;
}

自定义数据结构,用于函数irq_set_chip_data的第二个参数:

// 自定义数据结构,用于函数irq_set_chip_data的第二个参数,作者随意定义,无实际意义
struct   chip_data
{
    int num;
    char * name;
    int flags;
};

模块加载函数定义:

static int __init irq_set_chip_data_init(void)
{
    int result=0;
    int result1=0;
    int result2=0;
    struct chip_data data;        //自定义结构体变量,在此只是充当参数,没有实际应用的意义
    printk("into irq_set_chip_data_init\n");

    /*申请中断*/
    result=request_threaded_irq(irq, irq_handler, irq_thread_fn, IRQF_DISABLED, "A_NEW_DEVICE", NULL); result1=irq_set_chip(irq, NULL); //调用函数irq_set_chip( )给chip赋值
    result2=irq_set_chip_data(irq, &data); //调用函数irq_set_chip_data( )给chip_data赋值
    printk("the request_threaded_irq result is: %d\n", result);
                                  //显示函数request_threaded_irq( )返回结果
    printk("the irq_set_chip result is: %d\n", result1);
                                  //显示函数irq_set_chip( )返回结果
    printk("the irq_set_chip_data result is: %d\n", result2);
                                  //显示函数irq_set_chip_data( )返回结果
    printk("out irq_set_chip_data_init\n");
    return 0;
}

模块退出函数定义:

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

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

module_init(irq_set_chip_data_init);
module_exit(irq_set_chip_data_exit);

实例运行结果及分析:

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

Linux内核API irq_set_chip_data

如果将传入的第一个参数irq设置为1000,出现如图B所示的运行结果。

Linux内核API irq_set_chip_data

结果分析:

由图A可以看出函数irq_set_chip_data( )的返回结果是0,说明函数设置chip_data字段成功;对于图B的输出信息,可以看出函数irq_set_chip_data( )返回结果是-22,说明函数设置字段chip_data失败,因为传入的第一个参数irq的值为1000,此值超过了数组irq_desc的范围,数组越界,对应的中断描述符不存在。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程