diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-03-06 09:43:12 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-03-06 09:43:12 +0000 |
commit | 30c73db82fbd034b89094dd58f069be43c1734d2 (patch) | |
tree | 18b5932d1778e2e1838e856528628733ad39561b /os/ports | |
parent | 18f25c97363ae944c918e2edf134ea990e3183db (diff) | |
download | ChibiOS-30c73db82fbd034b89094dd58f069be43c1734d2.tar.gz ChibiOS-30c73db82fbd034b89094dd58f069be43c1734d2.tar.bz2 ChibiOS-30c73db82fbd034b89094dd58f069be43c1734d2.zip |
More Cortex-M0 GCC port improvements.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2801 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/ports')
-rw-r--r-- | os/ports/GCC/ARMCMx/chcore_v6m.c | 27 | ||||
-rw-r--r-- | os/ports/GCC/ARMCMx/chcore_v6m.h | 22 |
2 files changed, 29 insertions, 20 deletions
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c index 5004b2256..f132697d5 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.c +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -128,6 +128,33 @@ void port_switch(Thread *ntp, Thread *otp) { }
/**
+ * @brief IRQ epilogue code.
+ *
+ * @param[in] lr value of the @p LR register on ISR entry
+ */
+void _port_irq_epilogue(regarm_t lr) {
+
+ if (lr != (regarm_t)0xFFFFFFF1) {
+ port_lock_from_isr();
+ if (chSchIsRescRequiredExI()) {
+ register struct extctx *ctxp;
+
+ /* Adding an artificial exception return context, there is no need to
+ populate it fully.*/
+ asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory");
+ ctxp--;
+ asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory");
+ ctxp->pc = _port_switch_from_isr;
+ ctxp->xpsr = (regarm_t)0x01000000;
+ /* Note, returning without unlocking is intentional, this is done in
+ order to keep the rest of the context switching atomic.*/
+ return;
+ }
+ port_unlock_from_isr();
+ }
+}
+
+/**
* @brief Start a thread by invoking its work function.
* @details If the work function returns @p chThdExit() is automatically
* invoked.
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index 4e156f4c4..4cfd7de8a 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -113,26 +113,7 @@ struct intctx { * @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() { \
- if (_saved_lr != (regarm_t)0xFFFFFFF1) { \
- port_lock_from_isr(); \
- if (chSchIsRescRequiredExI()) { \
- register struct extctx *ctxp; \
- \
- /* Adding an artificial exception return context, there is no need to \
- populate it fully.*/ \
- asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory"); \
- ctxp--; \
- asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); \
- ctxp->pc = _port_switch_from_isr; \
- ctxp->xpsr = (regarm_t)0x01000000; \
- /* Note, returning without unlocking is intentional, this is done in \
- order to keep the rest of the context switching atomic.*/ \
- return; \
- } \
- port_unlock_from_isr(); \
- } \
-}
+#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr)
/**
* @brief IRQ handler function declaration.
@@ -223,6 +204,7 @@ extern "C" { #endif
void port_halt(void);
void port_switch(Thread *ntp, Thread *otp);
+ void _port_irq_epilogue(regarm_t lr);
void _port_switch_from_isr(void);
void _port_thread_start(void);
#ifdef __cplusplus
|