diff --git a/docs/reports/LPC1114-48-GCC.txt b/docs/reports/LPC1114-48-GCC.txt index fc24856de..1701b16f4 100644 --- a/docs/reports/LPC1114-48-GCC.txt +++ b/docs/reports/LPC1114-48-GCC.txt @@ -9,6 +9,7 @@ Settings: CLK=48, (2 wait states) *** Compiler: GCC 4.3.3 *** Architecture: ARMv6-M *** Core Variant: Cortex-M0 +*** Port Info: Preemption through NMI *** Platform: LPC11xx *** Test Board: Embedded Artists LPCXpresso Base Board + LPC1114 @@ -98,7 +99,7 @@ Settings: CLK=48, (2 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.1 (Benchmark, messages #1) ---- Score : 126786 msgs/S, 253572 ctxswc/S +--- Score : 126785 msgs/S, 253570 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.2 (Benchmark, messages #2) diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c index 3574c620f..18082e86f 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.c +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -44,6 +44,7 @@ CH_IRQ_HANDLER(SysTickVector) { CH_IRQ_EPILOGUE(); } +#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) /** * @brief NMI vector. * @details The NMI vector is used for exception mode re-entering after a @@ -59,6 +60,24 @@ void NMIVector(void) { asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); port_unlock_from_isr(); } +#endif /* !CORTEX_ALTERNATE_SWITCH */ + +#if CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) +/** + * @brief PendSV vector. + * @details The PendSV vector is used for exception mode re-entering after a + * context switch. + */ +void PendSVVector(void) { + register struct extctx *ctxp; + + /* Discarding the current exception context and positioning the stack to + point to the real one.*/ + asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory"); + ctxp++; + asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); +} +#endif /* CORTEX_ALTERNATE_SWITCH */ /** * @brief Post-IRQ switch code. @@ -72,8 +91,13 @@ __attribute__((naked)) void _port_switch_from_isr(void) { chSchDoRescheduleI(); +#if CORTEX_ALTERNATE_SWITCH + SCB_ICSR = ICSR_PENDSVSET; + port_unlock(); +#else SCB_ICSR = ICSR_NMIPENDSET; - /* The following loop should never be executed, the NMI will kick in +#endif + /* The following loop should never be executed, the exception will kick in immediately.*/ while (TRUE) ; diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index e6aeabc2d..2141ee468 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -45,6 +45,15 @@ /* Port configurable parameters. */ /*===========================================================================*/ +/** + * @brief Alternate preemption method. + * @details Activating this option will make the Kernel use the PendSV + * handler for preemption instead of the NMI handler. + */ +#ifndef CORTEX_ALTERNATE_SWITCH +#define CORTEX_ALTERNATE_SWITCH FALSE +#endif + /*===========================================================================*/ /* Port derived parameters. */ /*===========================================================================*/ @@ -72,6 +81,15 @@ #define CH_CORE_VARIANT_NAME "Cortex-M1" #endif +/** + * @brief Port-specific information string. + */ +#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) +#define CH_PORT_INFO "Preemption through NMI" +#else +#define CH_PORT_INFO "Preemption through PendSV" +#endif + /*===========================================================================*/ /* Port implementation part. */ /*===========================================================================*/