From 5df4a20cbbfd99054582c127963ff0671d9eac62 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 2 Jun 2011 12:05:56 +0000 Subject: Alternate preemption mode implemented in ARMv6-M GCC port. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3011 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ports/GCC/ARMCMx/chcore_v6m.c | 26 +++++++++++++++++++++++++- os/ports/GCC/ARMCMx/chcore_v6m.h | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'os') 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. */ /*===========================================================================*/ -- cgit v1.2.3