diff options
Diffstat (limited to 'os')
| -rw-r--r-- | os/common/ports/ARMCMx/chcore_v6m.c | 32 | ||||
| -rw-r--r-- | os/common/ports/ARMCMx/chcore_v6m.h | 16 | 
2 files changed, 17 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
  | 
