From c05ba6901bbbd269198512737431650876a81764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Mon, 13 Apr 2026 11:33:46 -0400 Subject: [PATCH 1/5] Fix race condition and message loss in Cortex-M GNU ports (#516) - Added compiler memory barriers to BASEPRI management functions in tx_port.h. - Added architectural barriers (DSB/ISB) to scheduler return paths in tx_port.h and tx_thread_system_return.S to prevent fall-through before context switch. - These changes address spurious thread resumption and lost messages, especially when TX_NOT_INTERRUPTABLE is enabled. Assisted-by: Gemini (Gemini 2.0 Flash) --- ports/cortex_m0/gnu/inc/tx_port.h | 3 +++ ports/cortex_m0/gnu/src/tx_thread_system_return.S | 15 ++++++++++----- ports/cortex_m23/gnu/inc/tx_port.h | 3 +++ .../cortex_m23/gnu/src/tx_thread_system_return.S | 4 ++++ ports/cortex_m3/gnu/inc/tx_port.h | 6 ++++-- ports/cortex_m3/gnu/src/tx_thread_system_return.S | 4 ++++ ports/cortex_m33/gnu/inc/tx_port.h | 5 ++++- .../cortex_m33/gnu/src/tx_thread_system_return.S | 4 ++++ ports/cortex_m4/gnu/inc/tx_port.h | 10 +++++++--- ports/cortex_m4/gnu/src/tx_thread_system_return.S | 4 ++++ ports/cortex_m55/gnu/inc/tx_port.h | 6 +++++- .../cortex_m55/gnu/src/tx_thread_system_return.S | 4 ++++ ports/cortex_m7/gnu/inc/tx_port.h | 12 ++++++++---- ports/cortex_m7/gnu/src/tx_thread_system_return.S | 4 ++++ ports/cortex_m85/gnu/inc/tx_port.h | 6 +++++- .../cortex_m85/gnu/src/tx_thread_system_return.S | 4 ++++ 16 files changed, 77 insertions(+), 17 deletions(-) diff --git a/ports/cortex_m0/gnu/inc/tx_port.h b/ports/cortex_m0/gnu/inc/tx_port.h index 9b315869f..2c4ab1bbb 100644 --- a/ports/cortex_m0/gnu/inc/tx_port.h +++ b/ports/cortex_m0/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -322,6 +324,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_primask_value(); diff --git a/ports/cortex_m0/gnu/src/tx_thread_system_return.S b/ports/cortex_m0/gnu/src/tx_thread_system_return.S index d798994ea..d330d979f 100644 --- a/ports/cortex_m0/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m0/gnu/src/tx_thread_system_return.S @@ -5,11 +5,14 @@ @ * terms of the MIT License which is available at @ * https://opensource.org/licenses/MIT. @ * -@ * SPDX-License-Identifier: MIT -@ **************************************************************************/ -@ -@ -@/**************************************************************************/ +* SPDX-License-Identifier: MIT +**************************************************************************/ + +// Some portions generated by Gemini (Gemini 2.0 Flash). + + +/**************************************************************************/ + @/**************************************************************************/ @/** */ @/** ThreadX Component */ @@ -72,6 +75,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 @ Load PENDSVSET bit LDR r1, =0xE000ED04 @ Load NVIC base STR r0, [r1] @ Set PENDSVBIT in ICSR + DSB #0xF @ Ensure memory access is complete + ISB #0xF @ Flush pipeline MRS r0, IPSR @ Pickup IPSR CMP r0, #0 @ Is it a thread returning? BNE _isr_context @ If ISR, skip interrupt enable diff --git a/ports/cortex_m23/gnu/inc/tx_port.h b/ports/cortex_m23/gnu/inc/tx_port.h index b1eab9e38..0967f811d 100644 --- a/ports/cortex_m23/gnu/inc/tx_port.h +++ b/ports/cortex_m23/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -389,6 +391,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_get_ipsr() == 0) { interrupt_save = __get_primask_value(); diff --git a/ports/cortex_m23/gnu/src/tx_thread_system_return.S b/ports/cortex_m23/gnu/src/tx_thread_system_return.S index a14fdba3a..c4eb97a35 100644 --- a/ports/cortex_m23/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m23/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 // Load PENDSVSET bit LDR r1, =0xE000ED04 // Load ICSR address STR r0, [r1] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m3/gnu/inc/tx_port.h b/ports/cortex_m3/gnu/inc/tx_port.h index 23affb8bf..38b837a9a 100644 --- a/ports/cortex_m3/gnu/inc/tx_port.h +++ b/ports/cortex_m3/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,7 +541,7 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -552,7 +554,6 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsign { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +579,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m3/gnu/src/tx_thread_system_return.S b/ports/cortex_m3/gnu/src/tx_thread_system_return.S index 9d9a32fc9..a33fa57fb 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m3/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m33/gnu/inc/tx_port.h b/ports/cortex_m33/gnu/inc/tx_port.h index 727e9fce5..e97275d0a 100644 --- a/ports/cortex_m33/gnu/inc/tx_port.h +++ b/ports/cortex_m33/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -541,7 +543,7 @@ UINT posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -579,6 +581,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m33/gnu/src/tx_thread_system_return.S b/ports/cortex_m33/gnu/src/tx_thread_system_return.S index 17db56a59..3596f029e 100644 --- a/ports/cortex_m33/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m33/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m4/gnu/inc/tx_port.h b/ports/cortex_m4/gnu/inc/tx_port.h index 7c2b04c58..73ee6760d 100644 --- a/ports/cortex_m4/gnu/inc/tx_port.h +++ b/ports/cortex_m4/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,9 +541,10 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); @@ -552,7 +555,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsign { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +581,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m4/gnu/src/tx_thread_system_return.S b/ports/cortex_m4/gnu/src/tx_thread_system_return.S index 8c4a09fd1..975d16637 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m4/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m55/gnu/inc/tx_port.h b/ports/cortex_m55/gnu/inc/tx_port.h index a70426fa6..bf9bf05b0 100644 --- a/ports/cortex_m55/gnu/inc/tx_port.h +++ b/ports/cortex_m55/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -541,7 +543,7 @@ UINT posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -554,6 +556,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT i { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -579,6 +582,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m55/gnu/src/tx_thread_system_return.S b/ports/cortex_m55/gnu/src/tx_thread_system_return.S index 0fc717b99..38e6a4e74 100644 --- a/ports/cortex_m55/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m55/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m7/gnu/inc/tx_port.h b/ports/cortex_m7/gnu/inc/tx_port.h index 48a34cfa4..2dabe3c4e 100644 --- a/ports/cortex_m7/gnu/inc/tx_port.h +++ b/ports/cortex_m7/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,25 +541,26 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif } + __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { unsigned int int_posture; @@ -578,6 +581,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m7/gnu/src/tx_thread_system_return.S b/ports/cortex_m7/gnu/src/tx_thread_system_return.S index ce5a3f46f..baf8f5110 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m7/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m85/gnu/inc/tx_port.h b/ports/cortex_m85/gnu/inc/tx_port.h index 9057a1324..f23309fd9 100644 --- a/ports/cortex_m85/gnu/inc/tx_port.h +++ b/ports/cortex_m85/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -541,7 +543,7 @@ UINT posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -554,6 +556,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT i { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -579,6 +582,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m85/gnu/src/tx_thread_system_return.S b/ports/cortex_m85/gnu/src/tx_thread_system_return.S index bbb5a6303..9c19e13df 100644 --- a/ports/cortex_m85/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m85/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable From 6c45adf75961b508a6c90e930f53ecceba49f6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Mon, 13 Apr 2026 11:38:42 -0400 Subject: [PATCH 2/5] Fix race condition and message loss in Cortex-M AC6 ports (#516) - Added compiler memory barriers to BASEPRI management functions in tx_port.h. - Added architectural barriers (DSB/ISB) to scheduler return paths in tx_port.h and tx_thread_system_return.S to prevent fall-through before context switch. - These changes address spurious thread resumption and lost messages, especially when TX_NOT_INTERRUPTABLE is enabled. Assisted-by: Gemini (Gemini 2.0 Flash) --- ports/cortex_m3/ac6/inc/tx_port.h | 12 +++++---- .../ac6/src/tx_thread_system_return.S | 4 +++ ports/cortex_m33/ac6/inc/tx_port.h | 6 ++++- .../ac6/src/tx_thread_system_return.S | 4 +++ ports/cortex_m4/ac6/inc/tx_port.h | 26 ++++++++++++++++--- .../ac6/src/tx_thread_system_return.S | 4 +++ 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/ports/cortex_m3/ac6/inc/tx_port.h b/ports/cortex_m3/ac6/inc/tx_port.h index 0a25ae64f..32604f3cf 100644 --- a/ports/cortex_m3/ac6/inc/tx_port.h +++ b/ports/cortex_m3/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m3/ac6/src/tx_thread_system_return.S b/ports/cortex_m3/ac6/src/tx_thread_system_return.S index e1c5c2a2c..a8654f6ba 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m3/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m33/ac6/inc/tx_port.h b/ports/cortex_m33/ac6/inc/tx_port.h index e2a8f6e6a..a706ff62f 100644 --- a/ports/cortex_m33/ac6/inc/tx_port.h +++ b/ports/cortex_m33/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -541,7 +543,7 @@ UINT posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -554,6 +556,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT i { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -579,6 +582,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m33/ac6/src/tx_thread_system_return.S b/ports/cortex_m33/ac6/src/tx_thread_system_return.S index 3c97b666f..e57b28ea2 100644 --- a/ports/cortex_m33/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m33/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m4/ac6/inc/tx_port.h b/ports/cortex_m4/ac6/inc/tx_port.h index fa109c522..c35bb424a 100644 --- a/ports/cortex_m4/ac6/inc/tx_port.h +++ b/ports/cortex_m4/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -574,6 +576,22 @@ unsigned int int_posture; __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ diff --git a/ports/cortex_m4/ac6/src/tx_thread_system_return.S b/ports/cortex_m4/ac6/src/tx_thread_system_return.S index b4348f9db..4c5068ee9 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m4/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable From 5819e64aaf77055ffa87c7978d156c05e87aa8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Mon, 13 Apr 2026 11:39:02 -0400 Subject: [PATCH 3/5] Fix race condition and message loss in Cortex-M IAR ports (#516) - Added compiler memory barriers to BASEPRI management functions in tx_port.h. - Added architectural barriers (DSB/ISB) to scheduler return paths in tx_port.h and tx_thread_system_return.s to prevent fall-through before context switch. - These changes address spurious thread resumption and lost messages, especially when TX_NOT_INTERRUPTABLE is enabled. Assisted-by: Gemini (Gemini 2.0 Flash) --- ports/cortex_m33/iar/inc/tx_port.h | 6 ++++- .../iar/src/tx_thread_system_return.s | 27 +++++++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ports/cortex_m33/iar/inc/tx_port.h b/ports/cortex_m33/iar/inc/tx_port.h index 62f20620a..6298ddcb0 100644 --- a/ports/cortex_m33/iar/inc/tx_port.h +++ b/ports/cortex_m33/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -541,7 +543,7 @@ UINT posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -554,6 +556,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT i { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -579,6 +582,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m33/iar/src/tx_thread_system_return.s b/ports/cortex_m33/iar/src/tx_thread_system_return.s index 442e0e141..83eb4a66a 100644 --- a/ports/cortex_m33/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m33/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * Copyright (c) 2026-present Eclipse ThreadX contributors - * - * This program and the accompanying materials are made available under the - * terms of the MIT License which is available at - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* Copyright (c) 2024 Microsoft Corporation +;* Copyright (c) 2026-present Eclipse ThreadX contributors +;* +;* This program and the accompanying materials are made available under the +;* terms of the MIT License which is available at +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -69,6 +72,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable From 5b3ac329a33d1f592e81f4ed40ef1560471ea9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Tue, 14 Apr 2026 16:56:36 -0400 Subject: [PATCH 4/5] Fix race condition and message loss in additional Cortex-M AC6 ports (#516) - Added compiler memory barriers to BASEPRI management functions in tx_port.h (M7). - Added architectural barriers (DSB/ISB) to scheduler return paths in tx_port.h and tx_thread_system_return.S (M7, M23) to prevent fall-through before context switch. - These changes address spurious thread resumption and lost messages, especially when TX_NOT_INTERRUPTABLE is enabled. Assisted-by: Gemini (Gemini 2.0 Flash) --- ports/cortex_m23/ac6/inc/tx_port.h | 3 +++ ports/cortex_m23/ac6/src/tx_thread_system_return.S | 4 ++++ ports/cortex_m7/ac6/inc/tx_port.h | 12 +++++++----- ports/cortex_m7/ac6/src/tx_thread_system_return.S | 4 ++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ports/cortex_m23/ac6/inc/tx_port.h b/ports/cortex_m23/ac6/inc/tx_port.h index 5ae0b62b0..2140af537 100644 --- a/ports/cortex_m23/ac6/inc/tx_port.h +++ b/ports/cortex_m23/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -376,6 +378,7 @@ unsigned int was_masked; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_get_ipsr() == 0) { was_masked = __disable_irq(); diff --git a/ports/cortex_m23/ac6/src/tx_thread_system_return.S b/ports/cortex_m23/ac6/src/tx_thread_system_return.S index d85981da1..c0bfe023d 100644 --- a/ports/cortex_m23/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m23/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 // Load PENDSVSET bit LDR r1, =0xE000ED04 // Load ICSR address STR r0, [r1] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m7/ac6/inc/tx_port.h b/ports/cortex_m7/ac6/inc/tx_port.h index d3b3bb019..d8c2b51e7 100644 --- a/ports/cortex_m7/ac6/inc/tx_port.h +++ b/ports/cortex_m7/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m7/ac6/src/tx_thread_system_return.S b/ports/cortex_m7/ac6/src/tx_thread_system_return.S index 831c00e4c..a092e34c8 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m7/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable From 5a845a064ce6ef69f986236b7111594ccfc22c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Tue, 14 Apr 2026 17:36:10 -0400 Subject: [PATCH 5/5] Fix race condition and message loss in all remaining Cortex-M IAR ports (#516) - Added compiler memory barriers to BASEPRI management functions in tx_port.h (M3, M4, M7, M55, M85). - Added architectural barriers (DSB/ISB) to scheduler return paths in tx_port.h and tx_thread_system_return.s (all architectures) to prevent fall-through before context switch. - Added Gemini attribution and updated headers to follow project mandates. - These changes address spurious thread resumption and lost messages, especially when TX_NOT_INTERRUPTABLE is enabled. Assisted-by: Gemini (Gemini 2.0 Flash) --- ports/cortex_m0/iar/inc/tx_port.h | 1 + .../iar/src/tx_thread_system_return.s | 7 ++++- ports/cortex_m23/iar/inc/tx_port.h | 1 + .../iar/src/tx_thread_system_return.s | 27 +++++++++++-------- ports/cortex_m3/iar/inc/tx_port.h | 12 +++++---- .../iar/src/tx_thread_system_return.s | 27 +++++++++++-------- ports/cortex_m4/iar/inc/tx_port.h | 12 +++++---- .../iar/src/tx_thread_system_return.s | 27 +++++++++++-------- ports/cortex_m55/iar/inc/tx_port.h | 1 + .../iar/src/tx_thread_system_return.s | 27 +++++++++++-------- ports/cortex_m7/iar/inc/tx_port.h | 12 +++++---- .../iar/src/tx_thread_system_return.s | 27 +++++++++++-------- ports/cortex_m85/iar/inc/tx_port.h | 5 +++- .../iar/src/tx_thread_system_return.s | 27 +++++++++++-------- 14 files changed, 130 insertions(+), 83 deletions(-) diff --git a/ports/cortex_m0/iar/inc/tx_port.h b/ports/cortex_m0/iar/inc/tx_port.h index af5f58bb8..c92c71f81 100644 --- a/ports/cortex_m0/iar/inc/tx_port.h +++ b/ports/cortex_m0/iar/inc/tx_port.h @@ -313,6 +313,7 @@ __istate_t interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_IPSR() == 0) { interrupt_save = __get_interrupt_state(); diff --git a/ports/cortex_m0/iar/src/tx_thread_system_return.s b/ports/cortex_m0/iar/src/tx_thread_system_return.s index da8a481ea..9426a137d 100644 --- a/ports/cortex_m0/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m0/iar/src/tx_thread_system_return.s @@ -1,5 +1,6 @@ -;/*************************************************************************** +;*************************************************************************** ; * Copyright (c) 2024 Microsoft Corporation +; * Copyright (c) 2026-present Eclipse ThreadX contributors ; * ; * This program and the accompanying materials are made available under the ; * terms of the MIT License which is available at @@ -7,6 +8,8 @@ ; * ; * SPDX-License-Identifier: MIT ; **************************************************************************/ + +; Some portions generated by Gemini (Gemini 2.0 Flash). ; ; ;/**************************************************************************/ @@ -68,6 +71,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 ; Load PENDSVSET bit LDR r1, =0xE000ED04 ; Load NVIC base STR r0, [r1] ; Set PENDSVBIT in ICSR + DSB SY ; Ensure memory access is complete + ISB SY ; Flush pipeline MRS r0, IPSR ; Pickup IPSR CMP r0, #0 ; Is it a thread returning? BNE _isr_context ; If ISR, skip interrupt enable diff --git a/ports/cortex_m23/iar/inc/tx_port.h b/ports/cortex_m23/iar/inc/tx_port.h index be6bebd55..dee22f50c 100644 --- a/ports/cortex_m23/iar/inc/tx_port.h +++ b/ports/cortex_m23/iar/inc/tx_port.h @@ -399,6 +399,7 @@ __istate_t interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_IPSR() == 0) { interrupt_save = __get_interrupt_state(); diff --git a/ports/cortex_m23/iar/src/tx_thread_system_return.s b/ports/cortex_m23/iar/src/tx_thread_system_return.s index 91ef52c72..da4b6d045 100644 --- a/ports/cortex_m23/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m23/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * Copyright (c) 2026-present Eclipse ThreadX contributors - * - * This program and the accompanying materials are made available under the - * terms of the MIT License which is available at - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* Copyright (c) 2024 Microsoft Corporation +;* Copyright (c) 2026-present Eclipse ThreadX contributors +;* +;* This program and the accompanying materials are made available under the +;* terms of the MIT License which is available at +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -65,6 +68,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 // Load PENDSVSET bit LDR r1, =0xE000ED04 // Load ICSR address STR r0, [r1] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m3/iar/inc/tx_port.h b/ports/cortex_m3/iar/inc/tx_port.h index ff8b75ca2..1b298161b 100644 --- a/ports/cortex_m3/iar/inc/tx_port.h +++ b/ports/cortex_m3/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m3/iar/src/tx_thread_system_return.s b/ports/cortex_m3/iar/src/tx_thread_system_return.s index 712a6e5ce..8bd4ca820 100644 --- a/ports/cortex_m3/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m3/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * Copyright (c) 2026-present Eclipse ThreadX contributors - * - * This program and the accompanying materials are made available under the - * terms of the MIT License which is available at - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* Copyright (c) 2024 Microsoft Corporation +;* Copyright (c) 2026-present Eclipse ThreadX contributors +;* +;* This program and the accompanying materials are made available under the +;* terms of the MIT License which is available at +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -70,6 +73,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m4/iar/inc/tx_port.h b/ports/cortex_m4/iar/inc/tx_port.h index 1253befaf..85fe8e6e0 100644 --- a/ports/cortex_m4/iar/inc/tx_port.h +++ b/ports/cortex_m4/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m4/iar/src/tx_thread_system_return.s b/ports/cortex_m4/iar/src/tx_thread_system_return.s index 4f8b9870f..f9a668d96 100644 --- a/ports/cortex_m4/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m4/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * Copyright (c) 2026-present Eclipse ThreadX contributors - * - * This program and the accompanying materials are made available under the - * terms of the MIT License which is available at - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* Copyright (c) 2024 Microsoft Corporation +;* Copyright (c) 2026-present Eclipse ThreadX contributors +;* +;* This program and the accompanying materials are made available under the +;* terms of the MIT License which is available at +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -70,6 +73,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m55/iar/inc/tx_port.h b/ports/cortex_m55/iar/inc/tx_port.h index b8a389f55..c1b94ea0d 100644 --- a/ports/cortex_m55/iar/inc/tx_port.h +++ b/ports/cortex_m55/iar/inc/tx_port.h @@ -579,6 +579,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m55/iar/src/tx_thread_system_return.s b/ports/cortex_m55/iar/src/tx_thread_system_return.s index 2762f49e7..20493afcb 100644 --- a/ports/cortex_m55/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m55/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * Copyright (c) 2026-present Eclipse ThreadX contributors - * - * This program and the accompanying materials are made available under the - * terms of the MIT License which is available at - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* Copyright (c) 2024 Microsoft Corporation +;* Copyright (c) 2026-present Eclipse ThreadX contributors +;* +;* This program and the accompanying materials are made available under the +;* terms of the MIT License which is available at +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -69,6 +72,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m7/iar/inc/tx_port.h b/ports/cortex_m7/iar/inc/tx_port.h index 63d821bfc..14524c46e 100644 --- a/ports/cortex_m7/iar/inc/tx_port.h +++ b/ports/cortex_m7/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } -#else +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m7/iar/src/tx_thread_system_return.s b/ports/cortex_m7/iar/src/tx_thread_system_return.s index 0cef80c6f..00a07ea87 100644 --- a/ports/cortex_m7/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m7/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * Copyright (c) 2026-present Eclipse ThreadX contributors - * - * This program and the accompanying materials are made available under the - * terms of the MIT License which is available at - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* Copyright (c) 2024 Microsoft Corporation +;* Copyright (c) 2026-present Eclipse ThreadX contributors +;* +;* This program and the accompanying materials are made available under the +;* terms of the MIT License which is available at +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -70,6 +73,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable diff --git a/ports/cortex_m85/iar/inc/tx_port.h b/ports/cortex_m85/iar/inc/tx_port.h index bf2450495..409aecdd3 100644 --- a/ports/cortex_m85/iar/inc/tx_port.h +++ b/ports/cortex_m85/iar/inc/tx_port.h @@ -541,7 +541,7 @@ UINT posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -554,6 +554,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT i { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -623,3 +624,5 @@ extern CHAR _tx_version_id[]; #endif #endif + +#endif diff --git a/ports/cortex_m85/iar/src/tx_thread_system_return.s b/ports/cortex_m85/iar/src/tx_thread_system_return.s index 768262a2a..fcc87228c 100644 --- a/ports/cortex_m85/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m85/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * Copyright (c) 2026-present Eclipse ThreadX contributors - * - * This program and the accompanying materials are made available under the - * terms of the MIT License which is available at - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* Copyright (c) 2024 Microsoft Corporation +;* Copyright (c) 2026-present Eclipse ThreadX contributors +;* +;* This program and the accompanying materials are made available under the +;* terms of the MIT License which is available at +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -69,6 +72,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable