Linux 驱动中 Timer / Tasklet / Workqueue 的作用与对比
🧩 1. 使用场景概览(对比表)
机制 | 执行上下文 | 是否可睡眠 | 使用场景 | 常用接口 |
---|
Timer | 中断上下文 | ❌ 不可睡眠 | 延迟执行(如防抖、超时处理) | add_timer() 等 |
Tasklet | 软中断上下文 | ❌ 不可睡眠 | 中断后的轻量快速处理 | tasklet_schedule() |
Workqueue | 进程上下文 | ✅ 可睡眠 | 可阻塞、耗时操作(如 I/O) | schedule_work() 等 |
🧠 2. 各机制作用详解
🔧 Timer(定时器)
- 作用:延迟执行某个函数,常用于按键防抖、超时控制等
- 上下文:中断上下文(不可睡眠)
- 示例:
struct timer_list my_timer;
timer_setup(&my_timer, my_timer_handler, 0);
mod_timer(&my_timer, jiffies + msecs_to_jiffies(20));
⚡ Tasklet(软中断)
- 作用:将中断处理函数中不能做的工作,延后到软中断上下文处理。
- 上下文:软中断上下文(不可阻塞)。
示例:
struct tasklet_struct tasklet;
DECLARE_TASKLET(my_tasklet, tasklet_handler, data);
tasklet_schedule(&my_tasklet);
🧵 Workqueue(工作队列)
- 作用:将任务放到内核线程中执行,可以使用阻塞操作,适合复杂或耗时的任务。
- 上下文:进程上下文(可阻塞)。
示例:
struct work_struct work;
void work_handler(struct work_struct *work) {printk(KERN_INFO "Work handler executed\n");
}
INIT_WORK(&my_work, work_handler);
schedule_work(&my_work);
三种方式调用func示例:
static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{struct gpio_key *gpio_key = dev_id;tasklet_schedule(&gpio_key->tasklet);mod_timer(&gpio_key->key_timer, jiffies + HZ/50);schedule_work(&gpio_key->work);return IRQ_HANDLED;
}