mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
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:
co-authored by
Copilot
parent
d5c75fd38f
commit
33efad3fee
@@ -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
|
||||
|
||||
@@ -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
|
||||
@/* } */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
// }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user