回想, 工作队列在将来某个时候调用一个函数, 在一个特殊工作者进程的上下文中. 因为这个工作队列函数在进程上下文运行, 它在需要时能够睡眠. 但是, 你不能从一个工作队列拷贝数据到用户空间, 除非你使用我们在 15 章演示的高级技术; 工作者进程不存取任何其他进程的地址空间.
short 驱动, 如果设置 wq 选项为一个非零值来加载, 为它的后半部处理使用一个工作队列. 它使用系统缺省的工作队列, 因此不要求特殊的设置代码; 如果你的驱动有特别的运行周期要求(或者可能在工作队列函数长时间睡眠), 你可能需要创建你自己的, 专用的工作队列. 我们确实需要一个 work_struct 结构, 它声明和初始化使用下列:
static struct work_struct short_wq;
/* this line is in short_init() /
INIT_WORK(&short_wq, (void ()(void *)) short_do_tasklet, NULL);
我们的工作者函数是 short_do_tasklet, 我们已经在前面一节看到. 当使用一个工作队列, short 还建立另一个中断处理, 看来如此:
irqreturn_t short_wq_interrupt(int irq, void *dev_id, struct pt_regs regs)
{
/ Grab the current time information. */
236
do_gettimeofday((struct timeval ) tv_head); short_incr_tv(&tv_head);
/ Queue the bh. Don’t worry about multiple enqueueing / schedule_work(&short_wq);
short_wq_count++; / record that an interrupt arrived */ return IRQ_HANDLED;
}
如你所见, 中断处理看来非常象这个 tasklet 版本, 除了它调用 schedule_work 来安排后半部处理.
转载:https://blog.csdn.net/xxzhaoming/article/details/113252383