The Linux kernel for ARM basically does CPU_idle in a loop:
while (1) {
disalbe_irq
wfi
enable_irq
}
I can understand that this logic works because "wfi" wakes up ARM regardless of IRQ/FIQ status. However, why "wfi" has to be bracketed by disable_irq and eanble_irq in the first place?
The source code /arch/arm/process.c has the following commends:
* We need to disable interrupts here
* to ensure we don't miss a wakeup call.
But I can't make sense of it. Can someone enlighten me in which scenario we would miss a wakeup call ?
If an interrupt comes in in-between any of those instructions and modifies the data, your first ISR can potentially read the wrong value. So you need to disable interrupts before you operate on it and also declare the variable volatile .
Interrupts and Pipelined CodeBecause an interrupt in the middle of a fully primed pipe destroys the synergy in instruction execution, the compiler may protect a software pipelining operation by disabling interrupts before entering the pipelined section and enabling interrupts on the way out (Figure 6.34).
"In a multithreaded system , if you disable interrupts, that means timer interrupts are also disabled.. and then a scheduler works on a timer only... so if the timer interrupt is disabled, it will not expire the scheduler and it will not find any task to schedule... and then again if interrupts are disabled, then no ...
The "di instruction" and "ei instruction" of the assembler instruction can be used to disable an interrupt locally in a function described in C language.
The whole 'going to sleep' sequence in the main loop is split into two steps:
The WFI instruction will act as a NOP if there are some interrupt flags still set, which allows the main loop to go back running the required tasks. So far so good.
There's a problem though if an interrupt occurs right after step 1 and before step 2. If that happens then the interrupt flags will be cleared upon exiting the ISR, and when control goes back to the main loop it will hit the WFI instruction with all interrupt flags cleared, causing the CPU to go into sleep before the main loop has had a chance to execute whatever tasks were required by the ISR.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With