aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/common/ports/ARMCMx/chcore_v6m.c32
-rw-r--r--os/common/ports/ARMCMx/chcore_v6m.h16
-rw-r--r--readme.txt1
3 files changed, 18 insertions, 31 deletions
diff --git a/os/common/ports/ARMCMx/chcore_v6m.c b/os/common/ports/ARMCMx/chcore_v6m.c
index 62daff813..5e43cb01a 100644
--- a/os/common/ports/ARMCMx/chcore_v6m.c
+++ b/os/common/ports/ARMCMx/chcore_v6m.c
@@ -107,15 +107,16 @@ void PendSV_Handler(void) {
*
* @param[in] lr value of the @p LR register on ISR entry
*/
-void _port_irq_epilogue(regarm_t lr) {
+void _port_irq_epilogue(void) {
+ struct port_extctx *ctxp;
- if (lr != (regarm_t)0xFFFFFFF1U) {
- struct port_extctx *ctxp;
+ port_lock_from_isr();
- port_lock_from_isr();
-
- /* The extctx structure is pointed by the PSP register.*/
- ctxp = (struct port_extctx *)__get_PSP();
+ /* Checking if the artificial exception return context has already been
+ added.*/
+ ctxp = (struct port_extctx *)__get_PSP();
+ if ((ctxp->pc != (regarm_t)_port_switch_from_isr) &&
+ chSchIsPreemptionRequired()) {
/* Adding an artificial exception return context, there is no need to
populate it fully.*/
@@ -127,21 +128,16 @@ void _port_irq_epilogue(regarm_t lr) {
/* Setting up a fake XPSR register value.*/
ctxp->xpsr = (regarm_t)0x01000000;
- /* The exit sequence is different depending on if a preemption is
- required or not.*/
- if (chSchIsPreemptionRequired()) {
- /* Preemption is required we need to enforce a context switch.*/
- ctxp->pc = (regarm_t)_port_switch_from_isr;
- }
- else {
- /* Preemption not required, we just need to exit the exception
- atomically.*/
- ctxp->pc = (regarm_t)_port_exit_from_isr;
- }
+ /* Return address set to OS code, there context switch will be
+ performed.*/
+ ctxp->pc = (regarm_t)_port_switch_from_isr;
/* Note, returning without unlocking is intentional, this is done in
order to keep the rest of the context switch atomic.*/
+ return;
}
+
+ port_unlock_from_isr();
}
/** @} */
diff --git a/os/common/ports/ARMCMx/chcore_v6m.h b/os/common/ports/ARMCMx/chcore_v6m.h
index d895f84a8..3d640506b 100644
--- a/os/common/ports/ARMCMx/chcore_v6m.h
+++ b/os/common/ports/ARMCMx/chcore_v6m.h
@@ -246,23 +246,14 @@ struct port_intctx {
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
*/
-#if defined(__GNUC__) || defined(__DOXYGEN__)
-#define PORT_IRQ_PROLOGUE() \
- regarm_t _saved_lr = (regarm_t)__builtin_return_address(0)
-#elif defined(__ICCARM__)
-#define PORT_IRQ_PROLOGUE() \
- regarm_t _saved_lr = (regarm_t)__get_LR()
-#elif defined(__CC_ARM)
-#define PORT_IRQ_PROLOGUE() \
- regarm_t _saved_lr = (regarm_t)__return_address()
-#endif
+#define PORT_IRQ_PROLOGUE()
/**
* @brief IRQ epilogue code.
* @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr)
+#define PORT_IRQ_EPILOGUE() _port_irq_epilogue()
/**
* @brief IRQ handler function declaration.
@@ -307,11 +298,10 @@ struct port_intctx {
#ifdef __cplusplus
extern "C" {
#endif
- void _port_irq_epilogue(regarm_t lr);
+ void _port_irq_epilogue(void);
void _port_switch(thread_t *ntp, thread_t *otp);
void _port_thread_start(void);
void _port_switch_from_isr(void);
- void _port_exit_from_isr(void);
#ifdef __cplusplus
}
#endif
diff --git a/readme.txt b/readme.txt
index 91b110754..d8d022a21 100644
--- a/readme.txt
+++ b/readme.txt
@@ -160,6 +160,7 @@
- EX: Updated LIS302DL to 1.1.0 (backported to 18.2.1).
- EX: Updated LPS25H to 1.1.0 (backported to 18.2.1).
- EX: Updated LSM303DLHC to 1.1.0 (backported to 18.2.1).
+- RT: Fixed GCC6 problem breaks Cortex-M0 port (bug #985).
- NIL: Fixed scheduler misbehaving in rare cases (bug #983)
(backported to 18.2.2 and 17.6.5).
- NIL: Fixed function chThdSuspendTimeoutS() ignoring TIME_IMMEDIATE (bug #982)