Merge pull request #14557 from bergzand/pr/cortexm_common/pendsv_priority

cortexm_common: Make no_thread_idle compatible with cortex-m0
This commit is contained in:
Kaspar Schleiser 2020-09-23 11:49:41 +02:00 committed by GitHub
commit 97a0ba33c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 9 additions and 19 deletions

View File

@ -16,6 +16,7 @@ config CPU_ARCH_ARMV6M
bool bool
select HAS_ARCH_ARM select HAS_ARCH_ARM
select HAS_ARCH_32BIT select HAS_ARCH_32BIT
select HAS_NO_IDLE_THREAD
config CPU_ARCH_ARMV7M config CPU_ARCH_ARMV7M
bool bool

View File

@ -33,9 +33,6 @@ else
$(error Unkwnown cortexm core: $(CPU_CORE)) $(error Unkwnown cortexm core: $(CPU_CORE))
endif endif
# cortex-m3 and higher don't need the idle thread FEATURES_PROVIDED += no_idle_thread
ifneq (,$(filter armv7m armv8m,$(CPU_ARCH)))
FEATURES_PROVIDED += no_idle_thread
endif
KCONFIG_ADD_CONFIG += $(RIOTCPU)/cortexm_common/cortexm_common.config KCONFIG_ADD_CONFIG += $(RIOTCPU)/cortexm_common/cortexm_common.config

View File

@ -142,7 +142,7 @@ extern "C" {
* If you want to set this, define it in your `cpu_conf.h`. * If you want to set this, define it in your `cpu_conf.h`.
*/ */
#ifndef CPU_CORTEXM_PENDSV_IRQ_PRIO #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 #endif
/** @} */ /** @} */

View File

@ -317,7 +317,9 @@ void __attribute__((naked)) __attribute__((used)) isr_pendsv(void) {
#endif #endif
"push {lr} \n" /* push exception return code */ "push {lr} \n" /* push exception return code */
"cpsid i \n" /* Disable IRQs during sched_run */
"bl sched_run \n" /* perform scheduling */ "bl sched_run \n" /* perform scheduling */
"cpsie i \n" /* Re-enable interrupts */
#if CPU_CORE_CORTEXM_FULL_THUMB #if CPU_CORE_CORTEXM_FULL_THUMB
"cmp r0, r12 \n" /* if r0 == 0: (no switch required) */ "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) 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 #ifdef MODULE_PM_LAYERED
void pm_set_lowest(void); void pm_set_lowest(void);
pm_set_lowest(); pm_set_lowest();
#else #else
__WFI(); __WFI();
#endif #endif
irq_restore(state); /* Briefly re-enable IRQs to allow pending interrupts to be serviced and
NVIC_SetPriority(PendSV_IRQn, CPU_CORTEXM_PENDSV_IRQ_PRIO); * have them update the runqueue */
SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk; __enable_irq();
__disable_irq();
} }