Fixed race condition and message loss in Cortex-M ports (#523)

* Fixed race condition and message loss in Cortex-M GNU, AC6, and 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.
- These changes ensure that pending interrupts (specifically PendSV) are recognised before subsequent instructions are executed, following Kairalite's feedback and ARM architectural guidelines.

 Assisted-by: Gemini (Gemini 2.0 Flash)

-----

* Added a comment in common/tx_queue_cleanup to document why the NI path omits revalidation guards

- In `TX_NOT_INTERRUPTABLE` mode, the caller keeps interrupts disabled across the entire cleanup call, so the race window that makes the guards necessary in the interruptable path cannot occur. Add a comment explaining this, and noting that all paths that resume a suspended thread clear tx_thread_suspend_cleanup before calling
_tx_thread_system_ni_resume, making double-cleanup impossible.

This prevents future false-positive suggestions (e.g. from AI tools) to add redundant checks to the NI path.

Relates to: eclipse-threadx/threadx#516

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Frédéric Desbiens
2026-04-29 09:10:57 -04:00
committed by GitHub
co-authored by Copilot
parent d5c75fd38f
commit 33efad3fee
43 changed files with 327 additions and 127 deletions
+13
View File
@@ -109,6 +109,19 @@ TX_THREAD *previous_thread;
{
#else
/* TX_NOT_INTERRUPTABLE path: the revalidation guards present in the
interruptable path above (cleanup pointer, suspension sequence, NULL
queue pointer, queue ID, and suspended count checks) are intentionally
omitted here. Those guards exist to handle the race window that opens
when the interruptable path calls TX_RESTORE before invoking cleanup,
allowing another context to service or abort the suspension in between.
In TX_NOT_INTERRUPTABLE mode the caller keeps interrupts disabled across
the entire cleanup call, so that race window never exists. Additionally,
every path that resumes a suspended thread (tx_queue_send, tx_queue_receive,
tx_queue_flush, tx_queue_delete) clears tx_thread_suspend_cleanup before
calling _tx_thread_system_ni_resume, making a double-cleanup impossible
under the NI serialisation guarantee. */
/* Setup pointer to queue control block. */
queue_ptr = TX_VOID_TO_QUEUE_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
#endif
+4
View File
@@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Gemini (Gemini 2.0 Flash).
/**************************************************************************/
/**************************************************************************/
@@ -322,11 +324,13 @@ 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();
__enable_interrupts();
__restore_interrupts(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -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,12 +75,15 @@ _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
MRS r1, PRIMASK @ Thread context returning, pickup PRIMASK
CPSIE i @ Enable interrupts
MSR PRIMASK, r1 @ Restore original interrupt posture
ISB #0xF @ Flush pipeline
_isr_context:
BX lr @ Return to caller
@/* } */
+1
View File
@@ -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();
@@ -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
+3
View File
@@ -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();
@@ -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
+4
View File
@@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Gemini (Gemini 2.0 Flash).
/**************************************************************************/
/**************************************************************************/
@@ -389,11 +391,13 @@ 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();
__enable_interrupts();
__restore_interrupts(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Gemini (Gemini 2.0 Flash).
/**************************************************************************/
/**************************************************************************/
@@ -74,12 +76,15 @@ _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
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
_isr_context:
BX lr // Return to caller
// }
+1
View File
@@ -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();
@@ -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
+7 -5
View File
@@ -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);
@@ -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
+5 -2
View File
@@ -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();
@@ -587,6 +589,7 @@ unsigned int interrupt_save;
__enable_interrupts();
#endif
__restore_interrupt(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -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
@@ -81,10 +85,12 @@ _tx_thread_system_return:
MOV r0, #0
MSR BASEPRI, r0 // Enable interrupts
MSR BASEPRI, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#else
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#endif
_isr_context:
BX lr // Return to caller
+7 -5
View File
@@ -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);
@@ -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
+5 -1
View File
@@ -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();
@@ -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
+5 -1
View File
@@ -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();
@@ -588,6 +591,7 @@ UINT interrupt_save;
__enable_interrupts();
#endif
__restore_interrupt(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -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
@@ -82,10 +86,12 @@ _tx_thread_system_return:
MOV r0, #0
MSR BASEPRI, r0 // Enable interrupts
MSR BASEPRI, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#else
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#endif
_isr_context:
BX lr // Return to caller
+5 -1
View File
@@ -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();
@@ -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
+22 -4
View File
@@ -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. */
@@ -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
+8 -3
View File
@@ -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();
@@ -587,6 +591,7 @@ unsigned int interrupt_save;
__enable_interrupts();
#endif
__restore_interrupt(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -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
@@ -81,10 +85,12 @@ _tx_thread_system_return:
MOV r0, #0
MSR BASEPRI, r0 // Enable interrupts
MSR BASEPRI, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#else
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#endif
_isr_context:
BX lr // Return to caller
+7 -5
View File
@@ -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);
@@ -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
+6 -1
View File
@@ -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();
@@ -588,6 +592,7 @@ UINT interrupt_save;
__enable_interrupts();
#endif
__restore_interrupt(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -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
@@ -82,10 +86,12 @@ _tx_thread_system_return:
MOV r0, #0
MSR BASEPRI, r0 // Enable interrupts
MSR BASEPRI, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#else
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#endif
_isr_context:
BX lr // Return to caller
+1
View File
@@ -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();
@@ -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
+7 -5
View File
@@ -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);
@@ -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
+9 -4
View File
@@ -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();
@@ -587,6 +591,7 @@ unsigned int interrupt_save;
__enable_interrupts();
#endif
__restore_interrupt(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -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
@@ -81,10 +85,12 @@ _tx_thread_system_return:
MOV r0, #0
MSR BASEPRI, r0 // Enable interrupts
MSR BASEPRI, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#else
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#endif
_isr_context:
BX lr // Return to caller
+7 -5
View File
@@ -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);
@@ -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
+6 -1
View File
@@ -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();
@@ -588,6 +592,7 @@ UINT interrupt_save;
__enable_interrupts();
#endif
__restore_interrupt(interrupt_save);
__asm__ volatile ("isb 0xF " : : : "memory");
}
}
@@ -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
@@ -82,10 +86,12 @@ _tx_thread_system_return:
MOV r0, #0
MSR BASEPRI, r0 // Enable interrupts
MSR BASEPRI, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#else
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
ISB #0xF // Flush pipeline
#endif
_isr_context:
BX lr // Return to caller
+4 -1
View File
@@ -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
@@ -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