注意事项
如果你的目的是使用工作队列来调度任务,应该使用 queue_work 而不是 tasklet_schedule,并避免混用工作队列和 tasklet。
如果你确实需要使用 tasklet,则需要用 tasklet_struct 替代 work_struct,并使用 tasklet_schedule。
中断上下文-tasklet
int irq;
static struct work_struct power_off_work;
static DECLARE_TASKLET(power_off_work, power_off_func);void power_off_func(struct work_struct *work)
{printk("powerdown detect sync filesystem!\n");//call_usermodehelper("/bin/sync", NULL, NULL, UMH_WAIT_PROC);ksys_sync();printk("powerdown detect reboot system!\n");kernel_power_off();
}// 中断服务函数
irqreturn_t test_interrupt(int irq, void *args)
{// 使用工作队列处理关机操作tasklet_schedule(&power_off_work);return IRQ_RETVAL(IRQ_HANDLED);
}//驱动入口函数
static int interrupt_irq_init(void){int ret;irq = gpio_to_irq(110); //填写要申请的gpio编号printk("irq is %d\n", irq);ret = request_irq(irq, test_interrupt, IRQF_TRIGGER_FALLING, "test", NULL); //引脚上升沿触发中断服务函数if(ret < 0){printk("request_irq is error\n");return -1;}return 0;
}//驱动出口函数
static void interrupt_irq_exit(void){free_irq(irq, NULL);printk("bye bye\n");
}module_init(interrupt_irq_init);
module_exit(interrupt_irq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YU");
中断上下文-工作队列
int irq;
static struct work_struct power_off_work;
static DECLARE_WORK(power_off_work, power_off_func);void power_off_func(struct work_struct *work)
{printk("powerdown detect sync filesystem!\n");//call_usermodehelper("/bin/sync", NULL, NULL, UMH_WAIT_PROC);ksys_sync();printk("powerdown detect reboot system!\n");kernel_power_off();
}// 中断服务函数
irqreturn_t test_interrupt(int irq, void *args)
{// 使用工作队列处理关机操作schedule_work(&power_off_work);return IRQ_RETVAL(IRQ_HANDLED);
}//驱动入口函数
static int interrupt_irq_init(void){int ret;irq = gpio_to_irq(110); //填写要申请的gpio编号printk("irq is %d\n", irq);ret = request_irq(irq, test_interrupt, IRQF_TRIGGER_FALLING, "test", NULL); //引脚上升沿触发中断服务函数if(ret < 0){printk("request_irq is error\n");return -1;}return 0;
}//驱动出口函数
static void interrupt_irq_exit(void){free_irq(irq, NULL);printk("bye bye\n");
}module_init(interrupt_irq_init);
module_exit(interrupt_irq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YU");