diff --git a/docs/reports/LPC1114-48-GCC.txt b/docs/reports/LPC1114-48-GCC.txt index 32ea4154e..87dd7dbbe 100644 --- a/docs/reports/LPC1114-48-GCC.txt +++ b/docs/reports/LPC1114-48-GCC.txt @@ -126,7 +126,7 @@ Settings: CLK=48, (2 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.8 (Benchmark, round robin context switching) ---- Score : 253332 ctxswc/S +--- Score : 253328 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.9 (Benchmark, I/O Queues throughput) diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index 4b4ef04f6..bb20cb4be 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -128,16 +128,18 @@ struct intctx { * enabled to invoke system APIs. */ #define PORT_IRQ_EPILOGUE() { \ - port_lock_from_isr(); \ - if ((_saved_lr != (regarm_t)0xFFFFFFF1) && chSchIsRescRequiredExI()) { \ - register struct cmxctx *ctxp; \ + if (_saved_lr != (regarm_t)0xFFFFFFF1) { \ + port_lock_from_isr(); \ + if (chSchIsRescRequiredExI()) { \ + register struct cmxctx *ctxp; \ \ - asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); \ - _port_saved_pc = ctxp->pc; \ - ctxp->pc = _port_switch_from_isr; \ - return; \ + asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); \ + _port_saved_pc = ctxp->pc; \ + ctxp->pc = _port_switch_from_isr; \ + return; \ + } \ + port_unlock_from_isr(); \ } \ - port_unlock_from_isr(); \ } /** diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.c b/os/ports/IAR/ARMCMx/chcore_v6m.c index 25b360809..d8ede674d 100644 --- a/os/ports/IAR/ARMCMx/chcore_v6m.c +++ b/os/ports/IAR/ARMCMx/chcore_v6m.c @@ -32,11 +32,6 @@ */ regarm_t _port_saved_pc; -/** - * @brief IRQ nesting counter. - */ -unsigned _port_irq_nesting; - /** * @brief System Timer vector. * @details This interrupt is used as system tick. diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.h b/os/ports/IAR/ARMCMx/chcore_v6m.h index a2d1a40d3..fdbde0641 100644 --- a/os/ports/IAR/ARMCMx/chcore_v6m.h +++ b/os/ports/IAR/ARMCMx/chcore_v6m.h @@ -118,18 +118,14 @@ struct intctx { * @details This macro must be inserted at the start of all IRQ handlers * enabled to invoke system APIs. */ -#define PORT_IRQ_PROLOGUE() { \ - port_lock_from_isr(); \ - _port_irq_nesting++; \ - port_unlock_from_isr(); \ -} +#define PORT_IRQ_PROLOGUE() regarm_t _saved_lr = (regarm_t)__get_LR() /** * @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() +#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr) /** * @brief IRQ handler function declaration. @@ -149,7 +145,6 @@ struct intctx { * @brief Port-related initialization code. */ #define port_init() { \ - _port_irq_nesting = 0; \ SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \ NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \ @@ -238,7 +233,6 @@ struct intctx { #if !defined(__DOXYGEN__) extern regarm_t _port_saved_pc; -extern unsigned _port_irq_nesting; #endif #ifdef __cplusplus @@ -246,7 +240,7 @@ extern "C" { #endif void port_halt(void); void _port_switch(Thread *ntp, Thread *otp); - void _port_irq_epilogue(void); + void _port_irq_epilogue(regarm_t lr); void _port_switch_from_isr(void); void _port_thread_start(void); #ifdef __cplusplus diff --git a/os/ports/IAR/ARMCMx/chcoreasm_v6m.s b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s index 1b8a5583c..5333d4ab9 100644 --- a/os/ports/IAR/ARMCMx/chcoreasm_v6m.s +++ b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s @@ -105,27 +105,23 @@ _port_switch_from_isr: */ PUBLIC _port_irq_epilogue _port_irq_epilogue: - push {r4, lr} + push {r3, lr} + adds r0, r0, #15 + beq stillnested cpsid i - ldr r2, =_port_irq_nesting - ldr r3, [r2] - subs r3, r3, #1 - str r3, [r2] - cmp r3, #0 - beq skipexit -notrequired - cpsie i - pop {r4, pc} -skipexit bl chSchIsRescRequiredExI cmp r0, #0 - beq notrequired - mrs r1, PSP + bne doresch + cpsie i +stillnested + pop {r3, pc} +doresch + mrs r3, PSP ldr r2, =_port_saved_pc - ldr r3, [r1, #24] - str r3, [r2] - ldr r3, =_port_switch_from_isr - str r3, [r1, #24] - pop {r4, pc} + ldr r1, [r3, #24] + str r1, [r2] + ldr r2, =_port_switch_from_isr + str r2, [r3, #24] + pop {r3, pc} END diff --git a/readme.txt b/readme.txt index 6c5174cfa..6a78aa5d2 100644 --- a/readme.txt +++ b/readme.txt @@ -69,7 +69,8 @@ ***************************************************************************** *** 2.3.0 *** -- FIX: Fixed race condition in CM0 ports (bug 3193062)(backported to 2.2.2). +- FIX: Fixed race condition in CM0 ports, the fix also improves the + ISR latency (bug 3193062)(backported to 2.2.2). - FIX: Fixed Cortex-Mx linker scripts alignment of __heap_base__, the correct alignment is now enforced at runtime into core_init() in order to make the OS integration easier (bug 3191112)(backported to 2.2.2).