diff --git a/cpu/cortexm_common/Kconfig b/cpu/cortexm_common/Kconfig index 245a979429..271d23c0ed 100644 --- a/cpu/cortexm_common/Kconfig +++ b/cpu/cortexm_common/Kconfig @@ -13,11 +13,13 @@ config CPU_ARCH_ARMV7M bool select HAS_ARCH_ARM select HAS_ARCH_32BIT + select HAS_NO_IDLE_THREAD config CPU_ARCH_ARMV8M bool select HAS_ARCH_ARM select HAS_ARCH_32BIT + select HAS_NO_IDLE_THREAD config CPU_ARCH default "armv6m" if CPU_ARCH_ARMV6M diff --git a/cpu/cortexm_common/Makefile.features b/cpu/cortexm_common/Makefile.features index 974d78d606..eef3d0ea8e 100644 --- a/cpu/cortexm_common/Makefile.features +++ b/cpu/cortexm_common/Makefile.features @@ -30,3 +30,8 @@ else ifeq ($(CPU_CORE),cortex-m23) 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 diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index 914fd15280..16c5efcef6 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -446,3 +446,24 @@ void __attribute__((used)) isr_svc(void) SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; } #endif /* MODULE_CORTEXM_SVC */ + +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(+). + */ + 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 + NVIC_SetPriority(PendSV_IRQn, CPU_CORTEXM_PENDSV_IRQ_PRIO); +}