diff --git a/cpu/cortexm_common/Kconfig b/cpu/cortexm_common/Kconfig index 13a67d2caa..8b9daa79c1 100644 --- a/cpu/cortexm_common/Kconfig +++ b/cpu/cortexm_common/Kconfig @@ -16,6 +16,7 @@ config CPU_ARCH_ARMV6M bool select HAS_ARCH_ARM select HAS_ARCH_32BIT + select HAS_NO_IDLE_THREAD config CPU_ARCH_ARMV7M bool diff --git a/cpu/cortexm_common/Makefile.features b/cpu/cortexm_common/Makefile.features index 7527c079d0..456647700f 100644 --- a/cpu/cortexm_common/Makefile.features +++ b/cpu/cortexm_common/Makefile.features @@ -33,9 +33,6 @@ else $(error Unkwnown cortexm core: $(CPU_CORE)) endif -# cortex-m3 and higher don't need the idle thread -ifneq (,$(filter armv7m armv8m,$(CPU_ARCH))) - FEATURES_PROVIDED += no_idle_thread -endif +FEATURES_PROVIDED += no_idle_thread KCONFIG_ADD_CONFIG += $(RIOTCPU)/cortexm_common/cortexm_common.config diff --git a/cpu/cortexm_common/include/cpu_conf_common.h b/cpu/cortexm_common/include/cpu_conf_common.h index 28e9643621..15c9bdef64 100644 --- a/cpu/cortexm_common/include/cpu_conf_common.h +++ b/cpu/cortexm_common/include/cpu_conf_common.h @@ -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 /** @} */ diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index dfbefc0d48..145372019d 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -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(); }