示例1:同tasklet
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/delay.h>
/*
myirqs{
interrupt-parent = <&gpiof>;
interrupts = <9 0>, <7 0>,<8 0>;
};
*/
struct device_node* node;
unsigned int irqno;
//一:创建一个工作队列结构体变量
struct work_struct work;
//四:填充工作队列处理函数
void work_func(struct work_struct* work){
//具体代码块
}
//4.填充中断处理函数
irqreturn_t key_irq_handle(int irq,void* dev){
//三:调用工作队列执行
schedule_work(&work);
//注意返回值
return IRQ_HANDLED;
}
static int __init mycdev_init(void){
int ret = 0;
//二:初始化工作队列
INIT_WORK(&work, work_func);
//1.获取节点
node = of_find_node_by_path("/myirqs");
if(NULL == node){
printk("of_find_node_by_path error\n");
return -EINVAL;
}
//2.根据节点获取中断号
irqno = irq_of_parse_and_map(node,0);
if(0 == irqno){
printk("irq_of_parse_and_map error\n");
return -EAGAIN;
}
//3.注册中断
ret = request_irq(irqno,key_irq_handle,IRQF_TRIGGER_FALLING,"my_irq",NULL);
if(ret){
printk("request_irq error\n");
return ret;
}
return 0;
}
static void __exit mycdev_exit(void){
//5.释放中断号
free_irq(irqno,NULL);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
示例二:工作队列不同于tasklet,可脱离中断单独执行
#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>
struct timer_list mytimer;
//一:创建一个工作队列结构体变量
struct work_struct work;
//四:填充工作队列处理函数
void work_func(struct work_struct* work){
//具体代码块
//再次启动定时器
mod_timer(&mytimer,jiffies+HZ);
}
//填充定时器处理函数
void timer_function(struct timer_list* timer){
//三:调用工作队列执行
schedule_work(&work);
}
static int __init mycdev_init(void){
//二:初始化工作队列
INIT_WORK(&work, work_func);
//定时器初始化
mytimer.expires = jiffies + HZ;
timer_setup(&mytimer,timer_function,0);
//启动并初始化定时器
add_timer(&mytimer);
return 0;
}
static void __exit mycdev_exit(void){
//销毁定时器
del_timer(&mytimer);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");