字符设备驱动之笔记-中断上下部

来源:互联网 发布:阿里云免费企业邮箱 编辑:程序博客网 时间:2024/05/16 17:39
 

中断下半部
在中断处理函数执行的过程中:
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.     不影响中断                 不影响中断