一點心得,有錯請指正^^;
我使用的平台是ARM, kernel版本是2.6.21
enable_irq / disable_irq函式的實作在:
kernel_source/kernel/irq/manage.c
看到disable_irq()裡面又呼叫disable_irq_nosync()
void disable_irq(unsigned int irq)
{
.....
disable_irq_nosync(irq);
.....
}
//disable_irq_nosync這個函式會對desc->depth做++的動作
//所以連呼叫兩次disable_irq()會使desc->depth的值變成2
void disable_irq_nosync(unsigned int irq)
{
.....
spin_lock_irqsave(&desc->lock, flags);
if (!desc->depth++) {
.....
}
.....
}
//再來看enable_irq()
//這個函式會判斷desc->depth的值
//假設呼叫兩次disable_irq之後我們只呼叫一次enable_irq,
//因為此時desc->depth為2,所以不會進到case 1去打開中斷
//只會到default裡面進行desc->depth--
//而如果一開始就呼叫enable_irq而不呼叫diable_irq
//則會進到case 0去印Unbalanced enable for IRQ的訊息
//可見在kernel的設計裡,disable_irq/enable_irq是要成對出現的
void enable_irq(unsigned int irq)
{
.....
switch (desc->depth) {
case 0:
printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
WARN_ON(1);
break;
case 1: {
unsigned int status = desc->status & ~IRQ_DISABLED;
/* Prevent probing on this irq: */
desc->status = status | IRQ_NOPROBE;
check_irq_resend(desc, irq);
/* fall-through */
}
default:
desc->depth--;
}
.....
}
※ 引述《eleghost (eleghost)》之銘言:
: 在 arm 平台環境.
: 請問 enable_irq / disable_irq是否一定要平衡?
: 意思是說如果disable_irq一次, 可用enable_irq
: 重新喚起irq.
: 但如果今日調用disable_irq兩次, 但只enable_irq一次
: 則無法喚起. 一定要在調用一次enable_irq才能使
: irq工作.
: 這是kernel設定嗎? 可以改變嗎? thanks.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 175.181.129.228