1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cortexm_common: Enable using pendsv IRQ at lower priority

This modifies the cortex-m thread specifics to allow running the PendSV
interrupt continuously at lower priority and removes the priority
modifications during the interrupt itself. Interrupts are disabled
during the scheduling itself, but enabled briefly after the sleep to
ensure that they are handled if activated during the scheduling or the
sleep.
This commit is contained in:
Koen Zandberg 2020-07-20 10:54:17 +02:00
parent 0806b4b173
commit ba58273b04
No known key found for this signature in database
GPG Key ID: 0895A893E6D2985B
2 changed files with 7 additions and 15 deletions

View File

@ -142,7 +142,7 @@ extern "C" {
* If you want to set this, define it in your `cpu_conf.h`.
*/
#ifndef CPU_CORTEXM_PENDSV_IRQ_PRIO
#define CPU_CORTEXM_PENDSV_IRQ_PRIO (CPU_DEFAULT_IRQ_PRIO)
#define CPU_CORTEXM_PENDSV_IRQ_PRIO (UINT8_MAX)
#endif
/** @} */

View File

@ -317,7 +317,9 @@ void __attribute__((naked)) __attribute__((used)) isr_pendsv(void) {
#endif
"push {lr} \n" /* push exception return code */
"cpsid i \n" /* Disable IRQs during sched_run */
"bl sched_run \n" /* perform scheduling */
"cpsie i \n" /* Re-enable interrupts */
#if CPU_CORE_CORTEXM_FULL_THUMB
"cmp r0, r12 \n" /* if r0 == 0: (no switch required) */
@ -495,24 +497,14 @@ void __attribute__((used)) isr_svc(void)
void sched_arch_idle(void)
{
/* by default, PendSV has the same priority as other ISRs.
* In this function, we temporarily lower the priority (set higher value),
* allowing other ISRs to interrupt.
*
* 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();
#ifdef MODULE_PM_LAYERED
void pm_set_lowest(void);
pm_set_lowest();
#else
__WFI();
#endif
irq_restore(state);
NVIC_SetPriority(PendSV_IRQn, CPU_CORTEXM_PENDSV_IRQ_PRIO);
SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk;
/* Briefly re-enable IRQs to allow pending interrupts to be serviced and
* have them update the runqueue */
__enable_irq();
__disable_irq();
}