aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/reports/LPC1114-48-GCC.txt3
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v6m.c26
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v6m.h18
3 files changed, 45 insertions, 2 deletions
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. */
/*===========================================================================*/