转自:http://blog.csdn.net/xavierxiao/article/details/6087277
版权声明:本文为博主原创文章,未经博主允许不得转载。
Linux 里,
handle_level_irq
* Level type interrupts are active as long as the hardware line has
* the active level. This may require to mask the interrupt and unmask
* it after the associated handler has acknowledged the device, so the
* interrupt line is back to inactive.
当中断线电平达到激活电平,中断一直会被激活。 所以需要刚进中断处理函数就要屏蔽掉中断,
等handler 处理完后再打开中断(unmask)
Pesudo code
- handle_level_irq()
- {
- mask( irq );
- ack( irq );
- status |=IRQ_INPROGRESS;
- handle_IRQ_event();
- status &=~IRQ_INPROGRESS;
- unmask( irq );
- }
由于irq在整个处理过程中都被屏蔽,所以需要handle_level_irq里的action要尽量简短
handle_edge_irq
* Interrupt occures on the falling and/or rising edge of a hardware
* signal. The occurence is latched into the irq controller hardware
* and must be acked in order to be reenabled. After the ack another
* interrupt can happen on the same source even before the first one
* is handled by the assosiacted event handler. If this happens it
* might be necessary to disable (mask) the interrupt depending on the
* controller hardware. This requires to reenable the interrupt inside
* of the loop which handles the interrupts which have arrived while
* the handler was running. If all pending interrupts are handled, the
* loop is left.
中断发生在上升沿/下降沿, 它会被中断控制器锁存起来,需要ack 后才能重新使能。 Ack 后新的
中断可以在前一个中断正在被处理时产生,如果这种情况发生,则需要屏蔽中断。同时,需要用一个loop
来处理中断处理过程中又有中断产生的情况,在这个loop中重新把中断屏蔽打开。 如果所有pending的
中断都处理完了,loop就可以离开。
Pesudo code
- handle_edge_irq()
- {
- if( status & IRQ_INPROGRESS ) {
- status |= (IRQ_PENDING | IRQ_MASKED);
- mask();
- ack();
- return;
- }
- ack();
- status |= IRQ_INPROGRESS;
- do{
- if( status & (IRQ_PENDING | IRQ_MASKED ) )
- umask();
- handle_IRQ_event();
- }while( status & IRQ_PENDING );
- status &= ~IRQ_INPROGRESS;
- }
中断触发方式的比较
http://blog.21ic.com/user1/2662/archives/2007/37347.html