Linux中的中断处理中的中断处理
与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq(),
request_irq()的原型为:
int request_irq(unsigned int irq,
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname,
void *dev_id);
irq是要申请的硬件中断号;
handler是向系统登记的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递;
irqflags是中断处理的属性,若设置SA_INTERRUPT,标明中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中
断,慢速处理程 序不屏蔽;若设置SA_SHIRQ,则多个设备共享中断,dev_id在中断共享时会用到,一般设置为这个设备的
device结构本身或者NULL。
free_irq()的原型为:
void free_irq(unsigned int irq,void *dev_id);
另外,与Linux中断息息相关的一个重要概念是Linux中断分为两个半部:上半部(tophalf)和下半部(bottom half)。上半部的
功能是"登记中断",当一个中断发生时,它进行相应地硬件读写后就把中断例程的下半部挂到该设备的下半部执行队列中去。
因此,上半部 执行的速度就会很快,可以服务更多的中断请求。但是,仅有"登记中断"是远远不够的,因为中断的事件可能很
复杂。因此,Linux引入了一个下半部,来完 成中断事件的绝大多数使命。下半部和上半部最大的不同是下半部是可中断的,
而上半部是不可中断的,下半部几乎做了中断处理程序所有的事情,而且可以被新的 中断打断!下半部则相对来说并不是非
常紧急的,通常还是比较耗时的,因此由系统自行安排运行时机,不在中断服务上下文中执行。
原理解析:
1、 中断概念
为什么需要中断?
1)外设的处理速度一般慢于CPU
2)CPU不能一直等待外部事件
所以设备必须有一种方法来通知CPU它的工作进度,这种方法就是中断。
2、 中断实现
在Linux驱动程序中,为设备实现一个中断包含两个步骤:
1)向内核注册中断
2)实现中断处理函数
3、 中断注册
request_irq用于实现中断的注册功能:
int request_irq(unsigned int irq, void (*handler)(int, void*, struct pt_regs *), unsigned long flags, const char *devname, void
*dev_id)
返回0表示成功,或者返回一个错误码
中断注册(参数)
1) unsigned int irq 中断号。
2)void (*handler)(int,void *,struct pt_regs *) 中断处理函数。
3)unsigned long flags 与中断管理有关的各种选项。