6.1 minor release

This commit is contained in:
Scott Larson
2020-09-30 15:42:41 -07:00
parent 7287542cc8
commit 1b5816a206
3038 changed files with 377204 additions and 8606 deletions

View File

@@ -0,0 +1,210 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Initialize */
/** */
/**************************************************************************/
/**************************************************************************/
SYSTEM_CLOCK = 6000000
SYSTICK_CYCLES = ((SYSTEM_CLOCK / 100) -1)
/* Setup the stack and heap areas. */
STACK_SIZE = 0x00000400
HEAP_SIZE = 0x00000000
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for any low-level processor */
/* initialization, including setting up interrupt vectors, setting */
/* up a periodic timer interrupt source, saving the system stack */
/* pointer for use in ISR processing later, and finding the first */
/* available RAM memory address for tx_application_define. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// VOID _tx_initialize_low_level(VOID)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_initialize_low_level
.thumb_func
.type _tx_initialize_low_level, function
_tx_initialize_low_level:
/* Disable interrupts during ThreadX initialization. */
CPSID i
/* Set base of available memory to end of non-initialised RAM area. */
LDR r0, =_tx_initialize_unused_memory // Build address of unused memory pointer
LDR r1, =Image$$ARM_LIB_STACK$$ZI$$Limit // Build first free address
ADDS r1, r1, #4 //
STR r1, [r0] // Setup first unused memory pointer
/* Setup Vector Table Offset Register. */
LDR r0, =0xE000ED08 // Build address of NVIC registers
LDR r1, =__Vectors // Pickup address of vector table
STR r1, [r0] // Set vector table address
// /* Enable the cycle count register. */
//
// LDR r0, =0xE0001000 // Build address of DWT register
// LDR r1, [r0] // Pickup the current value
// ORR r1, r1, #1 // Set the CYCCNTENA bit
// STR r1, [r0] // Enable the cycle count register
/* Set system stack pointer from vector value. */
LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer
LDR r1, =__Vectors // Pickup address of vector table
LDR r1, [r1] // Pickup reset stack pointer
STR r1, [r0] // Save system stack pointer
/* Configure SysTick. */
LDR r0, =0xE000E000 // Build address of NVIC registers
LDR r1, =SYSTICK_CYCLES
STR r1, [r0, #0x14] // Setup SysTick Reload Value
MOVW r1, #0x7 // Build SysTick Control Enable Value
STR r1, [r0, #0x10] // Setup SysTick Control
/* Configure handler priorities. */
LDR r1, =0x00000000 // Rsrv, UsgF, BusF, MemM
LDR r0, =0xE000E000 // Build address of NVIC registers
LDR r2, =0xD18 //
ADD r0, r0, r2 //
STR r1, [r0] // Setup System Handlers 4-7 Priority Registers
LDR r1, =0xFF000000 // SVCl, Rsrv, Rsrv, Rsrv
LDR r0, =0xE000E000 // Build address of NVIC registers
LDR r2, =0xD1C //
ADD r0, r0, r2 //
STR r1, [r0] // Setup System Handlers 8-11 Priority Registers
// Note: SVC must be lowest priority, which is 0xFF
LDR r1, =0x40FF0000 // SysT, PnSV, Rsrv, DbgM
LDR r0, =0xE000E000 // Build address of NVIC registers
LDR r2, =0xD20 //
ADD r0, r0, r2 //
STR r1, [r0] // Setup System Handlers 12-15 Priority Registers
// Note: PnSV must be lowest priority, which is 0xFF
/* Return to caller. */
BX lr
// }
/* Define shells for each of the unused vectors. */
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global __tx_BadHandler
.thumb_func
.type __tx_BadHandler, function
__tx_BadHandler:
B __tx_BadHandler
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global __tx_IntHandler
.thumb_func
.type __tx_IntHandler, function
__tx_IntHandler:
// VOID InterruptHandler (VOID)
// {
PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment)
/* Do interrupt handler work here */
/* .... */
POP {r0, r1}
MOV lr, r1
BX lr
// }
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global SysTick_Handler
.thumb_func
.type SysTick_Handler, function
SysTick_Handler:
// VOID TimerInterruptHandler (VOID)
// {
PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment)
BL _tx_timer_interrupt
POP {r0, r1}
MOV lr, r1
BX lr
// }
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global HardFault_Handler
.thumb_func
.type HardFault_Handler, function
HardFault_Handler:
// A stack overflow will trigger a hardfault.
// There is no CFSR in M23, so we will not try to
// determine if the fault is caused by a stack overflow
// or some other condition.
B HardFault_Handler
.end

View File

@@ -0,0 +1,74 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is not needed for Cortex-M. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* None */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// VOID _tx_thread_context_restore(VOID)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_context_restore
.thumb_func
.type _tx_thread_context_restore, function
_tx_thread_context_restore:
/* Return to interrupt processing. */
BX lr
// }
.end

View File

@@ -0,0 +1,74 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is not needed for Cortex-M. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* None */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// VOID _tx_thread_context_save(VOID)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_context_save
.thumb_func
.type _tx_thread_context_save, function
_tx_thread_context_save:
/* Return to interrupt processing. */
BX lr
// }
.end

View File

@@ -0,0 +1,78 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for changing the interrupt lockout */
/* posture of the system. */
/* */
/* INPUT */
/* */
/* new_posture New interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// UINT _tx_thread_interrupt_control(UINT new_posture)
// {
.section .text
.balign 4
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_interrupt_control
.thumb_func
.type _tx_thread_interrupt_control, function
_tx_thread_interrupt_control:
/* Pickup current interrupt lockout posture. */
MRS r1, PRIMASK
MSR PRIMASK, r0
MOV r0, r1
BX lr
// }
.end

View File

@@ -0,0 +1,77 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for disabling interrupts and returning */
/* the previous interrupt lockout posture. */
/* */
/* INPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// UINT _tx_thread_interrupt_disable(UINT new_posture)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_interrupt_disable
.thumb_func
.type _tx_thread_interrupt_disable, function
_tx_thread_interrupt_disable:
/* Return current interrupt lockout posture. */
MRS r0, PRIMASK
CPSID i
BX lr
// }
.end

View File

@@ -0,0 +1,76 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for restoring the previous */
/* interrupt lockout posture. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* previous_posture Previous interrupt posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// VOID _tx_thread_interrupt_restore(UINT new_posture)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_interrupt_restore
.thumb_func
.type _tx_thread_interrupt_restore, function
_tx_thread_interrupt_restore:
/* Restore previous interrupt lockout posture. */
MSR PRIMASK, r0
BX lr
// }
.end

View File

@@ -0,0 +1,327 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function waits for a thread control block pointer to appear in */
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
/* in the variable, the corresponding thread is resumed. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_schedule
.thumb_func
.type _tx_thread_schedule, function
_tx_thread_schedule:
/* This function should only ever be called on Cortex-M
from the first schedule request. Subsequent scheduling occurs
from the PendSV handling routine below. */
/* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */
MOVW r0, #0 // Build value for TX_FALSE
LDR r2, =_tx_thread_preempt_disable // Build address of preempt disable flag
STR r0, [r2, #0] // Clear preempt disable flag
/* Enable interrupts */
CPSIE i
/* Enter the scheduler for the first time. */
LDR r0, =0x10000000 // Load PENDSVSET bit
LDR r1, =0xE000ED04 // Load ICSR address
STR r0, [r1] // Set PENDSVBIT in ICSR
DSB // Complete all memory accesses
ISB // Flush pipeline
/* Wait here for the PendSV to take place. */
__tx_wait_here:
B __tx_wait_here // Wait for the PendSV to happen
// }
/* Generic context switching PendSV handler. */
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global PendSV_Handler
.thumb_func
.type PendSV_Handler, function
/* Get current thread value and new thread pointer. */
PendSV_Handler:
__tx_ts_handler:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the thread exit function to indicate the thread is no longer executing. */
CPSID i // Disable interrupts
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, r1} // Recover LR
MOV lr, r1
CPSIE i // Enable interrupts
#endif
MOVW r0, #:lower16:_tx_thread_current_ptr // Build current thread pointer address
MOVT r0, #:upper16:_tx_thread_current_ptr
MOVW r2, #:lower16:_tx_thread_execute_ptr // Build execute thread pointer address
MOVT r2, #:upper16:_tx_thread_execute_ptr
MOVW r3, #0 // Build NULL value
LDR r1, [r0] // Pickup current thread pointer
/* Determine if there is a current thread to finish preserving. */
CBZ r1, __tx_ts_new // If NULL, skip preservation
/* Recover PSP and preserve current thread context. */
STR r3, [r0] // Set _tx_thread_current_ptr to NULL
MRS r3, PSP // Pickup PSP pointer (thread's stack pointer)
SUBS r3, r3, #16 // Allocate stack space
STM r3!, {r4-r7} // Save its remaining registers (M3 Instruction: STMDB r12!, {r4-r11})
MOV r4, r8 //
MOV r5, r9 //
MOV r6, r10 //
MOV r7, r11 //
SUBS r3, r3, #32 // Allocate stack space
STM r3!, {r4-r7} //
SUBS r3, r3, #20 // Allocate stack space
MOV r5, lr //
STR r5, [r3] // Save LR on the stack
STR r3, [r1, #8] // Save the thread stack pointer
#if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE))
// Save secure context
LDR r5, =0x90 // Secure stack index offset
LDR r5, [r1, r5] // Load secure stack index
CBZ r5, _skip_secure_save // Skip save if there is no secure context
PUSH {r0, r1, r2, r3} // Save scratch registers
MOV r0, r1 // Move thread ptr to r0
BL _tx_thread_secure_stack_context_save // Save secure stack
POP {r0, r1, r2, r3} // Restore secure registers
_skip_secure_save:
#endif
/* Determine if time-slice is active. If it isn't, skip time handling processing. */
LDR r4, =_tx_timer_time_slice // Build address of time-slice variable
LDR r5, [r4] // Pickup current time-slice
CBZ r5, __tx_ts_new // If not active, skip processing
/* Time-slice is active, save the current thread's time-slice and clear the global time-slice variable. */
STR r5, [r1, #24] // Save current time-slice
/* Clear the global time-slice. */
MOVW r5, #0 // Build clear value
STR r5, [r4] // Clear time-slice
/* Executing thread is now completely preserved!!! */
__tx_ts_new:
/* Now we are looking for a new thread to execute! */
CPSID i // Disable interrupts
LDR r1, [r2] // Is there another thread ready to execute?
CBZ r1, __tx_ts_wait // No, skip to the wait processing
/* Yes, another thread is ready for else, make the current thread the new thread. */
STR r1, [r0] // Setup the current thread pointer to the new thread
CPSIE i // Enable interrupts
/* Increment the thread run count. */
__tx_ts_restore:
LDR r7, [r1, #4] // Pickup the current thread run count
MOVW r4, #:lower16:_tx_timer_time_slice // Build address of time-slice variable
MOVT r4, #:upper16:_tx_timer_time_slice
LDR r5, [r1, #24] // Pickup thread's current time-slice
ADDS r7, r7, #1 // Increment the thread run count
STR r7, [r1, #4] // Store the new run count
/* Setup global time-slice with thread's current time-slice. */
STR r5, [r4] // Setup global time-slice
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the thread entry function to indicate the thread is executing. */
PUSH {r0, r1} // Save r0/r1
BL _tx_execution_thread_enter // Call the thread execution enter function
POP {r0, r1} // Recover r0/r1
#endif
#if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE))
// Restore secure context
LDR r5, =0x90 // Secure stack index offset
LDR r0, [r1, r5] // Load secure stack index
CBZ r0, _skip_secure_restore // Skip restore if there is no secure context
PUSH {r0, r1} // Save r1 (and dummy r0)
MOV r0, r1 // Move thread ptr to r0
BL _tx_thread_secure_stack_context_restore // Restore secure stack
POP {r0, r1} // Restore r1 (and dummy r0)
_skip_secure_restore:
#endif
/* Restore the thread context and PSP. */
#ifdef TX_SINGLE_MODE_SECURE
// There are only stack limit registers in secure mode on the M23
LDR r3, [r1, #12] // Get stack start
MSR PSPLIM, r3 // Set stack limit
#endif
LDR r3, [r1, #8] // Pickup thread's stack pointer
LDR r5, [r3] // Recover saved LR
ADDS r3, r3, #4 // Position past LR
MOV lr, r5 // Restore LR
LDM r3!, {r4-r7} // Recover thread's registers (r4-r11)
MOV r11, r7 //
MOV r10, r6 //
MOV r9, r5 //
MOV r8, r4 //
LDM r3!, {r4-r7} //
MSR PSP, r3 // Setup the thread's stack pointer
/* Return to thread. */
BX lr // Return to thread!
/* The following is the idle wait processing... in this case, no threads are ready for execution and the
system will simply be idle until an interrupt occurs that makes a thread ready. Note that interrupts
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
CPSID i // Disable interrupts
LDR r1, [r2] // Pickup the next thread to execute pointer
STR r1, [r0] // Store it in the current pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_ENABLE_WFI
DSB // Ensure no outstanding memory transactions
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
CPSIE i // Enable interrupts
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
already in the handler! */
__tx_ts_ready:
LDR r7, =0x08000000 // Build clear PendSV value
LDR r5, =0xE000ED04 // Build ICSR address
STR r7, [r5] // Clear any PendSV
/* Re-enable interrupts and restore new thread. */
CPSIE i // Enable interrupts
B __tx_ts_restore // Restore the thread
#if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE))
// SVC_Handler is not needed when ThreadX is running in single mode.
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global SVC_Handler
.thumb_func
.type SVC_Handler, function
SVC_Handler:
MOVW r0, #4
MOV r1, lr
TST r1, r0 // Determine return stack from EXC_RETURN bit 2
BEQ _tx_get_msp
MRS r0, PSP // Get PSP if return stack is PSP
B _tx_got_sp
_tx_get_msp:
MRS r0, MSP // Get MSP if return stack is MSP
_tx_got_sp:
LDR r1, [r0, #24] // Load saved PC from stack
SUBS r1, r1, #2 // Calculate SVC number address
LDRB r1, [r1] // Load SVC number
CMP r1, #1 // Is it a secure stack allocate request?
BEQ _tx_svc_secure_alloc // Yes, go there
CMP r1, #2 // Is it a secure stack free request?
BEQ _tx_svc_secure_free // Yes, go there
// Unknown SVC argument - just return
BX lr
_tx_svc_secure_alloc:
PUSH {r0, lr} // Save SP and EXC_RETURN
LDM r0, {r0-r3} // Load function parameters from stack
BL _tx_thread_secure_mode_stack_allocate
POP {r1, r2} // Restore SP and EXC_RETURN
STR r0, [r1] // Store function return value
MOV lr, r2
BX lr
_tx_svc_secure_free:
PUSH {r0, lr} // Save SP and EXC_RETURN
LDM r0, {r0-r3} // Load function parameters from stack
BL _tx_thread_secure_mode_stack_free
POP {r1, r2} // Restore SP and EXC_RETURN
STR r0, [r1] // Store function return value
MOV lr, r2
BX lr
#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE
.end

View File

@@ -0,0 +1,467 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
#include "tx_api.h"
/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
no secure stack functionality is needed. */
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
#define TX_SOURCE_CODE
#include "ARMCM23_TZ.h" /* For intrinsic functions. */
#include "tx_secure_interface.h" /* Interface for NS code. */
/* Minimum size of secure stack. */
#ifndef TX_THREAD_SECURE_STACK_MINIMUM
#define TX_THREAD_SECURE_STACK_MINIMUM 256
#endif
/* Maximum size of secure stack. */
#ifndef TX_THREAD_SECURE_STACK_MAXIMUM
#define TX_THREAD_SECURE_STACK_MAXIMUM 1024
#endif
/* Secure stack info struct to hold stack start, stack limit,
current stack pointer, and pointer to owning thread.
This will be allocated for each thread with a secure stack. */
typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
{
VOID *tx_thread_secure_stack_ptr; /* Thread's secure stack current pointer */
VOID *tx_thread_secure_stack_start; /* Thread's secure stack start address */
VOID *tx_thread_secure_stack_limit; /* Thread's secure stack limit */
TX_THREAD *tx_thread_ptr; /* Keep track of thread for error handling */
} TX_THREAD_SECURE_STACK_INFO;
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_initialize Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes secure mode to use PSP stack. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* __get_CONTROL Intrinsic to get CONTROL */
/* __set_CONTROL Intrinsic to set CONTROL */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_initialize(void)
{
/* Set secure mode to use PSP. */
__set_CONTROL(__get_CONTROL() | 2);
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
return;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates a thread's secure stack. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* stack_size Size of stack to allocates */
/* */
/* OUTPUT */
/* */
/* TX_THREAD_ERROR Invalid thread pointer */
/* TX_SIZE_ERROR Invalid stack size */
/* TX_CALLER_ERROR Invalid caller of function */
/* status Actual completion status */
/* */
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
/* calloc Compiler's calloc function */
/* malloc Compiler's malloc function */
/* free Compiler's free() function */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* __TZ_get_PSPLIM_NS Intrinsic to get NS PSP */
/* */
/* CALLED BY */
/* */
/* SVC Handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
ULONG sp;
status = TX_SUCCESS;
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
status = TX_CALLER_ERROR;
}
else if (stack_size < TX_THREAD_SECURE_STACK_MINIMUM || stack_size > TX_THREAD_SECURE_STACK_MAXIMUM)
{
status = TX_SIZE_ERROR;
}
/* Check if thread already has secure stack allocated. */
else if (thread_ptr -> tx_thread_secure_stack_context != 0)
{
status = TX_THREAD_ERROR;
}
else
{
/* Allocate space for secure stack info. */
info_ptr = calloc(1, sizeof(TX_THREAD_SECURE_STACK_INFO));
if(info_ptr != TX_NULL)
{
/* If stack info allocated, allocate a stack. */
stack_mem = malloc(stack_size);
if(stack_mem != TX_NULL)
{
/* Secure stack has been allocated, save in the stack info struct. */
info_ptr -> tx_thread_secure_stack_limit = stack_mem;
info_ptr -> tx_thread_secure_stack_start = stack_mem + stack_size;
info_ptr -> tx_thread_secure_stack_ptr = info_ptr -> tx_thread_secure_stack_start;
info_ptr -> tx_thread_ptr = thread_ptr;
/* Save info pointer in thread. */
thread_ptr -> tx_thread_secure_stack_context = info_ptr;
/* Check if this thread is running by looking at PSP_NS and seeing if it is within
the stack_start and stack_end range. */
sp = __TZ_get_PSP_NS();
if(sp > ((ULONG) thread_ptr -> tx_thread_stack_start) && sp < ((ULONG) thread_ptr -> tx_thread_stack_end))
{
/* If this thread is running, set Secure PSP and PSPLIM. */
__set_PSPLIM((ULONG)(info_ptr -> tx_thread_secure_stack_limit));
__set_PSP((ULONG)(info_ptr -> tx_thread_secure_stack_ptr));
}
}
else
{
/* Stack not allocated, free the info struct. */
free(info_ptr);
status = TX_NO_MEMORY;
}
}
else
{
status = TX_NO_MEMORY;
}
}
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function frees a thread's secure stack. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* */
/* OUTPUT */
/* */
/* TX_THREAD_ERROR Invalid thread pointer */
/* TX_CALLER_ERROR Invalid caller of function */
/* status Actual completion status */
/* */
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
/* free Compiler's free() function */
/* */
/* CALLED BY */
/* */
/* SVC Handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
status = TX_SUCCESS;
/* Pickup stack info from thread. */
info_ptr = thread_ptr -> tx_thread_secure_stack_context;
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
status = TX_CALLER_ERROR;
}
/* Check that this secure context is for this thread. */
else if (info_ptr -> tx_thread_ptr != thread_ptr)
{
status = TX_THREAD_ERROR;
}
else
{
/* Free secure stack. */
free(info_ptr -> tx_thread_secure_stack_limit);
/* Free info struct. */
free(info_ptr);
/* Clear secure context from thread. */
thread_ptr -> tx_thread_secure_stack_context = 0;
}
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function saves context of the secure stack. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
/* __get_PSP Intrinsic to get PSP */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* */
/* CALLED BY */
/* */
/* PendSV Handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
/* Pickup the secure context pointer. */
info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
/* Check that stack pointer is in range */
sp = __get_PSP();
if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
return;
}
/* Save stack pointer. */
*(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp;
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
return;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function restores context of the secure stack. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* */
/* CALLED BY */
/* */
/* PendSV Handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
/* Pickup the secure context pointer. */
info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
/* Set stack pointer and limit. */
__set_PSPLIM((ULONG)info_ptr -> tx_thread_secure_stack_limit);
__set_PSP ((ULONG)info_ptr -> tx_thread_secure_stack_ptr);
return;
}
#endif

View File

@@ -0,0 +1,86 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_allocate Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enters the SVC handler to allocate a secure stack. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* stack_size Size of secure stack to */
/* allocate */
/* */
/* OUTPUT */
/* */
/* status Actual completion status */
/* */
/* CALLS */
/* */
/* SVC 1 */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// UINT _tx_thread_secure_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_secure_stack_allocate
.thumb_func
.type _tx_thread_secure_stack_allocate, function
_tx_thread_secure_stack_allocate:
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
MRS r3, PRIMASK // Save interrupt mask
CPSIE i // Enable interrupts for SVC call
SVC 1
CMP r3, #0 // If interrupts enabled, just return
BEQ _alloc_return_interrupt_enabled
CPSID i // Otherwise, disable interrupts
#else
// Executing in single mode - this function is not needed.
MOVS r0, #0xFF // Feature not enabled
#endif
_alloc_return_interrupt_enabled:
BX lr
.end

View File

@@ -0,0 +1,84 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_free Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enters the SVC handler to free a secure stack. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* */
/* OUTPUT */
/* */
/* status Actual completion status */
/* */
/* CALLS */
/* */
/* SVC 2 */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// UINT _tx_thread_secure_stack_free(TX_THREAD *thread_ptr)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_secure_stack_free
.thumb_func
.type _tx_thread_secure_stack_free, function
_tx_thread_secure_stack_free:
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
MRS r3, PRIMASK // Save interrupt mask
CPSIE i // Enable interrupts for SVC call
SVC 2
CMP r3, #0 // If interrupts enabled, just return
BEQ _free_return_interrupt_enabled
CPSID i // Otherwise, disable interrupts
#else
// Executing in single mode - this function is not needed.
MOVS r0, #0xFF // Feature not enabled
#endif
_free_return_interrupt_enabled:
BX lr
.end

View File

@@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds a stack frame on the supplied thread's stack. */
/* The stack frame results in a fake interrupt return to the supplied */
/* function pointer. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to thread control blk */
/* function_ptr Pointer to return function */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_thread_create Create thread service */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_stack_build
.thumb_func
.type _tx_thread_stack_build, function
_tx_thread_stack_build:
/* Build a fake interrupt frame. The form of the fake interrupt stack
on the Cortex-M23 should look like the following after it is built:
Stack Top:
LR Interrupted LR (LR at time of PENDSV)
r8 Initial value for r8
r9 Initial value for r9
r10 Initial value for r10
r11 Initial value for r11
r4 Initial value for r4
r5 Initial value for r5
r6 Initial value for r6
r7 Initial value for r7
r0 Initial value for r0 (Hardware stack starts here!!)
r1 Initial value for r1
r2 Initial value for r2
r3 Initial value for r3
r12 Initial value for r12
lr Initial value for lr
pc Initial value for pc
xPSR Initial value for xPSR
Stack Bottom: (higher memory address) */
LDR r2, [r0, #16] // Pickup end of stack area
MOVW r3, #0x7 //
BICS r2, r2, r3 // Align frame for 8-byte alignment
SUBS r2, r2, #68 // Subtract frame size
#ifdef TX_SINGLE_MODE_SECURE
LDR r3, =0xFFFFFFFD // Build initial LR value for secure mode
#else
LDR r3, =0xFFFFFFBC // Build initial LR value to return to non-secure PSP
#endif
STR r3, [r2, #0] // Save on the stack
/* Actually build the stack frame. */
MOVW r3, #0 // Build initial register value
STR r3, [r2, #4] // Store initial r8
STR r3, [r2, #8] // Store initial r9
STR r3, [r2, #12] // Store initial r10
STR r3, [r2, #16] // Store initial r11
STR r3, [r2, #20] // Store initial r4
STR r3, [r2, #24] // Store initial r5
STR r3, [r2, #28] // Store initial r6
STR r3, [r2, #32] // Store initial r7
/* Hardware stack follows. */
STR r3, [r2, #36] // Store initial r0
STR r3, [r2, #40] // Store initial r1
STR r3, [r2, #44] // Store initial r2
STR r3, [r2, #48] // Store initial r3
STR r3, [r2, #52] // Store initial r12
LDR r3, =0xFFFFFFFF // Poison EXC_RETURN value
STR r3, [r2, #56] // Store initial lr
STR r1, [r2, #60] // Store initial pc
LDR r3, =0x01000000 // Only T-bit need be set
STR r3, [r2, #64] // Store initial xPSR
/* Setup stack pointer. */
// thread_ptr -> tx_thread_stack_ptr = r2;
STR r2, [r0, #8] // Save stack pointer in thread's
// control block
BX lr // Return to caller
// }
.end

View File

@@ -0,0 +1,93 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_thread.h"
/* Define the global function pointer for stack error handling. If a stack error is
detected and the application has registered a stack error handler, it will be
called via this function pointer. */
VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_error_handler Cortex-M23 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes stack errors detected during run-time. */
/* */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_terminate */
/* _tx_thread_application_stack_error_handler */
/* */
/* CALLED BY */
/* */
/* ThreadX internal code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr)
{
#ifndef TX_THREAD_NO_TERMINATE_STACK_ERROR
/* Is there a thread? */
if (thread_ptr)
{
/* Terminate the current thread. */
_tx_thread_terminate(_tx_thread_current_ptr);
}
#endif
/* Determine if the application has registered an error handler. */
if (_tx_thread_application_stack_error_handler != TX_NULL)
{
/* Yes, an error handler is present, simply call the application error handler. */
(_tx_thread_application_stack_error_handler)(thread_ptr);
}
}

View File

@@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_trace.h"
extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_error_notify Cortex-M23 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers an application stack error handler. If */
/* ThreadX detects a stack error, this application handler is called. */
/* */
/* */
/* INPUT */
/* */
/* stack_error_handler Pointer to stack error */
/* handler, TX_NULL to disable */
/* */
/* OUTPUT */
/* */
/* status Service return status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr))
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Make entry in event log. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_STACK_ERROR_NOTIFY, 0, 0, 0, 0, TX_TRACE_THREAD_EVENTS)
/* Make entry in event log. */
TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
/* Setup global thread stack error handler. */
_tx_thread_application_stack_error_handler = stack_error_handler;
/* Restore interrupts. */
TX_RESTORE
/* Return success to caller. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,89 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is target processor specific. It is used to transfer */
/* control from a thread back to the ThreadX system. Only a */
/* minimal context is saved since the compiler assumes temp registers */
/* are going to get slicked by a function call anyway. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling loop */
/* */
/* CALLED BY */
/* */
/* ThreadX components */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
// VOID _tx_thread_system_return(VOID)
// {
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_thread_system_return
.thumb_func
.type _tx_thread_system_return, function
_tx_thread_system_return:
/* Return to real scheduler via PendSV. Note that this routine is often
replaced with in-line assembly in tx_port.h to improved performance. */
LDR r0, =0x10000000 // Load PENDSVSET bit
LDR r1, =0xE000ED04 // Load ICSR address
STR r0, [r1] // Set PENDSVBIT in ICSR
MRS r0, IPSR // Pickup IPSR
CMP r0, #0 // Is it a thread returning?
BNE _isr_context // If ISR, skip interrupt enable
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
_isr_context:
BX lr // Return to caller
// }
.end

View File

@@ -0,0 +1,262 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Timer */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-M23/GNU */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the hardware timer interrupt. This */
/* processing includes incrementing the system clock and checking for */
/* time slice and/or timer expiration. If either is found, the */
/* interrupt context save/restore functions are called along with the */
/* expiration functions. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_timer_expiration_process Timer expiration processing */
/* _tx_thread_time_slice Time slice interrupted thread */
/* */
/* CALLED BY */
/* */
/* interrupt vector */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_timer_interrupt(VOID)
{ */
.section .text
.balign 4
.syntax unified
.eabi_attribute Tag_ABI_align_preserved, 1
.global _tx_timer_interrupt
.thumb_func
.type _tx_timer_interrupt, function
_tx_timer_interrupt:
/* Upon entry to this routine, it is assumed that the compiler scratch registers are available
for use. */
/* Increment the system clock. */
// _tx_timer_system_clock++;
MOVW r1, #:lower16:_tx_timer_system_clock // Pickup address of system clock
MOVT r1, #:upper16:_tx_timer_system_clock
LDR r0, [r1, #0] // Pickup system clock
ADDS r0, r0, #1 // Increment system clock
STR r0, [r1, #0] // Store new system clock
/* Test for time-slice expiration. */
// if (_tx_timer_time_slice)
// {
MOVW r3, #:lower16:_tx_timer_time_slice // Pickup address of time-slice
MOVT r3, #:upper16:_tx_timer_time_slice
LDR r2, [r3, #0] // Pickup time-slice
CBZ r2, __tx_timer_no_time_slice // Is it non-active?
// Yes, skip time-slice processing
/* Decrement the time_slice. */
// _tx_timer_time_slice--;
SUBS r2, r2, #1 // Decrement the time-slice
STR r2, [r3, #0] // Store new time-slice value
/* Check for expiration. */
// if (__tx_timer_time_slice == 0)
CBNZ r2, __tx_timer_no_time_slice // Has it expired?
/* Set the time-slice expired flag. */
// _tx_timer_expired_time_slice = TX_TRUE;
MOVW r3, #:lower16:_tx_timer_expired_time_slice // Pickup address of expired flag
MOVT r3, #:upper16:_tx_timer_expired_time_slice
MOVW r0, #1 // Build expired value
STR r0, [r3, #0] // Set time-slice expiration flag
// }
__tx_timer_no_time_slice:
/* Test for timer expiration. */
// if (*_tx_timer_current_ptr)
// {
MOVW r1, #:lower16:_tx_timer_current_ptr // Pickup current timer pointer address
MOVT r1, #:upper16:_tx_timer_current_ptr
LDR r0, [r1, #0] // Pickup current timer
LDR r2, [r0, #0] // Pickup timer list entry
CBZ r2, __tx_timer_no_timer // Is there anything in the list?
// No, just increment the timer
/* Set expiration flag. */
// _tx_timer_expired = TX_TRUE;
MOVW r3, #:lower16:_tx_timer_expired // Pickup expiration flag address
MOVT r3, #:upper16:_tx_timer_expired
MOVW r2, #1 // Build expired value
STR r2, [r3, #0] // Set expired flag
B __tx_timer_done // Finished timer processing
// }
// else
// {
__tx_timer_no_timer:
/* No timer expired, increment the timer pointer. */
// _tx_timer_current_ptr++;
ADDS r0, r0, #4 // Move to next timer
/* Check for wrap-around. */
// if (_tx_timer_current_ptr == _tx_timer_list_end)
MOVW r3, #:lower16:_tx_timer_list_end // Pickup addr of timer list end
MOVT r3, #:upper16:_tx_timer_list_end
LDR r2, [r3, #0] // Pickup list end
CMP r0, r2 // Are we at list end?
BNE __tx_timer_skip_wrap // No, skip wrap-around logic
/* Wrap to beginning of list. */
// _tx_timer_current_ptr = _tx_timer_list_start;
MOVW r3, #:lower16:_tx_timer_list_start // Pickup addr of timer list start
MOVT r3, #:upper16:_tx_timer_list_start
LDR r0, [r3, #0] // Set current pointer to list start
__tx_timer_skip_wrap:
STR r0, [r1, #0] // Store new current timer pointer
// }
__tx_timer_done:
/* See if anything has expired. */
// if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
// {
MOVW r3, #:lower16:_tx_timer_expired_time_slice // Pickup addr of expired flag
MOVT r3, #:upper16:_tx_timer_expired_time_slice
LDR r2, [r3, #0] // Pickup time-slice expired flag
CBNZ r2, __tx_something_expired // Did a time-slice expire?
// If non-zero, time-slice expired
MOVW r1, #:lower16:_tx_timer_expired // Pickup addr of other expired flag
MOVT r1, #:upper16:_tx_timer_expired
LDR r0, [r1, #0] // Pickup timer expired flag
CBZ r0, __tx_timer_nothing_expired // Did a timer expire?
// No, nothing expired
__tx_something_expired:
PUSH {r0, lr} // Save the lr register on the stack
// and save r0 just to keep 8-byte alignment
/* Did a timer expire? */
// if (_tx_timer_expired)
// {
MOVW r1, #:lower16:_tx_timer_expired // Pickup addr of expired flag
MOVT r1, #:upper16:_tx_timer_expired
LDR r0, [r1, #0] // Pickup timer expired flag
CBZ r0, __tx_timer_dont_activate // Check for timer expiration
// If not set, skip timer activation
/* Process timer expiration. */
// _tx_timer_expiration_process();
BL _tx_timer_expiration_process // Call the timer expiration handling routine
// }
__tx_timer_dont_activate:
/* Did time slice expire? */
// if (_tx_timer_expired_time_slice)
// {
MOVW r3, #:lower16:_tx_timer_expired_time_slice // Pickup addr of time-slice expired
MOVT r3, #:upper16:_tx_timer_expired_time_slice
LDR r2, [r3, #0] // Pickup the actual flag
CBZ r2, __tx_timer_not_ts_expiration // See if the flag is set
// No, skip time-slice processing
/* Time slice interrupted thread. */
// _tx_thread_time_slice();
BL _tx_thread_time_slice // Call time-slice processing
MOVW r0, #:lower16:_tx_thread_preempt_disable // Build address of preempt disable flag
MOVT r0, #:upper16:_tx_thread_preempt_disable
LDR r1, [r0] // Is the preempt disable flag set?
CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic
MOVW r0, #:lower16:_tx_thread_current_ptr // Build current thread pointer address
MOVT r0, #:upper16:_tx_thread_current_ptr
LDR r1, [r0] // Pickup the current thread pointer
MOVW r2, #:lower16:_tx_thread_execute_ptr // Build execute thread pointer address
MOVT r2, #:upper16:_tx_thread_execute_ptr
LDR r3, [r2] // Pickup the execute thread pointer
LDR r0, =0xE000ED04 // Build address of control register
LDR r2, =0x10000000 // Build value for PendSV bit
CMP r1, r3 // Are they the same?
BEQ __tx_timer_skip_time_slice // If the same, there was no time-slice performed
STR r2, [r0] // Not the same, issue the PendSV for preemption
__tx_timer_skip_time_slice:
// }
__tx_timer_not_ts_expiration:
POP {r0, r1} // Recover lr register (r0 is just there for
MOV lr, r1 // the 8-byte stack alignment
// }
__tx_timer_nothing_expired:
DSB // Complete all memory access
BX lr // Return to caller
// }
.end

View File

@@ -0,0 +1,119 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txe_thread_secure_stack_allocate Cortex-M23 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks for errors in the secure stack allocate */
/* function call. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* stack_size Size of secure stack to */
/* allocate */
/* */
/* OUTPUT */
/* */
/* TX_THREAD_ERROR Invalid thread pointer */
/* TX_CALLER_ERROR Invalid caller of function */
/* status Actual completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_secure_stack_allocate Actual stack alloc function */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txe_thread_secure_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
#if defined(TX_SINGLE_MODE_SECURE) || defined(TX_SINGLE_MODE_NON_SECURE)
return(TX_FEATURE_NOT_ENABLED);
#else
UINT status;
/* Default status to success. */
status = TX_SUCCESS;
/* Check for an invalid thread pointer. */
if (thread_ptr == TX_NULL)
{
/* Thread pointer is invalid, return appropriate error code. */
status = TX_THREAD_ERROR;
}
/* Now check for invalid thread ID. */
else if (thread_ptr -> tx_thread_id != TX_THREAD_ID)
{
/* Thread pointer is invalid, return appropriate error code. */
status = TX_THREAD_ERROR;
}
/* Check for interrupt call. */
if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
{
/* Is call from an interrupt and not initialization? */
if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
{
/* Invalid caller of this function, return appropriate error code. */
status = TX_CALLER_ERROR;
}
}
/* Determine if everything is okay. */
if (status == TX_SUCCESS)
{
/* Call actual secure stack allocate function. */
status = _tx_thread_secure_stack_allocate(thread_ptr, stack_size);
}
/* Return completion status. */
return(status);
#endif
}

View File

@@ -0,0 +1,120 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txe_thread_secure_stack_free Cortex-M23 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks for errors in the secure stack free */
/* function call. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread control block pointer */
/* */
/* OUTPUT */
/* */
/* TX_THREAD_ERROR Invalid thread pointer */
/* TX_CALLER_ERROR Invalid caller of function */
/* status Actual completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_secure_stack_free Actual stack free function */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txe_thread_secure_stack_free(TX_THREAD *thread_ptr)
{
#if defined(TX_SINGLE_MODE_SECURE) || defined(TX_SINGLE_MODE_NON_SECURE)
return(TX_FEATURE_NOT_ENABLED);
#else
UINT status;
/* Default status to success. */
status = TX_SUCCESS;
/* Check for an invalid thread pointer. */
if (thread_ptr == TX_NULL)
{
/* Thread pointer is invalid, return appropriate error code. */
status = TX_THREAD_ERROR;
}
/* Now check for invalid thread ID. */
else if (thread_ptr -> tx_thread_id != TX_THREAD_ID)
{
/* Thread pointer is invalid, return appropriate error code. */
status = TX_THREAD_ERROR;
}
/* Check for interrupt call. */
if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
{
/* Is call from an interrupt and not initialization? */
if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
{
/* Invalid caller of this function, return appropriate error code. */
status = TX_CALLER_ERROR;
}
}
/* Determine if everything is okay. */
if (status == TX_SUCCESS)
{
/* Call actual secure stack allocate function. */
status = _tx_thread_secure_stack_free(thread_ptr);
}
/* Return completion status. */
return(status);
#endif
}