Skip to content

Commit

Permalink
cortexm_common: disable IRQ during thread_sched_idle
Browse files Browse the repository at this point in the history
A race condition is present where an IRQ is serviced between the
priority increase of the PENDSV and the sleep. When the IRQ
is serviced before the WFI sleep, the core will sleep until the next
IRQ and the thread activated by the IRQ will not be scheduled until
a new IRQ triggers.

This commit wraps an IRQ disable and restore around the priority
modification and sleep to prevent interrupts from being serviced until
the WFI call returns.

(cherry picked from commit eec7aa2)
  • Loading branch information
bergzand committed Jul 16, 2020
1 parent 172a3ba commit d023c70
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cpu/cortexm_common/thread_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ void sched_arch_idle(void)
* According to [this](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0321a/BIHJICIE.html),
* dynamically changing the priority is not supported on CortexM0(+).
*/
unsigned state = irq_disable();
NVIC_SetPriority(PendSV_IRQn, CPU_CORTEXM_PENDSV_IRQ_PRIO + 1);
__DSB();
__ISB();
Expand All @@ -469,5 +470,6 @@ void sched_arch_idle(void)
#else
__WFI();
#endif
irq_restore(state);
NVIC_SetPriority(PendSV_IRQn, CPU_CORTEXM_PENDSV_IRQ_PRIO);
}

0 comments on commit d023c70

Please sign in to comment.