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