OS:RHEL62
传递:同一中断号(ISR, IRQ)下会挂(注册)多个处理函数。每个处理函数,最后一个被注册的会最先被响应(先进后出)。如果最后一个注册函数在收到了中断后表示我有能力处理,则其他处理函数就没有处理机会。这个象击鼓传花(传递)。如此依次传递,中断会在有能力处理的处理函数处结束。
前半部中断和后半部(bottom half):中断处理函数收到中断后,发现有能力处理。则赶紧说可以我处理。这是前半部。有能力,通常是检查一下自己有没有对应寄存器上设置了中断位。
代码如下
为10号中断注册处理函数
request_irq(10, process_of_a_interrupt);
中断处理函数
int process_of_a_interrupt()
{
int reg = read_pci_card_or_my_fpga_register_value();
if(reg == IS_INTERRUPT_BIT_SETTED)
{
ret = I_CAN;
}
// 上半部结束。
set_bh_bit(NOW_IS_BOTTOM_HALF);
schedule_work(bh_process);
return ret;
}
下半部处理
void bh_process()
{
LONG_AND_DISTURBING_AND_COMPLEX_WORK_NOW
}
冲突:两个中断号相同了。根据上面的传递机制,如果两个不同的设备(显卡和数据卡)中断冲突了,只要他们的处理函数很理性,那么这个中断处理就仍然可以继续。什么叫理性,就是他们都象上文的伪代码一样,一眼看到自己的中断标志位有没有置,没置,就传递出去。
孪生设备的冲突:不同插槽放入同一种PCI卡,例如PLX9056.如果他们的中断号相同,那么这会冲突。冲突结果是同时两张卡都在工作时,他们互相冲突,无法工作。
为什么?
两张卡,每张都在irq10下注册了一个process_of_a_interrupt(),如此IRQ10下有两个注册处理函数process_a, process_b(都同process_of_a_interrupt)
两张卡同时处理数据,几乎同时来了中断,并把中断位 置上。
A,B卡都置上了中断位,并发送中断给CPU。
CPU收到并处理。CPU前后收到两个中断,分别是int_a, int_b。
CPU处理int_a,先调用process_b. B发现自己已经置上中断位,B告诉中断我有能力处理。这就错掉了。process_b会清空中断位。
CPU继续来,继续处理int_b,先调用process_b. B发现自己没有置中断位(已经被process_b清空),B告诉中断我没有能力处理。这也错掉了。
B没有处理中断int_b,按照传递方式,由process_a处理。A发现自己已经置上中断位,A告诉中断我有能力处理。
赞曰: 总体上来说,一步错后面全错了。
赞曰: 基本上不会出现不同插槽的同一种PCI卡的中断号相同的情况,如果有,主要是驱动写错了。