【中断处理例程】
中断处理器例程即中断处理函数,其作用是根据被服务的中断的含义进行适当的操作,通常是读、写数据。中断处理例程与普通C函数没有什么差别,但是中断处理装置有以下限制:
中断处理装置不能与用户空间传递数据,因为它不在进程上下文执行;
中断处理程序也不能做任何可能休眠的事情,例如,调用wait_event(),除了使用GFP_ATOMIC之外的任何东西来分配内存,或者锁住一个信号量;
中断处理例程不能调用schedule()。
中断处理例程的第一步常常包括清除设备的一个中断标志位,大部分硬件设备在清除”中断挂起“位前不会再产生中断。这也要根据硬件的工作原理决定,这一步也可能需要最后做而不是开始,没有通用的规则。一些设备不需要这一步,因为他们没有中断挂起位。
一个中断处理例程的经典任务是:如果中断通知它所等待的事件已经发生(例如新数据的到达),就会唤醒休眠在设备上的进程。不管是慢速还是快速处理函数,程序员应该编写执行时间尽可能短的处理函数。如果需要长时间计算,最好的方法是使用tasklet或workqueue在一个更安全的时间来调度计算任务。
典型的中断处理程序如下:
void sample_interrupt(intirq, void *dev_id, struct pt_regs *regs)
{
stuct sample_dev *dev=dev_id;
/*清除设备的中断标志位*/
/*其他必须的操作*/
}
中断处理例程的参数有:irq、dev_id和regs。Irq是中断号;dev_id是中断注册request_irq()函数的dev_id参数,在相应中断时作为参数传递给中断处理函数,通常传递一个指向设备数据结构的指针到dev_id中,这样一个为若干设备服务的驱动程序在中断处理是不需要任何其他代码,就可以找出是哪个设备产生了当前的中断事件,通过dev_id就可以区分。rags参数很少使用。
【中断的禁止和使能】
有时设备驱动必须在一段时间内阻塞中断发生,内核提供了多个函数来进行中断的禁止和使能操作,可以对某个中断,也可以对所有中断进行禁止和使能操作。
-
禁止和使能单个中断
有时驱动设备需要禁止一个特定的中断,可以使用在include/asm/irq.h中生声明disable_irq()和enable_irq()函数来进行单个中断的禁止和使能操作,这两个函数的原型:
void disable_irq(int irq);
void enable_irq(int irq);
disable_irq(int irq)函数禁止给定的中断,并等待当前的处理例程结束;enable_irq(int irq)使能给定中断。参数irq是给定的中断号。
-
禁止和使能所有中断
禁止所有中断时用宏local_irq_save(x)或local_irq_disable()来进行的,local_irq_save(x)宏保存当前的中断状态并且禁止所有的IRQ,local_irq_disable()禁止所有的IRQ,使能所有中断是用宏local_irq_restore(x)或local_irq_enable()来进行的。 local_irq_restore(x)宏与local_irq_save(x)对应,恢复保存的中断状态;local_irq_able()与local_irq_enable对应,恢复所有的IRQ。