diff --git a/arch/arm/src/armv6-m/arm_doirq.c b/arch/arm/src/armv6-m/arm_doirq.c index 4ee54a70bcf..b1a7e39e880 100644 --- a/arch/arm/src/armv6-m/arm_doirq.c +++ b/arch/arm/src/armv6-m/arm_doirq.c @@ -85,15 +85,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) /* Dispatch the PendSV interrupt */ irq_dispatch(irq, regs); -#endif -#ifdef CONFIG_ENABLE_ALL_SIGNALS - if (tcb->sigdeliver) - { - /* Pendsv able to access running tcb with no critical section */ - - up_schedule_sigaction(tcb); - } - #endif up_irq_save(); } @@ -104,6 +95,13 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) tcb = this_task(); +#ifdef CONFIG_ENABLE_ALL_SIGNALS + if (tcb->sigdeliver) + { + up_schedule_sigaction(tcb); + } +#endif + /* Update scheduler parameters. * The arm-m architecture svc call will trigger an interrupt, * and the actual context switch is executed after doirq is completed, diff --git a/arch/arm/src/armv6-m/arm_schedulesigaction.c b/arch/arm/src/armv6-m/arm_schedulesigaction.c index 0e51f0c5bcd..69cb9bd5c73 100644 --- a/arch/arm/src/armv6-m/arm_schedulesigaction.c +++ b/arch/arm/src/armv6-m/arm_schedulesigaction.c @@ -86,6 +86,11 @@ void up_schedule_sigaction(struct tcb_s *tcb) struct tcb_s *rtcb = running_task(); uint32_t ipsr = getipsr(); + if (tcb->xcp.saved_regs != NULL) + { + return; + } + /* First, handle some special cases when the signal is * being delivered to the currently executing task. */ diff --git a/arch/arm/src/armv6-m/arm_sigdeliver.c b/arch/arm/src/armv6-m/arm_sigdeliver.c index f61d216c6e7..ce43e27fff7 100644 --- a/arch/arm/src/armv6-m/arm_sigdeliver.c +++ b/arch/arm/src/armv6-m/arm_sigdeliver.c @@ -165,6 +165,7 @@ retry: g_running_tasks[this_cpu()] = NULL; rtcb->xcp.regs = rtcb->xcp.saved_regs; + rtcb->xcp.saved_regs = NULL; arm_fullcontextrestore(); UNUSED(regs); } diff --git a/arch/arm/src/armv7-m/arm_doirq.c b/arch/arm/src/armv7-m/arm_doirq.c index 9d22058ea0a..a70e909c167 100644 --- a/arch/arm/src/armv7-m/arm_doirq.c +++ b/arch/arm/src/armv7-m/arm_doirq.c @@ -85,15 +85,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) /* Dispatch the PendSV interrupt */ irq_dispatch(irq, regs); -#endif -#ifdef CONFIG_ENABLE_ALL_SIGNALS - if (tcb->sigdeliver) - { - /* Pendsv able to access running tcb with no critical section */ - - up_schedule_sigaction(tcb); - } - #endif up_irq_save(); @@ -105,6 +96,13 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) tcb = this_task(); +#ifdef CONFIG_ENABLE_ALL_SIGNALS + if (tcb->sigdeliver) + { + up_schedule_sigaction(tcb); + } +#endif + /* Update scheduler parameters. * The arm-m architecture svc call will trigger an interrupt, * and the actual context switch is executed after doirq is completed, diff --git a/arch/arm/src/armv7-m/arm_schedulesigaction.c b/arch/arm/src/armv7-m/arm_schedulesigaction.c index db570847049..75e8783ff25 100644 --- a/arch/arm/src/armv7-m/arm_schedulesigaction.c +++ b/arch/arm/src/armv7-m/arm_schedulesigaction.c @@ -87,6 +87,11 @@ void up_schedule_sigaction(struct tcb_s *tcb) struct tcb_s *rtcb = running_task(); uint32_t ipsr = getipsr(); + if (tcb->xcp.saved_regs != NULL) + { + return; + } + /* First, handle some special cases when the signal is * being delivered to the currently executing task. */ diff --git a/arch/arm/src/armv7-m/arm_sigdeliver.c b/arch/arm/src/armv7-m/arm_sigdeliver.c index 02b17525288..2ac5aeada24 100644 --- a/arch/arm/src/armv7-m/arm_sigdeliver.c +++ b/arch/arm/src/armv7-m/arm_sigdeliver.c @@ -189,6 +189,7 @@ retry: } rtcb->xcp.regs = rtcb->xcp.saved_regs; + rtcb->xcp.saved_regs = NULL; arm_fullcontextrestore(); UNUSED(regs); } diff --git a/arch/arm/src/armv8-m/arm_doirq.c b/arch/arm/src/armv8-m/arm_doirq.c index a327eeabd7a..e5ca07a4438 100644 --- a/arch/arm/src/armv8-m/arm_doirq.c +++ b/arch/arm/src/armv8-m/arm_doirq.c @@ -97,15 +97,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) /* Dispatch the PendSV interrupt */ irq_dispatch(irq, regs); -#endif -#ifdef CONFIG_ENABLE_ALL_SIGNALS - if (tcb->sigdeliver) - { - /* Pendsv able to access running tcb with no critical section */ - - up_schedule_sigaction(tcb); - } - #endif up_irq_save(); @@ -117,6 +108,13 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) tcb = this_task(); +#ifdef CONFIG_ENABLE_ALL_SIGNALS + if (tcb->sigdeliver) + { + up_schedule_sigaction(tcb); + } +#endif + /* Update scheduler parameters. * The arm-m architecture svc call will trigger an interrupt, * and the actual context switch is executed after doirq is completed, diff --git a/arch/arm/src/armv8-m/arm_schedulesigaction.c b/arch/arm/src/armv8-m/arm_schedulesigaction.c index a24d8fb8f12..8a166eff217 100644 --- a/arch/arm/src/armv8-m/arm_schedulesigaction.c +++ b/arch/arm/src/armv8-m/arm_schedulesigaction.c @@ -87,6 +87,11 @@ void up_schedule_sigaction(struct tcb_s *tcb) struct tcb_s *rtcb = running_task(); uint32_t ipsr = getipsr(); + if (tcb->xcp.saved_regs != NULL) + { + return; + } + /* First, handle some special cases when the signal is * being delivered to the currently executing task. */ diff --git a/arch/arm/src/armv8-m/arm_sigdeliver.c b/arch/arm/src/armv8-m/arm_sigdeliver.c index 39e1b0d3be9..5904b4e028e 100644 --- a/arch/arm/src/armv8-m/arm_sigdeliver.c +++ b/arch/arm/src/armv8-m/arm_sigdeliver.c @@ -189,6 +189,7 @@ retry: } rtcb->xcp.regs = rtcb->xcp.saved_regs; + rtcb->xcp.saved_regs = NULL; arm_fullcontextrestore(); UNUSED(regs); }