Release 6.1.11

This commit is contained in:
Yuxin Zhou
2022-04-20 05:07:02 +00:00
parent f851772ce0
commit cef9cb22a5
784 changed files with 57616 additions and 101103 deletions
@@ -21,9 +21,6 @@
/**************************************************************************/
/* Include macros for modifying the wait list. */
#include "tx_thread_smp_protection_wait_list_macros.h"
.text
.align 3
/**************************************************************************/
@@ -31,7 +28,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-A35-SMP/AC6 */
/* 6.1.3 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Andres Mlinar, Microsoft Corporation */
@@ -63,7 +60,10 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 12-31-2020 Andres Mlinar Initial Version 6.1.3 */
/* 12-31-2020 Andres Mlinar Initial Version 6.1.3 */
/* 04-25-2022 William E. Lamie Modified comments, removed */
/* FIFO queueing, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_context_restore(VOID)
@@ -76,7 +76,7 @@ _tx_thread_context_restore:
MSR DAIFSet, 0x3 // Lockout interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the ISR exit function to indicate an ISR is complete. */
@@ -101,13 +101,13 @@ _tx_thread_context_restore:
LDR x3, =_tx_thread_system_state // Pickup address of system state var
LDR w2, [x3, x8, LSL #2] // Pickup system state
SUB w2, w2, #1 // Decrement the counter
STR w2, [x3, x8, LSL #2] // Store the counter
STR w2, [x3, x8, LSL #2] // Store the counter
CMP w2, #0 // Was this the first interrupt?
BEQ __tx_thread_not_nested_restore // If so, not a nested restore
/* Interrupts are nested. */
/* Just recover the saved registers and return to the point of
/* Just recover the saved registers and return to the point of
interrupt. */
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL
@@ -151,7 +151,7 @@ __tx_thread_not_nested_restore:
LDR x3, =_tx_thread_execute_ptr // Pickup address of execute thread ptr
LDR x2, [x3, x8, LSL #3] // Pickup actual execute thread pointer
CMP x0, x2 // Is the same thread highest priority?
BEQ __tx_thread_no_preempt_restore // Same thread in the execute list,
BEQ __tx_thread_no_preempt_restore // Same thread in the execute list,
// no preemption needs to happen
LDR x3, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x3, #4] // Pickup the owning core
@@ -206,74 +206,6 @@ __tx_thread_no_preempt_restore:
// {
__tx_thread_preempt_restore:
/* Was the thread being preempted waiting for the lock? */
// if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
// {
LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
CMP w3, #0
BEQ _nobody_waiting_for_lock // Is the core waiting for the lock?
/* Do we not have the lock? This means the ISR never got the inter-core lock. */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
// {
LDR x2, =_tx_thread_smp_protection // Load address of protection structure
LDR w3, [x2, #4] // Pickup the owning core
CMP w8, w3 // Compare our core to the owning core
BEQ _this_core_has_lock // Do we have the lock?
/* We don't have the lock. This core should be in the list. Remove it. */
// _tx_thread_smp_protect_wait_list_remove(this_core);
_tx_thread_smp_protect_wait_list_remove // Call macro to remove core from the list
B _nobody_waiting_for_lock // Leave
// }
// else
// {
/* We have the lock. This means the ISR got the inter-core lock, but
never released it because it saw that there was someone waiting.
Note this core is not in the list. */
_this_core_has_lock:
/* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
// _tx_thread_smp_protect_wait_counts[core]--;
LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
SUB w3, w3, #1 // Decrement waiting value. Should be zero now
STR w3, [x2, x8, LSL #2] // Store new waiting value
/* Now release the inter-core lock. */
/* Set protected core as invalid. */
// _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
LDR x2, =_tx_thread_smp_protection // Load address of protection structure
MOV w3, #0xFFFFFFFF // Build invalid value
STR w3, [x2, #4] // Mark the protected core as invalid
DMB ISH // Ensure that accesses to shared resource have completed
/* Release protection. */
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
MOV w3, #0 // Build release protection value
STR w3, [x2, #0] // Release the protection
DSB ISH // To ensure update of the protection occurs before other CPUs awake
/* Wake up waiting processors. Note interrupts are already enabled. */
#ifdef TX_ENABLE_WFE
SEV // Send event to other CPUs
#endif
// }
// }
_nobody_waiting_for_lock:
LDR x4, [x0, #8] // Switch to thread stack pointer
MOV sp, x4 //
@@ -328,8 +260,8 @@ _skip_fp_save:
CMP w2, #0 // Is it active?
BEQ __tx_thread_dont_save_ts // No, don't save it
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
_tx_timer_time_slice = 0; */
// _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
// _tx_timer_time_slice = 0;
STR w2, [x0, #36] // Save thread's time-slice
MOV w2, #0 // Clear value
@@ -32,7 +32,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_protect Cortex-A35-SMP/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -63,11 +63,14 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* improved SMP code, */
/* resulting in version 6.1.9 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* improved SMP code, */
/* resulting in version 6.1.9 */
/* 04-25-2022 William E. Lamie Modified comments, removed */
/* FIFO queueing, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
.global _tx_thread_smp_protect
@@ -81,293 +84,49 @@ _tx_thread_smp_protect:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
UBFX x7, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
UBFX x7, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
ADDS x2, x2, x7, LSL #2 // Calculate CPU ID
#endif
/* Do we already have protection? */
// if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
// {
LDR x2, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x2, #4] // Pickup the owning core
CMP w1, w3 // Is it not this core?
BNE _protection_not_owned // No, the protection is not already owned
/* We already have protection. */
/* Increment the protection count. */
// _tx_thread_smp_protection.tx_thread_smp_protect_count++;
LDR w3, [x2, #8] // Pickup ownership count
ADD w3, w3, #1 // Increment ownership count
STR w3, [x2, #8] // Store ownership count
DMB ISH
B _return
_protection_not_owned:
/* Is the lock available? */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
// {
LDAXR w3, [x2, #0] // Pickup the protection flag
CMP w3, #0
BNE _start_waiting // No, protection not available
/* Is the list empty? */
// if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
// {
LDR x3, =_tx_thread_smp_protect_wait_list_head
LDR w3, [x3]
LDR x4, =_tx_thread_smp_protect_wait_list_tail
LDR w4, [x4]
CMP w3, w4
BNE _list_not_empty
/* Try to get the lock. */
// if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
// {
MOV w3, #1 // Build lock value
STXR w4, w3, [x2, #0] // Attempt to get the protection
CMP w4, #0
BNE _start_waiting // Did it fail?
/* We got the lock! */
// _tx_thread_smp_protect_lock_got();
DMB ISH // Ensure write to protection finishes
_tx_thread_smp_protect_lock_got // Call the lock got function
B _return
_list_not_empty:
/* Are we at the front of the list? */
// if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
// {
LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
LDR w3, [x3] // Get the value of the head
LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
LDR w4, [x4, x3, LSL #2] // Get the value at the head index
CMP w1, w4
BNE _start_waiting
/* Is the lock still available? */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
// {
LDAXR w3, [x2, #0] // Pickup the protection flag
CMP w3, #0
BNE _start_waiting // No, protection not available
/* Get the lock. */
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
MOV w3, #1 // Build lock value
STXR w4, w3, [x2, #0] // Attempt to get the protection
CMP w4, #0
BNE _start_waiting // Did it fail?
DMB ISH //
/* Got the lock. */
// _tx_thread_smp_protect_lock_got();
_tx_thread_smp_protect_lock_got
/* Remove this core from the wait list. */
// _tx_thread_smp_protect_remove_from_front_of_list();
_tx_thread_smp_protect_remove_from_front_of_list
B _return
_start_waiting:
/* For one reason or another, we didn't get the lock. */
/* Increment wait count. */
// _tx_thread_smp_protect_wait_counts[this_core]++;
LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
ADD w4, w4, #1 // Increment wait value
STR w4, [x3, x1, LSL #2] // Store new wait value
/* Have we not added ourselves to the list yet? */
// if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
// {
CMP w4, #1
BNE _already_in_list0 // Is this core already waiting?
/* Add ourselves to the list. */
// _tx_thread_smp_protect_wait_list_add(this_core);
_tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
// }
_already_in_list0:
/* Restore interrupts. */
LDR x1, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x1, #4] // Pickup the owning core
CMP w3, w2 // Is it this core?
BEQ _owned // Yes, the protection is already owned
LDAXR w4, [x1, #0] // Pickup the protection flag
CBZ w4, _get_protection // Yes, get the protection
MSR DAIF, x0 // Restore interrupts
ISB //
#ifdef TX_ENABLE_WFE
WFE // Go into standby
#endif
B _tx_thread_smp_protect // On waking, restart the protection attempt
/* We do this until we have the lock. */
// while (1)
// {
_try_to_get_lock:
/* Disable interrupts so we don't get preempted. */
MRS x0, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
#endif
/* Do we already have protection? */
// if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
// {
LDR w3, [x2, #4] // Pickup the owning core
CMP w3, w1 // Is it this core?
BEQ _got_lock_after_waiting // Yes, the protection is already owned. This means
// an ISR preempted us and got protection
// }
/* Are we at the front of the list? */
// if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
// {
LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
LDR w3, [x3] // Get the value of the head
LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
LDR w4, [x4, x3, LSL #2] // Get the value at the head index
CMP w1, w4
BNE _did_not_get_lock
/* Is the lock still available? */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
// {
LDAXR w3, [x2, #0] // Pickup the protection flag
CMP w3, #0
BNE _did_not_get_lock // No, protection not available
/* Get the lock. */
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
MOV w3, #1 // Build lock value
STXR w4, w3, [x2, #0] // Attempt to get the protection
CMP w4, #0
BNE _did_not_get_lock // Did it fail?
DMB ISH //
/* Got the lock. */
// _tx_thread_smp_protect_lock_got();
_tx_thread_smp_protect_lock_got
/* Remove this core from the wait list. */
// _tx_thread_smp_protect_remove_from_front_of_list();
_tx_thread_smp_protect_remove_from_front_of_list
B _got_lock_after_waiting
_did_not_get_lock:
/* For one reason or another, we didn't get the lock. */
/* Were we removed from the list? This can happen if we're a thread
and we got preempted. */
// if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
// {
LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
CMP w4, #0
BNE _already_in_list1 // Is this core already in the list?
/* Add ourselves to the list. */
// _tx_thread_smp_protect_wait_list_add(this_core);
_tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
/* Our waiting count was also reset when we were preempted. Increment it again. */
// _tx_thread_smp_protect_wait_counts[this_core]++;
LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
ADD w4, w4, #1 // Increment wait value
STR w4, [x3, x1, LSL #2] // Store new wait value value
// }
_already_in_list1:
/* Restore interrupts and try again. */
_get_protection:
MOV x4, #1 // Build lock value
STXR w5, w4, [x1] // Attempt to get the protection
CBZ w5, _got_protection // Did it succeed? w5 = 0 means success!
MSR DAIF, x0 // Restore interrupts
ISB //
#ifdef TX_ENABLE_WFE
WFE // Go into standby
#endif
B _try_to_get_lock // On waking, restart the protection attempt
_got_lock_after_waiting:
/* We're no longer waiting. */
// _tx_thread_smp_protect_wait_counts[this_core]--;
LDR x3, =_tx_thread_smp_protect_wait_counts // Load waiting list
LDR w4, [x3, x1, LSL #2] // Load current wait value
SUB w4, w4, #1 // Decrement wait value
STR w4, [x3, x1, LSL #2] // Store new wait value value
/* Restore registers and return. */
_return:
B _tx_thread_smp_protect // Restart the protection attempt
_got_protection:
DMB ISH //
STR w2, [x1, #4] // Save owning core
_owned:
LDR w5, [x1, #8] // Pickup ownership count
ADD w5, w5, #1 // Increment ownership count
STR w5, [x1, #8] // Store ownership count
DMB ISH //
RET
@@ -28,7 +28,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_unprotect Cortex-A35-SMP/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -60,10 +60,13 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* resulting in version 6.1.9 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* resulting in version 6.1.9 */
/* 04-25-2022 William E. Lamie Modified comments, removed */
/* FIFO queueing, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
.global _tx_thread_smp_unprotect
@@ -105,11 +108,6 @@ _tx_thread_smp_unprotect:
CMP w3, #0 // Is the preempt disable flag set?
BNE _still_protected // Yes, skip the protection release
LDR x2,=_tx_thread_smp_protect_wait_counts // Build build address of wait counts
LDR w3, [x2, x1, LSL #2] // Pickup wait list value
CMP w3, #0 // Are any entities on this core waiting?
BNE _still_protected // Yes, skip the protection release
LDR x2,=_tx_thread_smp_protection // Build address of protection structure
MOV w3, #0xFFFFFFFF // Build invalid value
STR w3, [x2, #4] // Mark the protected core as invalid
@@ -21,9 +21,6 @@
/**************************************************************************/
/* Include macros for modifying the wait list. */
#include "tx_thread_smp_protection_wait_list_macros.h"
.text
.align 3
/**************************************************************************/
@@ -31,7 +28,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-A35-SMP/GNU */
/* 6.1.3 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Andres Mlinar, Microsoft Corporation */
@@ -63,7 +60,10 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 12-31-2020 Andres Mlinar Initial Version 6.1.3 */
/* 12-31-2020 Andres Mlinar Initial Version 6.1.3 */
/* 04-25-2022 William E. Lamie Modified comments, removed */
/* FIFO queueing, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_context_restore(VOID)
@@ -76,7 +76,7 @@ _tx_thread_context_restore:
MSR DAIFSet, 0x3 // Lockout interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the ISR exit function to indicate an ISR is complete. */
@@ -101,13 +101,13 @@ _tx_thread_context_restore:
LDR x3, =_tx_thread_system_state // Pickup address of system state var
LDR w2, [x3, x8, LSL #2] // Pickup system state
SUB w2, w2, #1 // Decrement the counter
STR w2, [x3, x8, LSL #2] // Store the counter
STR w2, [x3, x8, LSL #2] // Store the counter
CMP w2, #0 // Was this the first interrupt?
BEQ __tx_thread_not_nested_restore // If so, not a nested restore
/* Interrupts are nested. */
/* Just recover the saved registers and return to the point of
/* Just recover the saved registers and return to the point of
interrupt. */
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL
@@ -151,7 +151,7 @@ __tx_thread_not_nested_restore:
LDR x3, =_tx_thread_execute_ptr // Pickup address of execute thread ptr
LDR x2, [x3, x8, LSL #3] // Pickup actual execute thread pointer
CMP x0, x2 // Is the same thread highest priority?
BEQ __tx_thread_no_preempt_restore // Same thread in the execute list,
BEQ __tx_thread_no_preempt_restore // Same thread in the execute list,
// no preemption needs to happen
LDR x3, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x3, #4] // Pickup the owning core
@@ -206,74 +206,6 @@ __tx_thread_no_preempt_restore:
// {
__tx_thread_preempt_restore:
/* Was the thread being preempted waiting for the lock? */
// if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
// {
LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
CMP w3, #0
BEQ _nobody_waiting_for_lock // Is the core waiting for the lock?
/* Do we not have the lock? This means the ISR never got the inter-core lock. */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
// {
LDR x2, =_tx_thread_smp_protection // Load address of protection structure
LDR w3, [x2, #4] // Pickup the owning core
CMP w8, w3 // Compare our core to the owning core
BEQ _this_core_has_lock // Do we have the lock?
/* We don't have the lock. This core should be in the list. Remove it. */
// _tx_thread_smp_protect_wait_list_remove(this_core);
_tx_thread_smp_protect_wait_list_remove // Call macro to remove core from the list
B _nobody_waiting_for_lock // Leave
// }
// else
// {
/* We have the lock. This means the ISR got the inter-core lock, but
never released it because it saw that there was someone waiting.
Note this core is not in the list. */
_this_core_has_lock:
/* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
// _tx_thread_smp_protect_wait_counts[core]--;
LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
SUB w3, w3, #1 // Decrement waiting value. Should be zero now
STR w3, [x2, x8, LSL #2] // Store new waiting value
/* Now release the inter-core lock. */
/* Set protected core as invalid. */
// _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
LDR x2, =_tx_thread_smp_protection // Load address of protection structure
MOV w3, #0xFFFFFFFF // Build invalid value
STR w3, [x2, #4] // Mark the protected core as invalid
DMB ISH // Ensure that accesses to shared resource have completed
/* Release protection. */
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
MOV w3, #0 // Build release protection value
STR w3, [x2, #0] // Release the protection
DSB ISH // To ensure update of the protection occurs before other CPUs awake
/* Wake up waiting processors. Note interrupts are already enabled. */
#ifdef TX_ENABLE_WFE
SEV // Send event to other CPUs
#endif
// }
// }
_nobody_waiting_for_lock:
LDR x4, [x0, #8] // Switch to thread stack pointer
MOV sp, x4 //
@@ -328,8 +260,8 @@ _skip_fp_save:
CMP w2, #0 // Is it active?
BEQ __tx_thread_dont_save_ts // No, don't save it
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
_tx_timer_time_slice = 0; */
// _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
// _tx_timer_time_slice = 0;
STR w2, [x0, #36] // Save thread's time-slice
MOV w2, #0 // Clear value
@@ -32,7 +32,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_protect Cortex-A35-SMP/GCC */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -63,11 +63,14 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* improved SMP code, */
/* resulting in version 6.1.9 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* improved SMP code, */
/* resulting in version 6.1.9 */
/* 04-25-2022 William E. Lamie Modified comments, removed */
/* FIFO queueing, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
.global _tx_thread_smp_protect
@@ -81,293 +84,49 @@ _tx_thread_smp_protect:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
UBFX x7, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
UBFX x7, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
ADDS x2, x2, x7, LSL #2 // Calculate CPU ID
#endif
/* Do we already have protection? */
// if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
// {
LDR x2, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x2, #4] // Pickup the owning core
CMP w1, w3 // Is it not this core?
BNE _protection_not_owned // No, the protection is not already owned
/* We already have protection. */
/* Increment the protection count. */
// _tx_thread_smp_protection.tx_thread_smp_protect_count++;
LDR w3, [x2, #8] // Pickup ownership count
ADD w3, w3, #1 // Increment ownership count
STR w3, [x2, #8] // Store ownership count
DMB ISH
B _return
_protection_not_owned:
/* Is the lock available? */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
// {
LDAXR w3, [x2, #0] // Pickup the protection flag
CMP w3, #0
BNE _start_waiting // No, protection not available
/* Is the list empty? */
// if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
// {
LDR x3, =_tx_thread_smp_protect_wait_list_head
LDR w3, [x3]
LDR x4, =_tx_thread_smp_protect_wait_list_tail
LDR w4, [x4]
CMP w3, w4
BNE _list_not_empty
/* Try to get the lock. */
// if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
// {
MOV w3, #1 // Build lock value
STXR w4, w3, [x2, #0] // Attempt to get the protection
CMP w4, #0
BNE _start_waiting // Did it fail?
/* We got the lock! */
// _tx_thread_smp_protect_lock_got();
DMB ISH // Ensure write to protection finishes
_tx_thread_smp_protect_lock_got // Call the lock got function
B _return
_list_not_empty:
/* Are we at the front of the list? */
// if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
// {
LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
LDR w3, [x3] // Get the value of the head
LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
LDR w4, [x4, x3, LSL #2] // Get the value at the head index
CMP w1, w4
BNE _start_waiting
/* Is the lock still available? */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
// {
LDAXR w3, [x2, #0] // Pickup the protection flag
CMP w3, #0
BNE _start_waiting // No, protection not available
/* Get the lock. */
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
MOV w3, #1 // Build lock value
STXR w4, w3, [x2, #0] // Attempt to get the protection
CMP w4, #0
BNE _start_waiting // Did it fail?
DMB ISH //
/* Got the lock. */
// _tx_thread_smp_protect_lock_got();
_tx_thread_smp_protect_lock_got
/* Remove this core from the wait list. */
// _tx_thread_smp_protect_remove_from_front_of_list();
_tx_thread_smp_protect_remove_from_front_of_list
B _return
_start_waiting:
/* For one reason or another, we didn't get the lock. */
/* Increment wait count. */
// _tx_thread_smp_protect_wait_counts[this_core]++;
LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
ADD w4, w4, #1 // Increment wait value
STR w4, [x3, x1, LSL #2] // Store new wait value
/* Have we not added ourselves to the list yet? */
// if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
// {
CMP w4, #1
BNE _already_in_list0 // Is this core already waiting?
/* Add ourselves to the list. */
// _tx_thread_smp_protect_wait_list_add(this_core);
_tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
// }
_already_in_list0:
/* Restore interrupts. */
LDR x1, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x1, #4] // Pickup the owning core
CMP w3, w2 // Is it this core?
BEQ _owned // Yes, the protection is already owned
LDAXR w4, [x1, #0] // Pickup the protection flag
CBZ w4, _get_protection // Yes, get the protection
MSR DAIF, x0 // Restore interrupts
ISB //
#ifdef TX_ENABLE_WFE
WFE // Go into standby
#endif
B _tx_thread_smp_protect // On waking, restart the protection attempt
/* We do this until we have the lock. */
// while (1)
// {
_try_to_get_lock:
/* Disable interrupts so we don't get preempted. */
MRS x0, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
#endif
/* Do we already have protection? */
// if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
// {
LDR w3, [x2, #4] // Pickup the owning core
CMP w3, w1 // Is it this core?
BEQ _got_lock_after_waiting // Yes, the protection is already owned. This means
// an ISR preempted us and got protection
// }
/* Are we at the front of the list? */
// if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
// {
LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
LDR w3, [x3] // Get the value of the head
LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
LDR w4, [x4, x3, LSL #2] // Get the value at the head index
CMP w1, w4
BNE _did_not_get_lock
/* Is the lock still available? */
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
// {
LDAXR w3, [x2, #0] // Pickup the protection flag
CMP w3, #0
BNE _did_not_get_lock // No, protection not available
/* Get the lock. */
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
MOV w3, #1 // Build lock value
STXR w4, w3, [x2, #0] // Attempt to get the protection
CMP w4, #0
BNE _did_not_get_lock // Did it fail?
DMB ISH //
/* Got the lock. */
// _tx_thread_smp_protect_lock_got();
_tx_thread_smp_protect_lock_got
/* Remove this core from the wait list. */
// _tx_thread_smp_protect_remove_from_front_of_list();
_tx_thread_smp_protect_remove_from_front_of_list
B _got_lock_after_waiting
_did_not_get_lock:
/* For one reason or another, we didn't get the lock. */
/* Were we removed from the list? This can happen if we're a thread
and we got preempted. */
// if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
// {
LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
CMP w4, #0
BNE _already_in_list1 // Is this core already in the list?
/* Add ourselves to the list. */
// _tx_thread_smp_protect_wait_list_add(this_core);
_tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
/* Our waiting count was also reset when we were preempted. Increment it again. */
// _tx_thread_smp_protect_wait_counts[this_core]++;
LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
ADD w4, w4, #1 // Increment wait value
STR w4, [x3, x1, LSL #2] // Store new wait value value
// }
_already_in_list1:
/* Restore interrupts and try again. */
_get_protection:
MOV x4, #1 // Build lock value
STXR w5, w4, [x1] // Attempt to get the protection
CBZ w5, _got_protection // Did it succeed? w5 = 0 means success!
MSR DAIF, x0 // Restore interrupts
ISB //
#ifdef TX_ENABLE_WFE
WFE // Go into standby
#endif
B _try_to_get_lock // On waking, restart the protection attempt
_got_lock_after_waiting:
/* We're no longer waiting. */
// _tx_thread_smp_protect_wait_counts[this_core]--;
LDR x3, =_tx_thread_smp_protect_wait_counts // Load waiting list
LDR w4, [x3, x1, LSL #2] // Load current wait value
SUB w4, w4, #1 // Decrement wait value
STR w4, [x3, x1, LSL #2] // Store new wait value value
/* Restore registers and return. */
_return:
B _tx_thread_smp_protect // Restart the protection attempt
_got_protection:
DMB ISH //
STR w2, [x1, #4] // Save owning core
_owned:
LDR w5, [x1, #8] // Pickup ownership count
ADD w5, w5, #1 // Increment ownership count
STR w5, [x1, #8] // Store ownership count
DMB ISH //
RET
@@ -28,7 +28,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_unprotect Cortex-A35-SMP/GCC */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -60,10 +60,13 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* resulting in version 6.1.9 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 10-15-2021 Andres Mlinar Updated comments, */
/* added ARMv8.2-A support, */
/* resulting in version 6.1.9 */
/* 04-25-2022 William E. Lamie Modified comments, removed */
/* FIFO queueing, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
.global _tx_thread_smp_unprotect
@@ -105,11 +108,6 @@ _tx_thread_smp_unprotect:
CMP w3, #0 // Is the preempt disable flag set?
BNE _still_protected // Yes, skip the protection release
LDR x2,=_tx_thread_smp_protect_wait_counts // Build build address of wait counts
LDR w3, [x2, x1, LSL #2] // Pickup wait list value
CMP w3, #0 // Are any entities on this core waiting?
BNE _still_protected // Yes, skip the protection release
LDR x2,=_tx_thread_smp_protection // Build address of protection structure
MOV w3, #0xFFFFFFFF // Build invalid value
STR w3, [x2, #4] // Mark the protected core as invalid
+8 -4
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M0+/AC6 */
/* 6.1.10 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -473,7 +476,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/AC6 */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -63,6 +63,8 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -338,14 +340,23 @@ __tx_ts_restore:
CMP r0, #0
BEQ skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
MOV r8, r1 // Copy thread ptr
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CMP r1, #0
MOVS r6, #0x8C
LDR r2, [r0, r6] // Pickup MPU region 5 address
CMP r2, #0
BEQ skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
// Is the MPU already set up for this module?
MOVS r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
MOVS r6, #0x10
BICS r2, r2, r6 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Initialize loop to configure MPU registers
// Order doesn't matter, so txm_module_instance_mpu_registers[0]
// will be in region 7 and txm_module_instance_mpu_registers[7] will be in region 0.
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
MOVS r5, #0 // Select region 0
@@ -359,7 +370,7 @@ _tx_mpu_loop:
ADDS r5, r5, #1 // Increment to next region
CMP r5, #8 // Check if all regions have been set
BNE _tx_mpu_loop
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOVS r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+9 -5
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M0+/GNU */
/* 6.1.10 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -138,13 +141,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -305,7 +308,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -487,7 +490,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/GNU */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -63,6 +63,8 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -338,14 +340,23 @@ __tx_ts_restore:
CMP r0, #0
BEQ skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
MOV r8, r1 // Copy thread ptr
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CMP r1, #0
MOVS r6, #0x8C
LDR r2, [r0, r6] // Pickup MPU region 5 address
CMP r2, #0
BEQ skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
// Is the MPU already set up for this module?
MOVS r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
MOVS r6, #0x10
BICS r2, r2, r6 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Initialize loop to configure MPU registers
// Order doesn't matter, so txm_module_instance_mpu_registers[0]
// will be in region 7 and txm_module_instance_mpu_registers[7] will be in region 0.
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
MOVS r5, #0 // Select region 0
@@ -359,7 +370,7 @@ _tx_mpu_loop:
ADDS r5, r5, #1 // Increment to next region
CMP r5, #8 // Check if all regions have been set
BNE _tx_mpu_loop
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOVS r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
@@ -58,9 +58,9 @@ __vector_table
DC32 NMI_Handler ; NMI
DC32 HardFault_Handler ; HardFault
DC32 MemManage_Handler ; MemManage
DC32 0 ; BusFault
DC32 0 ; UsageFault
DC32 HardFault_Handler ; MemManage
DC32 HardFault_Handler ; BusFault
DC32 HardFault_Handler ; UsageFault
DC32 0 ; 7
DC32 0 ; 8
DC32 0 ; 9
+8 -5
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M0+/IAR */
/* 6.1.10 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -142,14 +145,14 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -361,7 +364,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -532,7 +535,7 @@ static void _tx_thread_system_return_inline(void)
__istate_t interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_IPSR() == 0)
{
interrupt_save = __get_interrupt_state();
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/IAR */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -69,6 +69,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* change handler name, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -103,12 +106,8 @@ __tx_wait_here:
/* Memory Exception Handler. */
PUBLIC MemManage_Handler
PUBLIC BusFault_Handler
PUBLIC UsageFault_Handler
MemManage_Handler:
BusFault_Handler:
UsageFault_Handler:
PUBLIC HardFault_Handler
HardFault_Handler:
CPSID i // Disable interrupts
@@ -326,14 +325,23 @@ __tx_ts_restore:
CMP r0, #0
BEQ skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
MOV r8, r1 // Copy thread ptr
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CMP r1, #0
MOVS r6, #0x8C
LDR r2, [r0, r6] // Pickup MPU region 5 address
CMP r2, #0
BEQ skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
// Is the MPU already set up for this module?
MOVS r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
MOVS r6, #0x10
BICS r2, r2, r6 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Initialize loop to configure MPU registers
// Order doesn't matter, so txm_module_instance_mpu_registers[0]
// will be in region 7 and txm_module_instance_mpu_registers[7] will be in region 0.
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
MOVS r5, #0 // Select region 0
@@ -347,7 +355,7 @@ _tx_mpu_loop:
ADDS r5, r5, #1 // Increment to next region
CMP r5, #8 // Check if all regions have been set
BNE _tx_mpu_loop
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOVS r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+25 -25
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M23/AC6 */
/* 6.1.6 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -163,7 +166,7 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
#endif
#ifndef TX_TIMER_THREAD_PRIORITY
#ifndef TX_TIMER_THREAD_PRIORITY
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
#endif
@@ -175,17 +178,17 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -214,7 +217,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
#endif
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
define is negated, thereby forcing the stack fill which is necessary for the stack checking
@@ -228,7 +231,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
/* Define the TX_THREAD control block extensions for this port. The main reason
for the multiple macros is so that backward compatibility can be maintained with
for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
@@ -284,7 +287,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID (*tx_timer_module_expiration_function)(ULONG id);
/* Define the user extension field of the thread control block. Nothing
/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
@@ -362,9 +365,9 @@ static void _set_control(unsigned int _control)
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_set_control(_tx_vfp_state);; \
_set_control(_tx_vfp_state);; \
}
#else
@@ -392,26 +395,26 @@ void _tx_vfp_access(void);
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_set_control(_tx_vfp_state); \
_set_control(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
_tx_vfp_access(); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _get_control(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_set_control(_tx_vfp_state); \
_set_control(_tx_vfp_state); \
} \
} \
} \
@@ -481,7 +484,7 @@ void _tx_vfp_access(void);
/* Define the get system state macro. */
#ifndef TX_THREAD_GET_SYSTEM_STATE
#ifndef TX_MISRA_ENABLE
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _get_ipsr())
@@ -507,15 +510,12 @@ extern void _tx_thread_secure_stack_initialize(void);
#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
prevent early scheduling on Cortex-M parts. */
#define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++;
/* Determine if the ARM architecture has the CLZ instruction. This is available on
architectures v5 and above. If available, redefine the macro for calculating the
lowest bit set. */
#ifndef TX_DISABLE_INLINE
@@ -557,7 +557,7 @@ unsigned int was_masked;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_get_ipsr() == 0)
{
was_masked = __disable_irq();
@@ -572,8 +572,8 @@ unsigned int was_masked;
/* Define the version ID of ThreadX. This may be utilized by the application. */
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/AC6 Version 6.1.9 *";
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/AC6 Version 6.1.11 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/AC6 */
/* 6.1.6 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -63,6 +63,8 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -373,12 +375,20 @@ _skip_secure_restore:
LDR r0, [r1, r2] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
MOV r8, r1 // Copy thread ptr
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
MOVS r2, #0x74 // Index of MPU data region
LDR r2, [r0, r2] // Pickup MPU data region address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOVS r1, #2 // Select MPU region 2
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 2
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Initialize loop to configure MPU registers
// Order doesn't matter, so txm_module_instance_mpu_registers[0]
// will be in region 7 and txm_module_instance_mpu_registers[7] will be in region 0.
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
MOVS r5, #0 // Select region 0
@@ -392,7 +402,7 @@ _tx_mpu_loop:
ADDS r5, r5, #1 // Increment to next region
CMP r5, #8 // Check if all regions have been set
BNE _tx_mpu_loop
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOVS r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+18 -17
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M23/GNU */
/* 6.1.7 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -58,6 +58,9 @@
/* added symbol to enable */
/* stack error handler, */
/* resulting in version 6.1.7 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -172,7 +175,7 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
#endif
#ifndef TX_TIMER_THREAD_PRIORITY
#ifndef TX_TIMER_THREAD_PRIORITY
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
#endif
@@ -184,17 +187,17 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -223,7 +226,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
#endif
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
define is negated, thereby forcing the stack fill which is necessary for the stack checking
@@ -237,7 +240,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
/* Define the TX_THREAD control block extensions for this port. The main reason
for the multiple macros is so that backward compatibility can be maintained with
for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
@@ -293,7 +296,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID (*tx_timer_module_expiration_function)(ULONG id);
/* Define the user extension field of the thread control block. Nothing
/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
@@ -359,7 +362,7 @@ inline static unsigned int _get_ipsr(void)
/* Define the get system state macro. */
#ifndef TX_THREAD_GET_SYSTEM_STATE
#ifndef TX_MISRA_ENABLE
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _get_ipsr())
@@ -385,15 +388,12 @@ extern void _tx_thread_secure_stack_initialize(void);
#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
prevent early scheduling on Cortex-M parts. */
#define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++;
/* Determine if the ARM architecture has the CLZ instruction. This is available on
architectures v5 and above. If available, redefine the macro for calculating the
lowest bit set. */
#ifndef TX_DISABLE_INLINE
@@ -449,7 +449,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_get_ipsr() == 0)
{
interrupt_save = __get_primask_value();
@@ -482,8 +483,8 @@ unsigned int interrupt_save;
/* Define the version ID of ThreadX. This may be utilized by the application. */
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/GNU Version 6.1.9 *";
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/GNU Version 6.1.11 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -26,7 +26,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/GNU */
/* 6.1.6 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -59,6 +59,8 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -369,12 +371,20 @@ _skip_secure_restore:
LDR r0, [r1, r2] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
MOV r8, r1 // Copy thread ptr
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
MOVS r2, #0x74 // Index of MPU data region
LDR r2, [r0, r2] // Pickup MPU data region address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOVS r1, #2 // Select MPU region 2
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 2
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Initialize loop to configure MPU registers
// Order doesn't matter, so txm_module_instance_mpu_registers[0]
// will be in region 7 and txm_module_instance_mpu_registers[7] will be in region 0.
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
MOVS r5, #0 // Select region 0
@@ -388,7 +398,7 @@ _tx_mpu_loop:
ADDS r5, r5, #1 // Increment to next region
CMP r5, #8 // Check if all regions have been set
BNE _tx_mpu_loop
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOVS r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+12 -9
View File
@@ -25,8 +25,8 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h ARMv8-M */
/* 6.1.6 */
/* tx_port.h Cortex-M23/IAR */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -179,7 +182,7 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
#endif
/* Define various constants for the ThreadX Cortex-M port. */
/* Define various constants for the ThreadX Cortex-M23 port. */
#define TX_INT_DISABLE 1 /* Disable interrupts */
#define TX_INT_ENABLE 0 /* Enable interrupts */
@@ -189,14 +192,14 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -464,7 +467,7 @@ __attribute__( ( always_inline ) ) static inline void __set_CONTROL(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -644,7 +647,7 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_IPSR() == 0)
{
interrupt_save = __get_primask_value();
@@ -665,7 +668,7 @@ static void _tx_thread_system_return_inline(void)
__istate_t interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_IPSR() == 0)
{
interrupt_save = __get_interrupt_state();
@@ -701,7 +704,7 @@ VOID _tx_thread_interrupt_restore(UIN
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Modules ARMv8-M Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/IAR Version 6.1.11 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/IAR */
/* 6.1.6 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -75,6 +75,8 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -370,12 +372,20 @@ _skip_secure_restore:
LDR r0, [r1, r2] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
MOV r8, r1 // Copy thread ptr
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
MOVS r2, #0x74 // Index of MPU data region
LDR r2, [r0, r2] // Pickup MPU data region address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOVS r1, #2 // Select MPU region 2
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 2
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Initialize loop to configure MPU registers
// Order doesn't matter, so txm_module_instance_mpu_registers[0]
// will be in region 7 and txm_module_instance_mpu_registers[7] will be in region 0.
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
MOVS r5, #0 // Select region 0
@@ -389,7 +399,7 @@ _tx_mpu_loop:
ADDS r5, r5, #1 // Increment to next region
CMP r5, #8 // Check if all regions have been set
BNE _tx_mpu_loop
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOVS r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+9 -6
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M3/AC5 */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -282,7 +285,7 @@ void _tx_vfp_access(void);
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -435,7 +438,7 @@ unsigned int was_masked;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_ipsr == 0)
{
was_masked = __disable_irq();
@@ -458,7 +461,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/AC5 Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/AC5 Version 6.1.11 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/AC5 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -67,13 +67,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -125,7 +127,12 @@ __tx_wait_here
EXPORT MemManage_Handler
MemManage_Handler
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -208,7 +215,12 @@ MemManage_Handler
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -226,12 +238,22 @@ __tx_ts_handler
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -276,7 +298,12 @@ __tx_ts_new
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -285,7 +312,12 @@ __tx_ts_new
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -293,7 +325,12 @@ __tx_ts_wait
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -310,7 +347,12 @@ __tx_ts_restore
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -346,27 +388,34 @@ __tx_ts_restore
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+11 -7
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M3/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -291,7 +294,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -467,7 +470,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -497,7 +501,7 @@ unsigned int interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
@@ -508,7 +512,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/AC6 Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/AC6 Version 6.1.11 *";
#else
extern CHAR _tx_version_id[];
#endif
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -69,13 +69,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -135,7 +137,12 @@ BusFault_Handler:
.thumb_func
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -197,7 +204,7 @@ UsageFault_Handler:
LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address
LDR r1, [r0] // Load FPCCR
BIC r1, r1, #1 // Clear the lazy preservation active bit
STR r1, [r0] // Store the value
STR r1, [r0] // Save FPCCR
#endif
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
@@ -218,7 +225,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -239,12 +251,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -289,7 +311,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -298,7 +325,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -306,7 +338,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -323,7 +360,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -359,27 +401,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
@@ -538,14 +587,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
STM r0!, {r1-r2} // Insert r0, r1 into thread stack
LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
STM r0!, {r1-r2} // Insert r2, r3 into thread stack
LDM r3!, {r1-r2} // Get r12, lr from kernel stack
STM r0!, {r1-r2} // Insert r12, lr into thread stack
LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
+12 -8
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M3/GNU */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -291,7 +294,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -461,7 +464,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -491,8 +495,8 @@ unsigned int interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
thread. This is for legacy only, and not needed any longer. */
/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
void tx_thread_fpu_disable(void);
@@ -502,7 +506,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/GNU Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/GNU Version 6.1.11 *";
#else
extern CHAR _tx_version_id[];
#endif
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/GNU */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -67,7 +67,6 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
@@ -76,6 +75,9 @@
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 01-31-2022 Scott Larson Fixed predefined macro name, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -135,7 +137,12 @@ BusFault_Handler:
.thumb_func
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -197,7 +204,7 @@ UsageFault_Handler:
LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address
LDR r1, [r0] // Load FPCCR
BIC r1, r1, #1 // Clear the lazy preservation active bit
STR r1, [r0] // Store the value
STR r1, [r0] // Save FPCCR
#endif
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
@@ -218,7 +225,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -239,12 +251,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -289,7 +311,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -298,7 +325,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -306,7 +338,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -323,7 +360,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -359,27 +401,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+9 -6
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M3/IAR */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -127,14 +130,14 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -325,7 +328,7 @@ void _tx_misra_vfp_touch(void);
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -476,7 +479,7 @@ static void _tx_thread_system_return_inline(void)
__istate_t interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_IPSR() == 0)
{
interrupt_save = __get_interrupt_state();
@@ -488,7 +491,7 @@ __istate_t interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/IAR */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -63,13 +63,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -125,8 +127,12 @@ __tx_wait_here:
MemManage_Handler:
BusFault_Handler:
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -209,7 +215,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -227,12 +238,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -277,7 +298,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -286,7 +312,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -294,7 +325,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -311,7 +347,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -347,27 +388,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+16 -13
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M33 */
/* 6.1.10 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -61,13 +61,16 @@
/* added symbol to enable */
/* stack error handler, */
/* resulting in version 6.1.7 */
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* stack check error handling, */
/* resulting in version 6.1.9 */
/* 01-31-2022 Scott Larson Modified comment(s), unified */
/* this file across compilers, */
/* fixed predefined macro, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -196,14 +199,14 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -429,9 +432,9 @@ __attribute__( ( always_inline ) ) static inline void _tx_control_set(ULONG cont
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
}
#else
@@ -456,26 +459,26 @@ __attribute__( ( always_inline ) ) static inline void _tx_control_set(ULONG cont
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
TX_VFP_TOUCH(); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
} \
} \
} \
@@ -657,7 +660,7 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
UINT interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_tx_ipsr_get() == 0)
{
interrupt_save = __get_interrupt_posture();
@@ -29,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/MPU/AC6 */
/* 6.1.7 */
/* _tx_thread_schedule Cortex-M33/AC6 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -69,6 +69,9 @@
/* 06-02-2021 Scott Larson Fixed extended stack handling */
/* when calling kernel APIs, */
/* resulting in version 6.1.7 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -128,7 +131,12 @@ MemManage_Handler:
.thumb_func
BusFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -195,7 +203,7 @@ BusFault_Handler:
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
CPSID i // Disable interrupts
BL _tx_execution_thread_exit // Call the thread exit function
@@ -211,7 +219,12 @@ BusFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#ifdef TX_SINGLE_MODE_SECURE
LDR lr, =0xFFFFFFFD // Exception return to secure
#else
@@ -235,12 +248,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -296,7 +319,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -305,7 +333,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -313,7 +346,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -330,7 +368,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -378,9 +421,17 @@ _skip_secure_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x74] // Pickup MPU address of data region
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #2 // Select MPU region 2
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 2
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
LDR r2, =0xE000ED98 // Get region register
@@ -393,6 +444,7 @@ _skip_secure_restore:
STR r2, [r3] // Set region to 4
LDM r0, {r2-r9} // Load second four MPU regions
STM r1, {r2-r9} // Store second four MPU regions
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+16 -13
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M33 */
/* 6.1.10 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -61,13 +61,16 @@
/* added symbol to enable */
/* stack error handler, */
/* resulting in version 6.1.7 */
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* stack check error handling, */
/* resulting in version 6.1.9 */
/* 01-31-2022 Scott Larson Modified comment(s), unified */
/* this file across compilers, */
/* fixed predefined macro, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -196,14 +199,14 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -429,9 +432,9 @@ __attribute__( ( always_inline ) ) static inline void _tx_control_set(ULONG cont
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
}
#else
@@ -456,26 +459,26 @@ __attribute__( ( always_inline ) ) static inline void _tx_control_set(ULONG cont
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
TX_VFP_TOUCH(); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
} \
} \
} \
@@ -657,7 +660,7 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
UINT interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_tx_ipsr_get() == 0)
{
interrupt_save = __get_interrupt_posture();
@@ -28,8 +28,8 @@
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/MPU/GNU */
/* 6.1.10 */
/* _tx_thread_schedule Cortex-M33/GNU */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -70,6 +70,9 @@
/* resulting in version 6.1.7 */
/* 01-31-2022 Scott Larson Fixed predefined macro name, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -129,7 +132,12 @@ MemManage_Handler:
.thumb_func
BusFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -196,7 +204,7 @@ BusFault_Handler:
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
CPSID i // Disable interrupts
BL _tx_execution_thread_exit // Call the thread exit function
@@ -212,7 +220,12 @@ BusFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#ifdef TX_SINGLE_MODE_SECURE
LDR lr, =0xFFFFFFFD // Exception return to secure
#else
@@ -236,12 +249,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -297,7 +320,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -306,7 +334,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -314,7 +347,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -331,7 +369,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -379,9 +422,17 @@ _skip_secure_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x74] // Pickup MPU address of data region
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #2 // Select MPU region 2
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 2
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
LDR r2, =0xE000ED98 // Get region register
@@ -394,6 +445,7 @@ _skip_secure_restore:
STR r2, [r3] // Set region to 4
LDM r0, {r2-r9} // Load second four MPU regions
STM r1, {r2-r9} // Store second four MPU regions
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+16 -13
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M33 */
/* 6.1.10 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -61,13 +61,16 @@
/* added symbol to enable */
/* stack error handler, */
/* resulting in version 6.1.7 */
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* stack check error handling, */
/* resulting in version 6.1.9 */
/* 01-31-2022 Scott Larson Modified comment(s), unified */
/* this file across compilers, */
/* fixed predefined macro, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -196,14 +199,14 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -429,9 +432,9 @@ __attribute__( ( always_inline ) ) static inline void _tx_control_set(ULONG cont
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
}
#else
@@ -456,26 +459,26 @@ __attribute__( ( always_inline ) ) static inline void _tx_control_set(ULONG cont
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
TX_VFP_TOUCH(); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_control_set(_tx_vfp_state); \
_tx_control_set(_tx_vfp_state); \
} \
} \
} \
@@ -657,7 +660,7 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
UINT interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_tx_ipsr_get() == 0)
{
interrupt_save = __get_interrupt_posture();
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/IAR */
/* 6.1.8 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -81,6 +81,9 @@
/* 06-02-2021 Scott Larson Fixed extended stack handling */
/* when calling kernel APIs, */
/* resulting in version 6.1.7 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -132,7 +135,12 @@ __tx_wait_here:
MemManage_Handler:
BusFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -199,7 +207,7 @@ BusFault_Handler:
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
CPSID i // Disable interrupts
BL _tx_execution_thread_exit // Call the thread exit function
@@ -215,7 +223,12 @@ BusFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#ifdef TX_SINGLE_MODE_SECURE
LDR lr, =0xFFFFFFFD // Exception return to secure
#else
@@ -232,12 +245,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -293,7 +316,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -302,7 +330,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -310,7 +343,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -327,7 +365,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -375,9 +418,17 @@ _skip_secure_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x74] // Pickup MPU address of data region
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #2 // Select MPU region 2
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 2
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
LDR r2, =0xE000ED98 // Get region register
@@ -390,6 +441,7 @@ _skip_secure_restore:
STR r2, [r3] // Set region to 4
LDM r0, {r2-r9} // Load second four MPU regions
STM r1, {r2-r9} // Store second four MPU regions
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
@@ -412,8 +464,8 @@ _skip_vfp_restore:
SVC_Handler:
TST lr, #0x04 // Determine return stack from EXC_RETURN bit 2
ITE EQ
MRSEQ r0, MSP // Get MSP
MRSNE r0, PSP // Get PSP
MRSEQ r0, MSP // Get MSP if return stack is MSP
MRSNE r0, PSP // Get PSP if return stack is PSP
LDR r1, [r0,#24] // Load saved PC from stack
LDRB r2, [r1,#-2] // Load SVC number
+9 -6
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M4/AC5 */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -282,7 +285,7 @@ void _tx_vfp_access(void);
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -435,7 +438,7 @@ unsigned int was_masked;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_ipsr == 0)
{
was_masked = __disable_irq();
@@ -458,7 +461,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/AC5 Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/AC5 Version 6.1.11 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/AC5 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -67,13 +67,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -125,7 +127,12 @@ __tx_wait_here
EXPORT MemManage_Handler
MemManage_Handler
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -208,7 +215,12 @@ MemManage_Handler
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -226,12 +238,22 @@ __tx_ts_handler
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -276,7 +298,12 @@ __tx_ts_new
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -285,7 +312,12 @@ __tx_ts_new
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -293,7 +325,12 @@ __tx_ts_wait
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -310,7 +347,12 @@ __tx_ts_restore
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -346,27 +388,34 @@ __tx_ts_restore
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+11 -7
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M4/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -291,7 +294,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -467,7 +470,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -497,7 +501,7 @@ unsigned int interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
@@ -508,7 +512,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/AC6 Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/AC6 Version 6.1.11 *";
#else
extern CHAR _tx_version_id[];
#endif
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -69,13 +69,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -135,7 +137,12 @@ BusFault_Handler:
.thumb_func
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -197,7 +204,7 @@ UsageFault_Handler:
LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address
LDR r1, [r0] // Load FPCCR
BIC r1, r1, #1 // Clear the lazy preservation active bit
STR r1, [r0] // Store the value
STR r1, [r0] // Save FPCCR
#endif
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
@@ -218,7 +225,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -239,12 +251,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -289,7 +311,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -298,7 +325,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -306,7 +338,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -323,7 +360,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -359,27 +401,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
@@ -538,14 +587,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
STM r0!, {r1-r2} // Insert r0, r1 into thread stack
LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
STM r0!, {r1-r2} // Insert r2, r3 into thread stack
LDM r3!, {r1-r2} // Get r12, lr from kernel stack
STM r0!, {r1-r2} // Insert r12, lr into thread stack
LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
+12 -8
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M4/GNU */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -291,7 +294,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -461,7 +464,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -491,8 +495,8 @@ unsigned int interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
thread. This is for legacy only, and not needed any longer. */
/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
void tx_thread_fpu_disable(void);
@@ -502,7 +506,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/GNU Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/GNU Version 6.1.11 *";
#else
extern CHAR _tx_version_id[];
#endif
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/GNU */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -67,7 +67,6 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
@@ -76,6 +75,9 @@
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 01-31-2022 Scott Larson Fixed predefined macro name, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -135,7 +137,12 @@ BusFault_Handler:
.thumb_func
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -197,7 +204,7 @@ UsageFault_Handler:
LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address
LDR r1, [r0] // Load FPCCR
BIC r1, r1, #1 // Clear the lazy preservation active bit
STR r1, [r0] // Store the value
STR r1, [r0] // Save FPCCR
#endif
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
@@ -218,7 +225,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -239,12 +251,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -289,7 +311,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -298,7 +325,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -306,7 +338,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -323,7 +360,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -359,27 +401,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+9 -6
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M4/IAR */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -127,14 +130,14 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
@@ -325,7 +328,7 @@ void _tx_misra_vfp_touch(void);
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -476,7 +479,7 @@ static void _tx_thread_system_return_inline(void)
__istate_t interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_IPSR() == 0)
{
interrupt_save = __get_interrupt_state();
@@ -488,7 +491,7 @@ __istate_t interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/IAR */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -63,13 +63,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -125,8 +127,12 @@ __tx_wait_here:
MemManage_Handler:
BusFault_Handler:
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -209,7 +215,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -227,12 +238,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -277,7 +298,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -286,7 +312,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -294,7 +325,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -311,7 +347,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -347,27 +388,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+9 -6
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M7/AC5 */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -282,7 +285,7 @@ void _tx_vfp_access(void);
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -435,7 +438,7 @@ unsigned int was_masked;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_ipsr == 0)
{
was_masked = __disable_irq();
@@ -458,7 +461,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/AC5 Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/AC5 Version 6.1.11 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/AC5 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -67,13 +67,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -125,7 +127,12 @@ __tx_wait_here
EXPORT MemManage_Handler
MemManage_Handler
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -208,7 +215,12 @@ MemManage_Handler
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -226,12 +238,22 @@ __tx_ts_handler
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -276,7 +298,12 @@ __tx_ts_new
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -285,7 +312,12 @@ __tx_ts_new
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -293,7 +325,12 @@ __tx_ts_wait
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -310,7 +347,12 @@ __tx_ts_restore
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -346,27 +388,34 @@ __tx_ts_restore
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
+11 -7
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M7/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -291,7 +294,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -467,7 +470,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -497,7 +501,7 @@ unsigned int interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
@@ -508,7 +512,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/AC6 Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/AC6 Version 6.1.11 *";
#else
extern CHAR _tx_version_id[];
#endif
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/AC6 */
/* 6.1.9 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -69,13 +69,15 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -135,7 +137,12 @@ BusFault_Handler:
.thumb_func
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -197,7 +204,7 @@ UsageFault_Handler:
LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address
LDR r1, [r0] // Load FPCCR
BIC r1, r1, #1 // Clear the lazy preservation active bit
STR r1, [r0] // Store the value
STR r1, [r0] // Save FPCCR
#endif
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
@@ -218,7 +225,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -239,12 +251,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -289,7 +311,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -298,7 +325,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -306,7 +338,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -323,7 +360,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -359,27 +401,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
@@ -538,14 +587,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2}
STM r0!, {r1-r2}
LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
STM r0!, {r1-r2} // Insert r0, r1 into thread stack
LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
STM r0!, {r1-r2} // Insert r2, r3 into thread stack
LDM r3!, {r1-r2} // Get r12, lr from kernel stack
STM r0!, {r1-r2} // Insert r12, lr into thread stack
LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
+12 -8
View File
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M7/GNU */
/* 6.1.9 */
/* 6.1.11 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
@@ -123,13 +126,13 @@ typedef unsigned short USHORT;
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004)
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
@@ -291,7 +294,7 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = *((volatile ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
@@ -461,7 +464,8 @@ __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_i
{
unsigned int interrupt_save;
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_primask_value();
@@ -491,8 +495,8 @@ unsigned int interrupt_save;
#endif
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
thread. This is for legacy only, and not needed any longer. */
/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
void tx_thread_fpu_disable(void);
@@ -502,7 +506,7 @@ void tx_thread_fpu_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/GNU Version 6.1.9 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/GNU Version 6.1.11 *";
#else
extern CHAR _tx_version_id[];
#endif
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/GNU */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -67,7 +67,6 @@
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
@@ -76,6 +75,9 @@
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* 01-31-2022 Scott Larson Fixed predefined macro name, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -135,7 +137,12 @@ BusFault_Handler:
.thumb_func
UsageFault_Handler:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
/* Now pickup and store all the fault related information. */
@@ -197,7 +204,7 @@ UsageFault_Handler:
LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address
LDR r1, [r0] // Load FPCCR
BIC r1, r1, #1 // Clear the lazy preservation active bit
STR r1, [r0] // Store the value
STR r1, [r0] // Save FPCCR
#endif
BL _txm_module_manager_memory_fault_handler // Call memory manager fault handler
@@ -218,7 +225,12 @@ UsageFault_Handler:
LDR r1, =0x10000000 // Set PENDSVSET bit
STR r1, [r0] // Store ICSR
DSB // Wait for memory access to complete
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
MOV lr, #0xFFFFFFFD // Load exception return code
BX lr // Return from exception
@@ -239,12 +251,22 @@ __tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif /* TX_PORT_USE_BASEPRI */
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
#ifdef TX_PORT_USE_BASEPRI
MOV r0, 0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r0
#else
CPSIE i // Enable interrupts
#endif
#endif /* TX_PORT_USE_BASEPRI */
#endif /* EXECUTION PROFILE */
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
@@ -289,7 +311,12 @@ __tx_ts_new:
/* Now we are looking for a new thread to execute! */
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Is there another thread ready to execute?
CBNZ r1, __tx_ts_restore // Yes, schedule it
@@ -298,7 +325,12 @@ __tx_ts_new:
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
@@ -306,7 +338,12 @@ __tx_ts_wait:
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
@@ -323,7 +360,12 @@ __tx_ts_restore:
and enable interrupts. */
STR r1, [r0] // Setup the current thread pointer to the new thread
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
/* Increment the thread run count. */
@@ -359,27 +401,34 @@ __tx_ts_restore:
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
LDR r1, [r0, #0x64] // Pickup MPU register[0]
CBZ r1, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
LDR r1, =0xE000ED9C // Build address of MPU base register
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
// Is the MPU already set up for this module?
MOV r1, #5 // Select region 5 from MPU
LDR r3, =0xE000ED98 // MPU_RNR register address
STR r1, [r3] // Set region to 5
LDR r1, =0xE000ED9C // MPU_RBAR register address
LDR r3, [r1] // Load address stored in MPU region 5
BIC r2, r2, #0x10 // Clear VALID bit
CMP r2, r3 // Is module already loaded?
BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
STM r1,{r2-r9} // Store MPU regions 4-7
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#else
LDM r0!,{r2-r9} // Load first four MPU regions
STM r1,{r2-r9} // Store first four MPU regions
LDM r0,{r2-r9} // Load second four MPU regions
STM r1,{r2-r9} // Store second four MPU regions
#endif
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
File diff suppressed because it is too large Load Diff
@@ -1,119 +0,0 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
/**
* \file
* \section Purpose
*
* Utility for BMP
*
*/
#ifndef BMP_H
#define BMP_H
/** BMP magic number ('BM'). */
#define BMP_TYPE 0x4D42
/** headerSize must be set to 40 */
#define BITMAPINFOHEADER 40
/*------------------------------------------------------------------------------
* Exported types
*------------------------------------------------------------------------------*/
#pragma pack( 1 )
/** BMP (Windows) Header Format */
typedef struct _BMPHeader{
/* signature, must be 4D42 hex */
uint16_t type;
/* size of BMP file in bytes (unreliable) */
uint32_t fileSize;
/* reserved, must be zero */
uint16_t reserved1;
/* reserved, must be zero */
uint16_t reserved2;
/* offset to start of image data in bytes */
uint32_t offset;
/* size of BITMAPINFOHEADER structure, must be 40 */
uint32_t headerSize;
/* image width in pixels */
uint32_t width;
/* image height in pixels */
uint32_t height;
/* number of planes in the image, must be 1 */
uint16_t planes;
/* number of bits per pixel (1, 4, 8, 16, 24, 32) */
uint16_t bits;
/* compression type (0=none, 1=RLE-8, 2=RLE-4) */
uint32_t compression;
/* size of image data in bytes (including padding) */
uint32_t imageSize;
/* horizontal resolution in pixels per meter (unreliable) */
uint32_t xresolution;
/* vertical resolution in pixels per meter (unreliable) */
uint32_t yresolution;
/* number of colors in image, or zero */
uint32_t ncolours;
/* number of important colors, or zero */
uint32_t importantcolours;
} BMPHeader;
#pragma pack()
/*------------------------------------------------------------------------------
* Exported functions
*------------------------------------------------------------------------------*/
extern uint8_t BMP_IsValid(void *file);
extern uint32_t BMP_GetFileSize(void *file);
extern uint8_t BMP_Decode(
void *file,
uint8_t *buffer,
uint32_t width,
uint32_t height,
uint8_t bpp );
extern void WriteBMPheader(
uint32_t *pAddressHeader,
uint32_t bmpHSize,
uint32_t bmpVSize,
uint8_t nbByte_Pixels );
extern void BMP_displayHeader(uint32_t* pAddressHeader);
extern void RGB565toBGR555(
uint8_t *fileSource,
uint8_t *fileDestination,
uint32_t width,
uint32_t height,
uint8_t bpp );
#endif //#ifndef BMP_H
@@ -1,47 +0,0 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for the low-level initialization function.
*
*/
#ifndef BOARD_LOWLEVEL_H
#define BOARD_LOWLEVEL_H
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void LowLevelInit( void );
extern void _SetupMemoryRegion( void );
#endif /* BOARD_LOWLEVEL_H */

Some files were not shown because too many files have changed in this diff Show More