中断下半部
在中断处理函数执行的过程中:
1. 它可以被其他中断打断
2. 它不会再次响应同一个中断(同一个中断不会嵌套处理)
3. 如果中断处理函数执行的时间很长,系统性能会受影响
举例:
net_irq()
{
1. 从网卡芯片读数据到内存里 (比较快)
2. 处理数据 (比较耗时)
}
如果在net_irq执行期间,网卡不断收到数据,
由于上面第2点原因,导致net_irq不能立刻执行,
数据会堆积最终可能丢失
所以: net_irq要尽快执行完, 它只做最紧急的事: "1. 从网卡芯片读数据到内存里"
把"2. 处理数据" 留到合适的时间再做: 在处理完中断(调用中断处理函数)后,返回(恢复现场)之前执行
把中断处理分为上半部、下半部:
xxxx_irq()
{
执行上半部做紧急的事
把下半部告诉内核
}
怎么写代码?
1. 定义一个结构体tasklet_struct: 里面有"下半部的函数"
void button_tasklet_function(unsigned long data)
{
}
static DECLARE_TASKLET(buttons_tasklet, button_tasklet_function, 0);
2. 在中断服务程序里: 把下半部告诉内核
tasklet_schedule(&buttons_tasklet);
下半部特点:
1. 执行下半部过程中,可以响应中断
2. 下半部执行时间有保证
3. 如果下半部执行时间太长的话,会影响系统性能
4. 运行于中断上下文,不能休眠
如果数据处理执行的时间非常长,那么就不适合使用下半部, 用工作队列
1. 写处理函数,定义一个结构体
static void buttons_work_func(struct work_struct *work)
{
}
static struct work_struct buttons_work;
INIT_WORK(&buttons_work, buttons_work_func);
2. 把这个结构体告诉内核
schedule_work(&buttons_work);
下半部 工作队列
1. 运行于中断上下文 运行于内核线程上下文
2. 时间有保证 内核线程优先级比较高,时间也有保证
3. 不能休眠 可以休眠
4. 耗时不应太大 应该没有影响(可以设置APP的优先级让APP不受影响)
5. 不影响中断 不影响中断