用于ARM的Linux内核基本上在一个循环中执行CPU_idle:

while (1) {
    disalbe_irq
    wfi
    enable_irq
}

我可以理解,这种逻辑之所以有用,是因为无论IRQ/FIQ状态如何,“wfi”都会唤醒ARM。但是,为什么“wfi”必须首先由disable_irq和eanble_irq括起来?

源代码/arch/arm/process.c具有以下建议:
* We need to disable interrupts here
* to ensure we don't miss a wakeup call.

但我无法理解。有人能启发我在哪种情况下会错过叫醒电话吗?

最佳答案

主循环中的整个“进入休眠”序列分为两个步骤:

  • 意识到您没有工作要做;
  • 尝试休眠(即WFI)

  • 如果仍然设置了一些中断标志,则WFI指令将充当NOP,这允许主循环返回运行所需的任务。到现在为止还挺好。

    但是,如果在第1步之后和第2步之前发生中断,就会出现问题。如果发生中断,则在退出ISR时将清除中断标志,并且当控制权返回主循环时,它将以所有中断命中WFI指令。标志被清除,导致CPU在主循环有机会执行ISR所需的任何任务之前进入休眠状态。

    关于linux - 为什么我们需要在ARM Linux cpu_idle中的WFI之前禁用中断,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23305953/

    10-09 01:30