linux irq 接口,中断机制 – 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

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

#include

#include

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所示的结果。

cfb7c26701c5375cfcbc2e6c71c8b3c6.png

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

a963ae036d1f175bbc153589b63ae7c5.png

结果分析:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值