aboutsummaryrefslogtreecommitdiffstats
path: root/os/ports/GCC
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-16 19:56:47 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-16 19:56:47 +0000
commit51875dac89e323d1a0eebc301a2122903bbb58ba (patch)
tree15400c71298bc5a48d2c4719cff2a5b3043ff6f2 /os/ports/GCC
parent527c75dbcde62e2a0bb5739f8d4eed8389ca96bf (diff)
downloadChibiOS-51875dac89e323d1a0eebc301a2122903bbb58ba.tar.gz
ChibiOS-51875dac89e323d1a0eebc301a2122903bbb58ba.tar.bz2
ChibiOS-51875dac89e323d1a0eebc301a2122903bbb58ba.zip
Fixed bug 3317500, retested impacted ports.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3047 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/ports/GCC')
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v6m.c29
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v7m.c8
2 files changed, 17 insertions, 20 deletions
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c
index 18082e86f..2183a9ded 100644
--- a/os/ports/GCC/ARMCMx/chcore_v6m.c
+++ b/os/ports/GCC/ARMCMx/chcore_v6m.c
@@ -90,7 +90,8 @@ __attribute__((naked))
#endif
void _port_switch_from_isr(void) {
- chSchDoRescheduleI();
+ if (chSchIsRescRequiredExI())
+ chSchDoRescheduleI();
#if CORTEX_ALTERNATE_SWITCH
SCB_ICSR = ICSR_PENDSVSET;
port_unlock();
@@ -153,22 +154,18 @@ void _port_switch(Thread *ntp, Thread *otp) {
void _port_irq_epilogue(regarm_t lr) {
if (lr != (regarm_t)0xFFFFFFF1) {
+ register struct extctx *ctxp;
+
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();
+ /* 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.*/
}
}
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c
index 2cf5cfe6b..897c90a96 100644
--- a/os/ports/GCC/ARMCMx/chcore_v7m.c
+++ b/os/ports/GCC/ARMCMx/chcore_v7m.c
@@ -110,12 +110,12 @@ void PendSVVector(void) {
#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
- * @brief Reschedule verification and setup after an IRQ.
+ * @brief Exception exit redirection to _port_switch_from_isr().
*/
void _port_irq_epilogue(void) {
port_lock_from_isr();
- if ((SCB_ICSR & ICSR_RETTOBASE) && chSchIsRescRequiredExI()) {
+ if ((SCB_ICSR & ICSR_RETTOBASE)) {
register struct extctx *ctxp;
/* Adding an artificial exception return context, there is no need to
@@ -129,7 +129,6 @@ void _port_irq_epilogue(void) {
order to keep the rest of the context switching atomic.*/
return;
}
- /* ISR exit without context switching.*/
port_unlock_from_isr();
}
@@ -142,7 +141,8 @@ __attribute__((naked))
#endif
void _port_switch_from_isr(void) {
- chSchDoRescheduleI();
+ if (chSchIsRescRequiredExI())
+ chSchDoRescheduleI();
#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
asm volatile ("svc #0");
#else /* CORTEX_SIMPLIFIED_PRIORITY */