diff --git a/common/inc/tx_api.h b/common/inc/tx_api.h index c79c635c..ebe84017 100644 --- a/common/inc/tx_api.h +++ b/common/inc/tx_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* tx_api.h PORTABLE C */ -/* 6.1.6 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -69,6 +69,9 @@ /* 04-02-2021 Scott Larson Modified comment(s), and */ /* update patch number, */ /* resulting in version 6.1.6 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), added */ +/* Execution Profile support, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -101,7 +104,7 @@ extern "C" { #define AZURE_RTOS_THREADX #define THREADX_MAJOR_VERSION 6 #define THREADX_MINOR_VERSION 1 -#define THREADX_PATCH_VERSION 6 +#define THREADX_PATCH_VERSION 7 /* Define the following symbol for backward compatibility */ #define EL_PRODUCT_THREADX @@ -498,6 +501,17 @@ typedef struct TX_THREAD_STRUCT is typically defined to whitespace in tx_port.h. */ TX_THREAD_EXTENSION_3 + + /* Define variables for supporting execution profile. */ + /* Note that in ThreadX 5.x, user would define TX_ENABLE_EXECUTION_CHANGE_NOTIFY and use TX_THREAD_EXTENSION_3 + to define the following two variables. + For Azure RTOS 6, user shall use TX_EXECUTION_PROFILE_ENABLE instead of TX_ENABLE_EXECUTION_CHANGE_NOTIFY, + and SHALL NOT add variables to TX_THREAD_EXTENSION_3. */ +#if (defined(TX_EXECUTION_PROFILE_ENABLE) && !defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY)) + unsigned long long tx_thread_execution_time_total; + unsigned long long tx_thread_execution_time_last_start; +#endif + /* Define suspension sequence number. This is used to ensure suspension is still valid when cleanup routine executes. */ ULONG tx_thread_suspension_sequence; diff --git a/common/src/tx_byte_pool_search.c b/common/src/tx_byte_pool_search.c index 79e20095..eccda1d1 100644 --- a/common/src/tx_byte_pool_search.c +++ b/common/src/tx_byte_pool_search.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_byte_pool_search PORTABLE C */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -76,9 +76,12 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* 05-19-2020 William E. Lamie Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 06-02-2021 Scott Larson Improve possible free bytes */ +/* calculation, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ UCHAR *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size) @@ -96,13 +99,16 @@ UINT first_free_block_found = TX_FALSE; TX_THREAD *thread_ptr; ALIGN_TYPE *free_ptr; UCHAR *work_ptr; +ULONG total_theoretical_available; /* Disable interrupts. */ TX_DISABLE /* First, determine if there are enough bytes in the pool. */ - if (memory_size >= pool_ptr -> tx_byte_pool_available) + /* Theoretical bytes available = free bytes + ((fragments-2) * overhead of each block) */ + total_theoretical_available = pool_ptr -> tx_byte_pool_available + ((pool_ptr -> tx_byte_pool_fragments - 2) * ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))); + if (memory_size >= total_theoretical_available) { /* Restore interrupts. */ @@ -146,10 +152,9 @@ UCHAR *work_ptr; /* Determine if this is the first free block. */ if (first_free_block_found == TX_FALSE) { - /* This is the first free block. */ pool_ptr->tx_byte_pool_search = current_ptr; - + /* Set the flag to indicate we have found the first free block. */ first_free_block_found = TX_TRUE; @@ -178,7 +183,7 @@ UCHAR *work_ptr; /* Clear the available bytes variable. */ available_bytes = ((ULONG) 0); - /* Not enough memory, check to see if the neighbor is + /* Not enough memory, check to see if the neighbor is free and can be merged. */ work_ptr = TX_UCHAR_POINTER_ADD(next_ptr, (sizeof(UCHAR *))); free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr); @@ -207,14 +212,12 @@ UCHAR *work_ptr; /* See if the search pointer is affected. */ if (pool_ptr -> tx_byte_pool_search == next_ptr) { - /* Yes, update the search pointer. */ pool_ptr -> tx_byte_pool_search = current_ptr; } } else { - /* Neighbor is not free so we can skip over it! */ next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr); current_ptr = *next_block_link_ptr; @@ -222,7 +225,6 @@ UCHAR *work_ptr; /* Decrement the examined block count to account for this one. */ if (examine_blocks != ((UINT) 0)) { - examine_blocks--; #ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO @@ -297,7 +299,7 @@ UCHAR *work_ptr; /* Update the current pointer to point at the newly created block. */ *this_block_link_ptr = next_ptr; - + /* Set available equal to memory size for subsequent calculation. */ available_bytes = memory_size; diff --git a/common/src/tx_thread_create.c b/common/src/tx_thread_create.c index 6af34e3c..78075842 100644 --- a/common/src/tx_thread_create.c +++ b/common/src/tx_thread_create.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_create PORTABLE C */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -84,6 +84,9 @@ /* changed stack calculations */ /* to use ALIGN_TYPE integers, */ /* resulting in version 6.1 */ +/* 06-02-2021 William E. Lamie Modified comment(s), and */ +/* supported TX_MISRA_ENABLE, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ UINT _tx_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, VOID (*entry_function)(ULONG id), ULONG entry_input, @@ -120,7 +123,11 @@ ALIGN_TYPE updated_stack_start; stack_size = ((stack_size/(sizeof(ULONG))) * (sizeof(ULONG))) - (sizeof(ULONG)); /* Ensure the starting stack address is evenly aligned. */ +#ifdef TX_MISRA_ENABLE + new_stack_start = TX_POINTER_TO_ULONG_CONVERT(stack_start); +#else new_stack_start = TX_POINTER_TO_ALIGN_TYPE_CONVERT(stack_start); +#endif /* TX_MISRA_ENABLE */ updated_stack_start = ((((ULONG) new_stack_start) + ((sizeof(ULONG)) - ((ULONG) 1)) ) & (~((sizeof(ULONG)) - ((ULONG) 1)))); /* Determine if the starting stack address is different. */ @@ -132,7 +139,11 @@ ALIGN_TYPE updated_stack_start; } /* Update the starting stack pointer. */ +#ifdef TX_MISRA_ENABLE + stack_start = TX_ULONG_TO_POINTER_CONVERT(updated_stack_start); +#else stack_start = TX_ALIGN_TYPE_TO_POINTER_CONVERT(updated_stack_start); +#endif /* TX_MISRA_ENABLE */ #endif /* Prepare the thread control block prior to placing it on the created diff --git a/common/src/tx_thread_initialize.c b/common/src/tx_thread_initialize.c index 9ced1ccd..669805c3 100644 --- a/common/src/tx_thread_initialize.c +++ b/common/src/tx_thread_initialize.c @@ -310,6 +310,9 @@ const CHAR _tx_thread_special_string[] = /* 05-19-2020 William E. Lamie Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), added */ +/* Execution Profile support, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _tx_thread_initialize(VOID) @@ -439,7 +442,7 @@ VOID _tx_thread_initialize(VOID) #ifdef TX_ENABLE_EVENT_TRACE | (((ULONG) 1) << 8) #endif -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE) | (((ULONG) 1) << 7) #endif #if TX_PORT_SPECIFIC_BUILD_OPTIONS != 0 diff --git a/common/src/tx_thread_stack_error_handler.c b/common/src/tx_thread_stack_error_handler.c index 6d62c3f3..9049b338 100644 --- a/common/src/tx_thread_stack_error_handler.c +++ b/common/src/tx_thread_stack_error_handler.c @@ -26,6 +26,7 @@ /* Include necessary system files. */ #include "tx_api.h" +#ifndef TX_PORT_THREAD_STACK_ERROR_HANDLER #if defined(TX_MISRA_ENABLE) || defined(TX_ENABLE_STACK_CHECKING) #include "tx_thread.h" @@ -35,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_stack_error_handler PORTABLE C */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -72,6 +73,11 @@ /* 10-16-2020 William E. Lamie Modified comment(s), */ /* fixed link issue, */ /* resulting in version 6.1.1 */ +/* 06-02-2021 William E. Lamie Modified comment(s), */ +/* fixed link issue, added */ +/* conditional compilation */ +/* for ARMv8-M (Cortex M23/33) */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr) @@ -111,3 +117,4 @@ TX_INTERRUPT_SAVE_AREA } #endif /* TX_MISRA_ENABLE */ +#endif /* TX_PORT_THREAD_STACK_ERROR_HANDLER */ diff --git a/common/src/tx_thread_stack_error_notify.c b/common/src/tx_thread_stack_error_notify.c index a66eab56..6142bad3 100644 --- a/common/src/tx_thread_stack_error_notify.c +++ b/common/src/tx_thread_stack_error_notify.c @@ -26,6 +26,7 @@ /* Include necessary system files. */ #include "tx_api.h" +#ifndef TX_PORT_THREAD_STACK_ERROR_NOTIFY #include "tx_thread.h" #ifdef TX_ENABLE_STACK_CHECKING #include "tx_trace.h" @@ -37,7 +38,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_stack_error_notify PORTABLE C */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -74,6 +75,10 @@ /* 05-19-2020 William E. Lamie Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), added */ +/* conditional compilation */ +/* for ARMv8-M (Cortex M23/33) */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr)) @@ -125,3 +130,4 @@ TX_INTERRUPT_SAVE_AREA #endif } +#endif /* TX_PORT_THREAD_STACK_ERROR_NOTIFY */ diff --git a/common_modules/module_manager/src/txm_module_manager_thread_create.c b/common_modules/module_manager/src/txm_module_manager_thread_create.c index 58c8211e..dfebc085 100644 --- a/common_modules/module_manager/src/txm_module_manager_thread_create.c +++ b/common_modules/module_manager/src/txm_module_manager_thread_create.c @@ -108,10 +108,8 @@ UINT core_index; #endif TX_THREAD *next_thread; TX_THREAD *previous_thread; -#ifndef TX_DISABLE_PREEMPTION_THRESHOLD TX_THREAD *saved_thread_ptr; UINT saved_threshold = ((UINT) 0); -#endif UCHAR *temp_ptr; #ifdef TX_ENABLE_STACK_CHECKING ALIGN_TYPE new_stack_start; @@ -155,7 +153,7 @@ ULONG i; /* Determine if this thread matches the thread in the list. */ if (thread_ptr == next_thread) { - + break; } @@ -177,7 +175,7 @@ ULONG i; /* Decrement the preempt disable flag. */ _tx_thread_preempt_disable--; - + /* Restore interrupts. */ TX_RESTORE @@ -260,11 +258,11 @@ ULONG i; /* Check for interrupt call. */ if (TX_THREAD_GET_SYSTEM_STATE() != 0) { - + /* Now, make sure the call is 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. */ return(TX_CALLER_ERROR); } @@ -280,7 +278,7 @@ ULONG i; #ifdef TX_ENABLE_STACK_CHECKING - /* Ensure that there are two ULONG of 0xEF patterns at the top and + /* Ensure that there are two ULONG of 0xEF patterns at the top and bottom of the thread's stack. This will be used to check for stack overflow conditions during run-time. */ stack_size = ((stack_size/(sizeof(ULONG))) * (sizeof(ULONG))) - (sizeof(ULONG)); @@ -292,7 +290,7 @@ ULONG i; /* Determine if the starting stack address is different. */ if (new_stack_start != updated_stack_start) { - + /* Yes, subtract another ULONG from the size to avoid going past the stack area. */ stack_size = stack_size - (sizeof(ULONG)); } @@ -301,7 +299,7 @@ ULONG i; stack_start = TX_ALIGN_TYPE_TO_POINTER_CONVERT(updated_stack_start); #endif - /* Allocate the thread entry information at the top of thread's stack - Leaving one + /* Allocate the thread entry information at the top of thread's stack - Leaving one ULONG worth of 0xEF pattern between the actual stack and the entry info structure. */ stack_size = stack_size - (sizeof(TXM_MODULE_THREAD_ENTRY_INFO) + (3*sizeof(ULONG))); @@ -368,7 +366,7 @@ ULONG i; /* Default thread creation such that core0 is the only allowed core for execution, i.e., bit 1 is set to exclude core1. */ thread_ptr -> tx_thread_smp_cores_excluded = (TX_THREAD_SMP_CORE_MASK & 0xFFFFFFFE); thread_ptr -> tx_thread_smp_cores_allowed = 1; - + /* Default the timers to run on core 0 as well. */ thread_ptr -> tx_thread_timer.tx_timer_internal_smp_cores_excluded = (TX_THREAD_SMP_CORE_MASK & 0xFFFFFFFE); @@ -420,11 +418,11 @@ ULONG i; TX_THREAD_CREATE_INTERNAL_EXTENSION(thread_ptr) /* Setup pointer to the thread entry information structure, which will live at the top of each - module thread's stack. This will allow the module thread entry function to avoid direct + module thread's stack. This will allow the module thread entry function to avoid direct access to the actual thread control block. */ thread_entry_info = (TXM_MODULE_THREAD_ENTRY_INFO *) (((UCHAR *) thread_ptr -> tx_thread_stack_end) + (2*sizeof(ULONG)) + 1); thread_entry_info = (TXM_MODULE_THREAD_ENTRY_INFO *) (((ALIGN_TYPE)(thread_entry_info)) & (~0x3)); - + /* Build the thread entry information structure. */ thread_entry_info -> txm_module_thread_entry_info_thread = thread_ptr; thread_entry_info -> txm_module_thread_entry_info_module = module_instance; @@ -458,7 +456,7 @@ ULONG i; with the actual stack pointer at the end of stack build. */ thread_ptr -> tx_thread_stack_ptr = (VOID *) thread_entry_info; - /* Call the target specific stack frame building routine to build the + /* Call the target specific stack frame building routine to build the thread's initial stack and to setup the actual stack pointer in the control block. */ _txm_module_manager_thread_stack_build(thread_ptr, shell_function); @@ -648,22 +646,22 @@ ULONG i; /* Yes, this create call was made from initialization. */ /* Pickup the current thread execute pointer, which corresponds to the - highest priority thread ready to execute. Interrupt lockout is - not required, since interrupts are assumed to be disabled during + highest priority thread ready to execute. Interrupt lockout is + not required, since interrupts are assumed to be disabled during initialization. */ saved_thread_ptr = _tx_thread_execute_ptr; /* Determine if there is thread ready for execution. */ if (saved_thread_ptr != TX_NULL) { - + /* Yes, a thread is ready for execution when initialization completes. */ /* Save the current preemption-threshold. */ saved_threshold = saved_thread_ptr -> tx_thread_preempt_threshold; - /* For initialization, temporarily set the preemption-threshold to the - priority level to make sure the highest-priority thread runs once + /* For initialization, temporarily set the preemption-threshold to the + priority level to make sure the highest-priority thread runs once initialization is complete. */ saved_thread_ptr -> tx_thread_preempt_threshold = saved_thread_ptr -> tx_thread_priority; } diff --git a/common_smp/inc/tx_api.h b/common_smp/inc/tx_api.h index ee343f15..f775768a 100644 --- a/common_smp/inc/tx_api.h +++ b/common_smp/inc/tx_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* tx_api.h PORTABLE SMP */ -/* 6.1.6 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -58,6 +58,9 @@ /* 04-02-2021 Scott Larson Modified comment(s), and */ /* update patch number, */ /* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Added options for multiple */ +/* block pool search & delay, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -88,6 +91,15 @@ extern "C" { #endif +/* Define default block pool search and delay values. */ +#ifndef TX_BYTE_POOL_MULTIPLE_BLOCK_SEARCH +#define TX_BYTE_POOL_MULTIPLE_BLOCK_SEARCH 20 +#endif +#ifndef TX_BTYE_POOL_DELAY_VALUE +#define TX_BYTE_POOL_DELAY_VALUE 3 +#endif + + /* Define basic constants for the ThreadX kernel. */ @@ -97,7 +109,7 @@ extern "C" { #define AZURE_RTOS_THREADX #define THREADX_MAJOR_VERSION 6 #define THREADX_MINOR_VERSION 1 -#define THREADX_PATCH_VERSION 6 +#define THREADX_PATCH_VERSION 7 /* Define the following symbol for backward compatibility */ #define EL_PRODUCT_THREADX diff --git a/common_smp/inc/tx_user_sample.h b/common_smp/inc/tx_user_sample.h index 8a36a684..282cf19a 100644 --- a/common_smp/inc/tx_user_sample.h +++ b/common_smp/inc/tx_user_sample.h @@ -49,6 +49,9 @@ /* added option to remove */ /* FileX pointer, */ /* resulting in version 6.1.5 */ +/* 06-02-2021 Scott Larson Added options for multiple */ +/* block pool search & delay, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -268,5 +271,17 @@ #define TX_TIMER_ENABLE_PERFORMANCE_INFO */ +/* Override options for byte pool searches of multiple blocks. */ + +/* +#define TX_BYTE_POOL_MULTIPLE_BLOCK_SEARCH 20 +*/ + +/* Override options for byte pool search delay to avoid thrashing. */ + +/* +#define TX_BYTE_POOL_DELAY_VALUE 3 +*/ + #endif diff --git a/common_smp/src/tx_byte_pool_search.c b/common_smp/src/tx_byte_pool_search.c index 57ef5288..bd2b959f 100644 --- a/common_smp/src/tx_byte_pool_search.c +++ b/common_smp/src/tx_byte_pool_search.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** ThreadX Component */ +/** */ +/** ThreadX Component */ /** */ /** Byte Pool */ /** */ @@ -30,53 +30,57 @@ #include "tx_byte_pool.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _tx_byte_pool_search PORTABLE SMP */ -/* 6.1 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_byte_pool_search PORTABLE SMP */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function searches a byte pool for a memory block to satisfy */ -/* the requested number of bytes. Merging of adjacent free blocks */ -/* takes place during the search and a split of the block that */ -/* satisfies the request may occur before this function returns. */ -/* */ -/* It is assumed that this function is called with interrupts enabled */ -/* and with the tx_pool_owner field set to the thread performing the */ -/* search. Also note that the search can occur during allocation and */ -/* release of a memory block. */ -/* */ -/* INPUT */ -/* */ -/* pool_ptr Pointer to pool control block */ -/* memory_size Number of bytes required */ -/* */ -/* OUTPUT */ -/* */ -/* UCHAR * Pointer to the allocated memory, */ -/* if successful. Otherwise, a */ -/* NULL is returned */ -/* */ -/* CALLS */ -/* */ -/* None */ -/* */ -/* CALLED BY */ -/* */ -/* _tx_byte_allocate Allocate bytes of memory */ -/* _tx_byte_release Release bytes of memory */ -/* */ -/* RELEASE HISTORY */ -/* */ +/* */ +/* This function searches a byte pool for a memory block to satisfy */ +/* the requested number of bytes. Merging of adjacent free blocks */ +/* takes place during the search and a split of the block that */ +/* satisfies the request may occur before this function returns. */ +/* */ +/* It is assumed that this function is called with interrupts enabled */ +/* and with the tx_pool_owner field set to the thread performing the */ +/* search. Also note that the search can occur during allocation and */ +/* release of a memory block. */ +/* */ +/* INPUT */ +/* */ +/* pool_ptr Pointer to pool control block */ +/* memory_size Number of bytes required */ +/* */ +/* OUTPUT */ +/* */ +/* UCHAR * Pointer to the allocated memory, */ +/* if successful. Otherwise, a */ +/* NULL is returned */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_byte_allocate Allocate bytes of memory */ +/* _tx_byte_release Release bytes of memory */ +/* */ +/* RELEASE HISTORY */ +/* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Improve possible free bytes */ +/* calculation, and reduced */ +/* number of search resets, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ UCHAR *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size) @@ -84,17 +88,18 @@ UCHAR *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size) TX_INTERRUPT_SAVE_AREA -UCHAR *current_ptr; -UCHAR *next_ptr; +UCHAR *current_ptr; +UCHAR *next_ptr; UCHAR **this_block_link_ptr; UCHAR **next_block_link_ptr; -ULONG available_bytes; -UINT examine_blocks; +ULONG available_bytes; +UINT examine_blocks; UINT first_free_block_found = TX_FALSE; TX_THREAD *thread_ptr; ALIGN_TYPE *free_ptr; UCHAR *work_ptr; - +volatile ULONG delay_count; +ULONG total_theoretical_available; #ifdef TX_BYTE_POOL_MULTIPLE_BLOCK_SEARCH UINT blocks_searched = ((UINT) 0); #endif @@ -104,7 +109,9 @@ UINT blocks_searched = ((UINT) 0); TX_DISABLE /* First, determine if there are enough bytes in the pool. */ - if (memory_size >= pool_ptr -> tx_byte_pool_available) + /* Theoretical bytes available = free bytes + ((fragments-2) * overhead of each block) */ + total_theoretical_available = pool_ptr -> tx_byte_pool_available + ((pool_ptr -> tx_byte_pool_fragments - 2) * ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))); + if (memory_size >= total_theoretical_available) { /* Restore interrupts. */ @@ -121,7 +128,7 @@ UINT blocks_searched = ((UINT) 0); /* Setup ownership of the byte pool. */ pool_ptr -> tx_byte_pool_owner = thread_ptr; - + /* Walk through the memory pool in search for a large enough block. */ current_ptr = pool_ptr -> tx_byte_pool_search; examine_blocks = pool_ptr -> tx_byte_pool_fragments + ((UINT) 1); @@ -148,7 +155,6 @@ UINT blocks_searched = ((UINT) 0); /* Determine if this is the first free block. */ if (first_free_block_found == TX_FALSE) { - /* This is the first free block. */ pool_ptr->tx_byte_pool_search = current_ptr; @@ -171,7 +177,6 @@ UINT blocks_searched = ((UINT) 0); has been satisfied! */ if (available_bytes >= memory_size) { - /* Get out of the search loop! */ break; } @@ -181,7 +186,7 @@ UINT blocks_searched = ((UINT) 0); /* Clear the available bytes variable. */ available_bytes = ((ULONG) 0); - /* Not enough memory, check to see if the neighbor is + /* Not enough memory, check to see if the neighbor is free and can be merged. */ work_ptr = TX_UCHAR_POINTER_ADD(next_ptr, (sizeof(UCHAR *))); free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr); @@ -210,17 +215,15 @@ UINT blocks_searched = ((UINT) 0); /* See if the search pointer is affected. */ if (pool_ptr -> tx_byte_pool_search == next_ptr) { - /* Yes, update the search pointer. */ pool_ptr -> tx_byte_pool_search = current_ptr; } } else { - /* Neighbor is not free so we can skip over it! */ next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr); - current_ptr = *next_block_link_ptr; + current_ptr = *next_block_link_ptr; /* Decrement the examined block count to account for this one. */ if (examine_blocks != ((UINT) 0)) @@ -243,9 +246,9 @@ UINT blocks_searched = ((UINT) 0); { /* Block is not free, move to next block. */ - this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr); + this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr); current_ptr = *this_block_link_ptr; - } + } /* Another block has been searched... decrement counter. */ if (examine_blocks != ((UINT) 0)) @@ -282,12 +285,23 @@ UINT blocks_searched = ((UINT) 0); /* Disable interrupts. */ TX_DISABLE -#endif - +#endif /* Determine if anything has changed in terms of pool ownership. */ if (pool_ptr -> tx_byte_pool_owner != thread_ptr) { - + /* Loop to delay changing the ownership back to avoid thrashing. */ + delay_count = 0; + do + { + /* Restore interrupts temporarily. */ + TX_RESTORE + + /* Increment the delay counter. */ + delay_count++; + + /* Disable interrupts. */ + TX_DISABLE + } while (delay_count < ((ULONG) TX_BYTE_POOL_DELAY_VALUE)); /* Pool changed ownership in the brief period interrupts were enabled. Reset the search. */ current_ptr = pool_ptr -> tx_byte_pool_search; @@ -317,7 +331,7 @@ UINT blocks_searched = ((UINT) 0); work_ptr = TX_UCHAR_POINTER_ADD(next_ptr, (sizeof(UCHAR *))); free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr); *free_ptr = TX_BYTE_BLOCK_FREE; - + /* Increase the total fragment counter. */ pool_ptr -> tx_byte_pool_fragments++; @@ -371,7 +385,7 @@ UINT blocks_searched = ((UINT) 0); current_ptr = TX_NULL; } } - + /* Return the search pointer. */ return(current_ptr); } diff --git a/ports/cortex_m0/ac5/src/tx_thread_context_restore.s b/ports/cortex_m0/ac5/src/tx_thread_context_restore.s index 8a85dc39..01695662 100644 --- a/ports/cortex_m0/ac5/src/tx_thread_context_restore.s +++ b/ports/cortex_m0/ac5/src/tx_thread_context_restore.s @@ -21,9 +21,9 @@ ;/**************************************************************************/ ; ; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_exit - ENDIF +#endif ; AREA ||.text||, CODE, READONLY PRESERVE8 @@ -74,12 +74,12 @@ EXPORT _tx_thread_context_restore _tx_thread_context_restore - IF :DEF: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. */ ; BL _tx_execution_isr_exit ; Call the ISR exit function - ENDIF +#endif ; ; /* Preemption has already been addressed - just return! */ ; diff --git a/ports/cortex_m0/ac5/src/tx_thread_context_save.s b/ports/cortex_m0/ac5/src/tx_thread_context_save.s index cda02b79..d7553de8 100644 --- a/ports/cortex_m0/ac5/src/tx_thread_context_save.s +++ b/ports/cortex_m0/ac5/src/tx_thread_context_save.s @@ -21,9 +21,9 @@ ;/**************************************************************************/ ; ; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_enter - ENDIF +#endif ; ; AREA ||.text||, CODE, READONLY @@ -73,7 +73,7 @@ ;{ EXPORT _tx_thread_context_save _tx_thread_context_save - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) ; ; /* Call the ISR enter function to indicate an ISR is executing. */ ; @@ -81,7 +81,7 @@ _tx_thread_context_save BL _tx_execution_isr_enter ; Call the ISR enter function POP {r0, r1} ; Recover ISR lr MOV lr, r1 - ENDIF +#endif ; ; /* Return to interrupt processing. */ ; diff --git a/ports/cortex_m0/ac5/src/tx_thread_schedule.s b/ports/cortex_m0/ac5/src/tx_thread_schedule.s index 93f37635..5a8de971 100644 --- a/ports/cortex_m0/ac5/src/tx_thread_schedule.s +++ b/ports/cortex_m0/ac5/src/tx_thread_schedule.s @@ -26,10 +26,10 @@ IMPORT _tx_timer_time_slice IMPORT _tx_thread_system_stack_ptr IMPORT _tx_thread_preempt_disable - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_thread_enter IMPORT _tx_execution_thread_exit - ENDIF +#endif IF :DEF:TX_LOW_POWER IMPORT tx_low_power_enter IMPORT tx_low_power_exit @@ -127,7 +127,7 @@ __tx_PendSVHandler ; __tx_ts_handler - IF :DEF: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. */ ; @@ -137,7 +137,7 @@ __tx_ts_handler POP {r0, r1} ; Recover LR MOV lr, r1 ; CPSIE i ; Enable interrupts - ENDIF +#endif LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address LDR r2, =_tx_thread_execute_ptr ; Build execute thread pointer address MOVS r3, #0 ; Build NULL value @@ -210,14 +210,14 @@ __tx_ts_restore ; STR r5, [r4] ; Setup global time-slice - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) ; ; /* 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 +#endif ; ; /* Restore the thread context and PSP. */ ; diff --git a/ports/cortex_m0/ac6/src/tx_thread_context_restore.S b/ports/cortex_m0/ac6/src/tx_thread_context_restore.S index 38959c32..0b039e55 100644 --- a/ports/cortex_m0/ac6/src/tx_thread_context_restore.S +++ b/ports/cortex_m0/ac6/src/tx_thread_context_restore.S @@ -21,6 +21,9 @@ @/**************************************************************************/ @ @ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif .global _tx_thread_system_state .global _tx_thread_current_ptr .global _tx_thread_system_stack_ptr @@ -81,6 +84,12 @@ .thumb_func _tx_thread_context_restore: @ -@ /* Not needed for this port - just return! */ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr @} diff --git a/ports/cortex_m0/ac6/src/tx_thread_context_save.S b/ports/cortex_m0/ac6/src/tx_thread_context_save.S index a83ba2a0..e2d73d48 100644 --- a/ports/cortex_m0/ac6/src/tx_thread_context_save.S +++ b/ports/cortex_m0/ac6/src/tx_thread_context_save.S @@ -21,6 +21,9 @@ @/**************************************************************************/ @ @ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_enter +#endif .global _tx_thread_system_state .global _tx_thread_current_ptr @ @@ -75,6 +78,12 @@ .thumb_func _tx_thread_context_save: @ -@ /* Not needed for this port - just return! */ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + BX lr @} diff --git a/ports/cortex_m0/ac6/src/tx_thread_schedule.S b/ports/cortex_m0/ac6/src/tx_thread_schedule.S index f1ee3a94..a9369dd3 100644 --- a/ports/cortex_m0/ac6/src/tx_thread_schedule.S +++ b/ports/cortex_m0/ac6/src/tx_thread_schedule.S @@ -25,6 +25,10 @@ .global _tx_thread_execute_ptr .global _tx_timer_time_slice .global _tx_thread_system_stack_ptr +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit +#endif #ifdef TX_LOW_POWER .global tx_low_power_enter .global tx_low_power_exit @@ -131,7 +135,7 @@ __tx_SVCallHandler: .thumb_func __tx_ts_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. */ @ @@ -214,7 +218,7 @@ __tx_ts_restore: @ STR r5, [r4] @ Setup global time-slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) @ @ /* Call the thread entry function to indicate the thread is executing. */ @ diff --git a/ports/cortex_m0/gnu/src/tx_thread_context_restore.S b/ports/cortex_m0/gnu/src/tx_thread_context_restore.S index fc453b61..258786b8 100644 --- a/ports/cortex_m0/gnu/src/tx_thread_context_restore.S +++ b/ports/cortex_m0/gnu/src/tx_thread_context_restore.S @@ -29,6 +29,9 @@ .global _tx_thread_schedule .global _tx_thread_preempt_disable .global _tx_execution_isr_exit +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif @ @ .text 32 @@ -85,6 +88,11 @@ .thumb_func _tx_thread_context_restore: @ -@ /* Not needed for this port - just return! */ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif BX lr @} diff --git a/ports/cortex_m0/gnu/src/tx_thread_context_save.S b/ports/cortex_m0/gnu/src/tx_thread_context_save.S index 710f5e26..dd5f2c68 100644 --- a/ports/cortex_m0/gnu/src/tx_thread_context_save.S +++ b/ports/cortex_m0/gnu/src/tx_thread_context_save.S @@ -79,6 +79,14 @@ .thumb_func _tx_thread_context_save: @ -@ /* Not needed for this port - just return! */ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr @} diff --git a/ports/cortex_m0/gnu/src/tx_thread_schedule.S b/ports/cortex_m0/gnu/src/tx_thread_schedule.S index e110259b..5134f6e1 100644 --- a/ports/cortex_m0/gnu/src/tx_thread_schedule.S +++ b/ports/cortex_m0/gnu/src/tx_thread_schedule.S @@ -135,7 +135,7 @@ __tx_SVCallHandler: .thumb_func __tx_ts_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. */ @ @@ -218,7 +218,7 @@ __tx_ts_restore: @ STR r5, [r4] @ Setup global time-slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) @ @ /* Call the thread entry function to indicate the thread is executing. */ @ diff --git a/ports/cortex_m0/iar/inc/tx_port.h b/ports/cortex_m0/iar/inc/tx_port.h index 2c671a74..eb450bff 100644 --- a/ports/cortex_m0/iar/inc/tx_port.h +++ b/ports/cortex_m0/iar/inc/tx_port.h @@ -190,12 +190,7 @@ ULONG _tx_misra_time_stamp_get(VOID); #else #define TX_THREAD_EXTENSION_2 #endif -#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 -#else -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; -#endif /* Define the port extensions of the remaining ThreadX objects. */ diff --git a/ports/cortex_m0/iar/src/tx_thread_context_restore.s b/ports/cortex_m0/iar/src/tx_thread_context_restore.s index 0facd555..ea92ab67 100644 --- a/ports/cortex_m0/iar/src/tx_thread_context_restore.s +++ b/ports/cortex_m0/iar/src/tx_thread_context_restore.s @@ -80,7 +80,7 @@ PUBLIC _tx_thread_context_restore _tx_thread_context_restore: -#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. */ ; diff --git a/ports/cortex_m0/iar/src/tx_thread_context_save.s b/ports/cortex_m0/iar/src/tx_thread_context_save.s index 6d9e8ec6..bac122c4 100644 --- a/ports/cortex_m0/iar/src/tx_thread_context_save.s +++ b/ports/cortex_m0/iar/src/tx_thread_context_save.s @@ -73,7 +73,7 @@ ;{ PUBLIC _tx_thread_context_save _tx_thread_context_save: -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) ; ; /* Call the ISR enter function to indicate an ISR is starting. */ ; diff --git a/ports/cortex_m0/iar/src/tx_thread_schedule.s b/ports/cortex_m0/iar/src/tx_thread_schedule.s index e4bac172..0e79efd8 100644 --- a/ports/cortex_m0/iar/src/tx_thread_schedule.s +++ b/ports/cortex_m0/iar/src/tx_thread_schedule.s @@ -124,7 +124,7 @@ __tx_PendSVHandler: ; __tx_ts_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. */ ; @@ -208,7 +208,7 @@ __tx_ts_restore: ; STR r5, [r4] ; Setup global time-slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) ; ; /* Call the thread entry function to indicate the thread is executing. */ ; diff --git a/ports/cortex_m0/keil/src/tx_thread_context_restore.s b/ports/cortex_m0/keil/src/tx_thread_context_restore.s index 8a85dc39..0938bde5 100644 --- a/ports/cortex_m0/keil/src/tx_thread_context_restore.s +++ b/ports/cortex_m0/keil/src/tx_thread_context_restore.s @@ -21,9 +21,10 @@ ;/**************************************************************************/ ; ; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_exit - ENDIF +#endif + ; AREA ||.text||, CODE, READONLY PRESERVE8 @@ -74,12 +75,12 @@ EXPORT _tx_thread_context_restore _tx_thread_context_restore - IF :DEF: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. */ ; BL _tx_execution_isr_exit ; Call the ISR exit function - ENDIF +#endif ; ; /* Preemption has already been addressed - just return! */ ; diff --git a/ports/cortex_m0/keil/src/tx_thread_context_save.s b/ports/cortex_m0/keil/src/tx_thread_context_save.s index cda02b79..eea08c6b 100644 --- a/ports/cortex_m0/keil/src/tx_thread_context_save.s +++ b/ports/cortex_m0/keil/src/tx_thread_context_save.s @@ -21,9 +21,9 @@ ;/**************************************************************************/ ; ; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_enter - ENDIF +#endif ; ; AREA ||.text||, CODE, READONLY @@ -73,7 +73,7 @@ ;{ EXPORT _tx_thread_context_save _tx_thread_context_save - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) ; ; /* Call the ISR enter function to indicate an ISR is executing. */ ; @@ -81,7 +81,7 @@ _tx_thread_context_save BL _tx_execution_isr_enter ; Call the ISR enter function POP {r0, r1} ; Recover ISR lr MOV lr, r1 - ENDIF +#endif ; ; /* Return to interrupt processing. */ ; diff --git a/ports/cortex_m0/keil/src/tx_thread_schedule.s b/ports/cortex_m0/keil/src/tx_thread_schedule.s index b09972b1..c9f50c37 100644 --- a/ports/cortex_m0/keil/src/tx_thread_schedule.s +++ b/ports/cortex_m0/keil/src/tx_thread_schedule.s @@ -26,10 +26,10 @@ IMPORT _tx_timer_time_slice IMPORT _tx_thread_system_stack_ptr IMPORT _tx_thread_preempt_disable - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_thread_enter IMPORT _tx_execution_thread_exit - ENDIF +#endif IF :DEF:TX_LOW_POWER IMPORT tx_low_power_enter IMPORT tx_low_power_exit @@ -127,7 +127,7 @@ __tx_PendSVHandler ; __tx_ts_handler - IF :DEF: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. */ ; @@ -137,7 +137,7 @@ __tx_ts_handler POP {r0, r1} ; Recover LR MOV lr, r1 ; CPSIE i ; Enable interrupts - ENDIF +#endif LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address LDR r2, =_tx_thread_execute_ptr ; Build execute thread pointer address MOVS r3, #0 ; Build NULL value @@ -211,14 +211,14 @@ __tx_ts_restore ; STR r5, [r4] ; Setup global time-slice - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) ; ; /* 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 +#endif ; ; /* Restore the thread context and PSP. */ ; diff --git a/ports/cortex_m23/ac5/example_build/ARMCM23_TZ_config.txt b/ports/cortex_m23/ac5/example_build/ARMCM23_TZ_config.txt deleted file mode 100644 index 0d31ad76..00000000 --- a/ports/cortex_m23/ac5/example_build/ARMCM23_TZ_config.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Parameters: -# instance.parameter=value #(type, mode) default = 'def value' : description : [min..max] -#---------------------------------------------------------------------------------------------- -cpu0.semihosting-enable=0 # (bool , init-time) default = '1' : Enable semihosting SVC traps. Applications that do not use semihosting must set this parameter to false. -idau.NUM_IDAU_REGION=0x0 # (int , init-time) default = '0xA' : -cpu0.SECEXT=1 # (bool , init-time) default = '1' : Whether the ARMv8-M Security Extensions are included -fvp_mps2.platform_type=0x0 # (int , init-time) default = '0x0' : 0:MPS2 ; 1:IoT Kit ; 2:Castor : [0x0..0x2] -fvp_mps2.DISABLE_GATING=1 # (bool , init-time) default = '0' : Disable Memory gating logic -#---------------------------------------------------------------------------------------------- diff --git a/ports/cortex_m23/ac5/example_build/AzureRTOS.uvmpw b/ports/cortex_m23/ac5/example_build/AzureRTOS.uvmpw deleted file mode 100644 index 860a1c52..00000000 --- a/ports/cortex_m23/ac5/example_build/AzureRTOS.uvmpw +++ /dev/null @@ -1,26 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - WorkSpace - - - .\demo_secure_zone\demo_secure_zone.uvprojx - 1 - - - - .\demo_threadx_non-secure_zone\demo_threadx_non-secure_zone.uvprojx - 1 - - - - .\ThreadX_Library.uvprojx - 1 - 1 - - -
diff --git a/ports/cortex_m23/ac5/example_build/Debug.ini b/ports/cortex_m23/ac5/example_build/Debug.ini deleted file mode 100644 index 2a9dfba0..00000000 --- a/ports/cortex_m23/ac5/example_build/Debug.ini +++ /dev/null @@ -1,4 +0,0 @@ -LOAD "..\\demo_threadx_non-secure_zone\\Objects\\demo_threadx_non-secure_zone.axf" incremental -LOAD "..\\demo_secure_zone\\Objects\\demo_secure_zone.axf" incremental -RESET -g, \\demo_secure_zone\main_s\main \ No newline at end of file diff --git a/ports/cortex_m23/ac5/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h b/ports/cortex_m23/ac5/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h deleted file mode 100644 index 476361d7..00000000 --- a/ports/cortex_m23/ac5/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'ThreadX_Library' - * Target: 'ThreadX_Library_Project' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM23_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m23/ac5/example_build/ThreadX_Library.uvoptx b/ports/cortex_m23/ac5/example_build/ThreadX_Library.uvoptx deleted file mode 100644 index 0757f5f4..00000000 --- a/ports/cortex_m23/ac5/example_build/ThreadX_Library.uvoptx +++ /dev/null @@ -1,2564 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - ThreadX_Library_Project - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 7 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 13 - - - - - - - - - - - BIN\UL2V8M.DLL - - - - 0 - UL2V8M - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - - - - - 0 - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - - - Source Group - 0 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_allocate.c - tx_block_allocate.c - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_cleanup.c - tx_block_pool_cleanup.c - 0 - 0 - - - 1 - 3 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_create.c - tx_block_pool_create.c - 0 - 0 - - - 1 - 4 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_delete.c - tx_block_pool_delete.c - 0 - 0 - - - 1 - 5 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_info_get.c - tx_block_pool_info_get.c - 0 - 0 - - - 1 - 6 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_initialize.c - tx_block_pool_initialize.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_performance_info_get.c - tx_block_pool_performance_info_get.c - 0 - 0 - - - 1 - 8 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c - tx_block_pool_performance_system_info_get.c - 0 - 0 - - - 1 - 9 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_prioritize.c - tx_block_pool_prioritize.c - 0 - 0 - - - 1 - 10 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_release.c - tx_block_release.c - 0 - 0 - - - 1 - 11 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_allocate.c - tx_byte_allocate.c - 0 - 0 - - - 1 - 12 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_cleanup.c - tx_byte_pool_cleanup.c - 0 - 0 - - - 1 - 13 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_create.c - tx_byte_pool_create.c - 0 - 0 - - - 1 - 14 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_delete.c - tx_byte_pool_delete.c - 0 - 0 - - - 1 - 15 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_info_get.c - tx_byte_pool_info_get.c - 0 - 0 - - - 1 - 16 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_initialize.c - tx_byte_pool_initialize.c - 0 - 0 - - - 1 - 17 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_performance_info_get.c - tx_byte_pool_performance_info_get.c - 0 - 0 - - - 1 - 18 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c - tx_byte_pool_performance_system_info_get.c - 0 - 0 - - - 1 - 19 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_prioritize.c - tx_byte_pool_prioritize.c - 0 - 0 - - - 1 - 20 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_search.c - tx_byte_pool_search.c - 0 - 0 - - - 1 - 21 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_release.c - tx_byte_release.c - 0 - 0 - - - 1 - 22 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_cleanup.c - tx_event_flags_cleanup.c - 0 - 0 - - - 1 - 23 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_create.c - tx_event_flags_create.c - 0 - 0 - - - 1 - 24 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_delete.c - tx_event_flags_delete.c - 0 - 0 - - - 1 - 25 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_get.c - tx_event_flags_get.c - 0 - 0 - - - 1 - 26 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_info_get.c - tx_event_flags_info_get.c - 0 - 0 - - - 1 - 27 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_initialize.c - tx_event_flags_initialize.c - 0 - 0 - - - 1 - 28 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_performance_info_get.c - tx_event_flags_performance_info_get.c - 0 - 0 - - - 1 - 29 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c - tx_event_flags_performance_system_info_get.c - 0 - 0 - - - 1 - 30 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_set.c - tx_event_flags_set.c - 0 - 0 - - - 1 - 31 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_set_notify.c - tx_event_flags_set_notify.c - 0 - 0 - - - 1 - 32 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_initialize_high_level.c - tx_initialize_high_level.c - 0 - 0 - - - 1 - 33 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_initialize_kernel_enter.c - tx_initialize_kernel_enter.c - 0 - 0 - - - 1 - 34 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_initialize_kernel_setup.c - tx_initialize_kernel_setup.c - 0 - 0 - - - 1 - 35 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_cleanup.c - tx_mutex_cleanup.c - 0 - 0 - - - 1 - 36 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_create.c - tx_mutex_create.c - 0 - 0 - - - 1 - 37 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_delete.c - tx_mutex_delete.c - 0 - 0 - - - 1 - 38 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_get.c - tx_mutex_get.c - 0 - 0 - - - 1 - 39 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_info_get.c - tx_mutex_info_get.c - 0 - 0 - - - 1 - 40 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_initialize.c - tx_mutex_initialize.c - 0 - 0 - - - 1 - 41 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_performance_info_get.c - tx_mutex_performance_info_get.c - 0 - 0 - - - 1 - 42 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_performance_system_info_get.c - tx_mutex_performance_system_info_get.c - 0 - 0 - - - 1 - 43 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_prioritize.c - tx_mutex_prioritize.c - 0 - 0 - - - 1 - 44 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_priority_change.c - tx_mutex_priority_change.c - 0 - 0 - - - 1 - 45 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_put.c - tx_mutex_put.c - 0 - 0 - - - 1 - 46 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_cleanup.c - tx_queue_cleanup.c - 0 - 0 - - - 1 - 47 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_create.c - tx_queue_create.c - 0 - 0 - - - 1 - 48 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_delete.c - tx_queue_delete.c - 0 - 0 - - - 1 - 49 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_flush.c - tx_queue_flush.c - 0 - 0 - - - 1 - 50 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_front_send.c - tx_queue_front_send.c - 0 - 0 - - - 1 - 51 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_info_get.c - tx_queue_info_get.c - 0 - 0 - - - 1 - 52 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_initialize.c - tx_queue_initialize.c - 0 - 0 - - - 1 - 53 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_performance_info_get.c - tx_queue_performance_info_get.c - 0 - 0 - - - 1 - 54 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_performance_system_info_get.c - tx_queue_performance_system_info_get.c - 0 - 0 - - - 1 - 55 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_prioritize.c - tx_queue_prioritize.c - 0 - 0 - - - 1 - 56 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_receive.c - tx_queue_receive.c - 0 - 0 - - - 1 - 57 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_send.c - tx_queue_send.c - 0 - 0 - - - 1 - 58 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_send_notify.c - tx_queue_send_notify.c - 0 - 0 - - - 1 - 59 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_ceiling_put.c - tx_semaphore_ceiling_put.c - 0 - 0 - - - 1 - 60 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_cleanup.c - tx_semaphore_cleanup.c - 0 - 0 - - - 1 - 61 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_create.c - tx_semaphore_create.c - 0 - 0 - - - 1 - 62 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_delete.c - tx_semaphore_delete.c - 0 - 0 - - - 1 - 63 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_get.c - tx_semaphore_get.c - 0 - 0 - - - 1 - 64 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_info_get.c - tx_semaphore_info_get.c - 0 - 0 - - - 1 - 65 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_initialize.c - tx_semaphore_initialize.c - 0 - 0 - - - 1 - 66 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_performance_info_get.c - tx_semaphore_performance_info_get.c - 0 - 0 - - - 1 - 67 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c - tx_semaphore_performance_system_info_get.c - 0 - 0 - - - 1 - 68 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_prioritize.c - tx_semaphore_prioritize.c - 0 - 0 - - - 1 - 69 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_put.c - tx_semaphore_put.c - 0 - 0 - - - 1 - 70 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_put_notify.c - tx_semaphore_put_notify.c - 0 - 0 - - - 1 - 71 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_create.c - tx_thread_create.c - 0 - 0 - - - 1 - 72 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_delete.c - tx_thread_delete.c - 0 - 0 - - - 1 - 73 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_entry_exit_notify.c - tx_thread_entry_exit_notify.c - 0 - 0 - - - 1 - 74 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_identify.c - tx_thread_identify.c - 0 - 0 - - - 1 - 75 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_info_get.c - tx_thread_info_get.c - 0 - 0 - - - 1 - 76 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_initialize.c - tx_thread_initialize.c - 0 - 0 - - - 1 - 77 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_performance_info_get.c - tx_thread_performance_info_get.c - 0 - 0 - - - 1 - 78 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_performance_system_info_get.c - tx_thread_performance_system_info_get.c - 0 - 0 - - - 1 - 79 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_preemption_change.c - tx_thread_preemption_change.c - 0 - 0 - - - 1 - 80 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_priority_change.c - tx_thread_priority_change.c - 0 - 0 - - - 1 - 81 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_relinquish.c - tx_thread_relinquish.c - 0 - 0 - - - 1 - 82 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_reset.c - tx_thread_reset.c - 0 - 0 - - - 1 - 83 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_resume.c - tx_thread_resume.c - 0 - 0 - - - 1 - 84 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_shell_entry.c - tx_thread_shell_entry.c - 0 - 0 - - - 1 - 85 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_sleep.c - tx_thread_sleep.c - 0 - 0 - - - 1 - 86 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_stack_analyze.c - tx_thread_stack_analyze.c - 0 - 0 - - - 1 - 87 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_suspend.c - tx_thread_suspend.c - 0 - 0 - - - 1 - 88 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_system_preempt_check.c - tx_thread_system_preempt_check.c - 0 - 0 - - - 1 - 89 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_system_resume.c - tx_thread_system_resume.c - 0 - 0 - - - 1 - 90 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_system_suspend.c - tx_thread_system_suspend.c - 0 - 0 - - - 1 - 91 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_terminate.c - tx_thread_terminate.c - 0 - 0 - - - 1 - 92 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_time_slice.c - tx_thread_time_slice.c - 0 - 0 - - - 1 - 93 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_time_slice_change.c - tx_thread_time_slice_change.c - 0 - 0 - - - 1 - 94 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_timeout.c - tx_thread_timeout.c - 0 - 0 - - - 1 - 95 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_wait_abort.c - tx_thread_wait_abort.c - 0 - 0 - - - 1 - 96 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_time_get.c - tx_time_get.c - 0 - 0 - - - 1 - 97 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_time_set.c - tx_time_set.c - 0 - 0 - - - 1 - 98 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_activate.c - tx_timer_activate.c - 0 - 0 - - - 1 - 99 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_change.c - tx_timer_change.c - 0 - 0 - - - 1 - 100 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_create.c - tx_timer_create.c - 0 - 0 - - - 1 - 101 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_deactivate.c - tx_timer_deactivate.c - 0 - 0 - - - 1 - 102 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_delete.c - tx_timer_delete.c - 0 - 0 - - - 1 - 103 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_expiration_process.c - tx_timer_expiration_process.c - 0 - 0 - - - 1 - 104 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_info_get.c - tx_timer_info_get.c - 0 - 0 - - - 1 - 105 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_initialize.c - tx_timer_initialize.c - 0 - 0 - - - 1 - 106 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_performance_info_get.c - tx_timer_performance_info_get.c - 0 - 0 - - - 1 - 107 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_performance_system_info_get.c - tx_timer_performance_system_info_get.c - 0 - 0 - - - 1 - 108 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_system_activate.c - tx_timer_system_activate.c - 0 - 0 - - - 1 - 109 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_system_deactivate.c - tx_timer_system_deactivate.c - 0 - 0 - - - 1 - 110 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_thread_entry.c - tx_timer_thread_entry.c - 0 - 0 - - - 1 - 111 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_disable.c - tx_trace_disable.c - 0 - 0 - - - 1 - 112 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_enable.c - tx_trace_enable.c - 0 - 0 - - - 1 - 113 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_initialize.c - tx_trace_initialize.c - 0 - 0 - - - 1 - 114 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_interrupt_control.c - tx_trace_interrupt_control.c - 0 - 0 - - - 1 - 115 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_isr_enter_insert.c - tx_trace_isr_enter_insert.c - 0 - 0 - - - 1 - 116 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_isr_exit_insert.c - tx_trace_isr_exit_insert.c - 0 - 0 - - - 1 - 117 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_object_register.c - tx_trace_object_register.c - 0 - 0 - - - 1 - 118 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_object_unregister.c - tx_trace_object_unregister.c - 0 - 0 - - - 1 - 119 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_user_event_insert.c - tx_trace_user_event_insert.c - 0 - 0 - - - 1 - 120 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_allocate.c - txe_block_allocate.c - 0 - 0 - - - 1 - 121 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_create.c - txe_block_pool_create.c - 0 - 0 - - - 1 - 122 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_delete.c - txe_block_pool_delete.c - 0 - 0 - - - 1 - 123 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_info_get.c - txe_block_pool_info_get.c - 0 - 0 - - - 1 - 124 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_prioritize.c - txe_block_pool_prioritize.c - 0 - 0 - - - 1 - 125 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_release.c - txe_block_release.c - 0 - 0 - - - 1 - 126 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_allocate.c - txe_byte_allocate.c - 0 - 0 - - - 1 - 127 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_create.c - txe_byte_pool_create.c - 0 - 0 - - - 1 - 128 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_delete.c - txe_byte_pool_delete.c - 0 - 0 - - - 1 - 129 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_info_get.c - txe_byte_pool_info_get.c - 0 - 0 - - - 1 - 130 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_prioritize.c - txe_byte_pool_prioritize.c - 0 - 0 - - - 1 - 131 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_release.c - txe_byte_release.c - 0 - 0 - - - 1 - 132 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_create.c - txe_event_flags_create.c - 0 - 0 - - - 1 - 133 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_delete.c - txe_event_flags_delete.c - 0 - 0 - - - 1 - 134 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_get.c - txe_event_flags_get.c - 0 - 0 - - - 1 - 135 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_info_get.c - txe_event_flags_info_get.c - 0 - 0 - - - 1 - 136 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_set.c - txe_event_flags_set.c - 0 - 0 - - - 1 - 137 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_set_notify.c - txe_event_flags_set_notify.c - 0 - 0 - - - 1 - 138 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_create.c - txe_mutex_create.c - 0 - 0 - - - 1 - 139 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_delete.c - txe_mutex_delete.c - 0 - 0 - - - 1 - 140 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_get.c - txe_mutex_get.c - 0 - 0 - - - 1 - 141 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_info_get.c - txe_mutex_info_get.c - 0 - 0 - - - 1 - 142 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_prioritize.c - txe_mutex_prioritize.c - 0 - 0 - - - 1 - 143 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_put.c - txe_mutex_put.c - 0 - 0 - - - 1 - 144 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_create.c - txe_queue_create.c - 0 - 0 - - - 1 - 145 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_delete.c - txe_queue_delete.c - 0 - 0 - - - 1 - 146 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_flush.c - txe_queue_flush.c - 0 - 0 - - - 1 - 147 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_front_send.c - txe_queue_front_send.c - 0 - 0 - - - 1 - 148 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_info_get.c - txe_queue_info_get.c - 0 - 0 - - - 1 - 149 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_prioritize.c - txe_queue_prioritize.c - 0 - 0 - - - 1 - 150 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_receive.c - txe_queue_receive.c - 0 - 0 - - - 1 - 151 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_send.c - txe_queue_send.c - 0 - 0 - - - 1 - 152 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_send_notify.c - txe_queue_send_notify.c - 0 - 0 - - - 1 - 153 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_ceiling_put.c - txe_semaphore_ceiling_put.c - 0 - 0 - - - 1 - 154 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_create.c - txe_semaphore_create.c - 0 - 0 - - - 1 - 155 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_delete.c - txe_semaphore_delete.c - 0 - 0 - - - 1 - 156 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_get.c - txe_semaphore_get.c - 0 - 0 - - - 1 - 157 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_info_get.c - txe_semaphore_info_get.c - 0 - 0 - - - 1 - 158 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_prioritize.c - txe_semaphore_prioritize.c - 0 - 0 - - - 1 - 159 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_put.c - txe_semaphore_put.c - 0 - 0 - - - 1 - 160 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_put_notify.c - txe_semaphore_put_notify.c - 0 - 0 - - - 1 - 161 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_create.c - txe_thread_create.c - 0 - 0 - - - 1 - 162 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_delete.c - txe_thread_delete.c - 0 - 0 - - - 1 - 163 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_entry_exit_notify.c - txe_thread_entry_exit_notify.c - 0 - 0 - - - 1 - 164 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_info_get.c - txe_thread_info_get.c - 0 - 0 - - - 1 - 165 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_preemption_change.c - txe_thread_preemption_change.c - 0 - 0 - - - 1 - 166 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_priority_change.c - txe_thread_priority_change.c - 0 - 0 - - - 1 - 167 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_relinquish.c - txe_thread_relinquish.c - 0 - 0 - - - 1 - 168 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_reset.c - txe_thread_reset.c - 0 - 0 - - - 1 - 169 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_resume.c - txe_thread_resume.c - 0 - 0 - - - 1 - 170 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_suspend.c - txe_thread_suspend.c - 0 - 0 - - - 1 - 171 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_terminate.c - txe_thread_terminate.c - 0 - 0 - - - 1 - 172 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_time_slice_change.c - txe_thread_time_slice_change.c - 0 - 0 - - - 1 - 173 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_wait_abort.c - txe_thread_wait_abort.c - 0 - 0 - - - 1 - 174 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_activate.c - txe_timer_activate.c - 0 - 0 - - - 1 - 175 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_change.c - txe_timer_change.c - 0 - 0 - - - 1 - 176 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_create.c - txe_timer_create.c - 0 - 0 - - - 1 - 177 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_deactivate.c - txe_timer_deactivate.c - 0 - 0 - - - 1 - 178 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_delete.c - txe_timer_delete.c - 0 - 0 - - - 1 - 179 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_info_get.c - txe_timer_info_get.c - 0 - 0 - - - 1 - 180 - 2 - 0 - 0 - 0 - ..\src\tx_timer_interrupt.s - tx_timer_interrupt.s - 0 - 0 - - - 1 - 181 - 2 - 0 - 0 - 0 - ..\src\tx_thread_context_restore.s - tx_thread_context_restore.s - 0 - 0 - - - 1 - 182 - 2 - 0 - 0 - 0 - ..\src\tx_thread_context_save.s - tx_thread_context_save.s - 0 - 0 - - - 1 - 183 - 2 - 0 - 0 - 0 - ..\src\tx_thread_interrupt_control.s - tx_thread_interrupt_control.s - 0 - 0 - - - 1 - 184 - 2 - 0 - 0 - 0 - ..\src\tx_thread_schedule.s - tx_thread_schedule.s - 0 - 0 - - - 1 - 185 - 2 - 0 - 0 - 0 - ..\src\tx_thread_stack_build.s - tx_thread_stack_build.s - 0 - 0 - - - 1 - 186 - 2 - 0 - 0 - 0 - ..\src\tx_thread_system_return.s - tx_thread_system_return.s - 0 - 0 - - - 1 - 187 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_buffer_full_notify.c - tx_trace_buffer_full_notify.c - 0 - 0 - - - 1 - 188 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_event_filter.c - tx_trace_event_filter.c - 0 - 0 - - - 1 - 189 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_event_unfilter.c - tx_trace_event_unfilter.c - 0 - 0 - - - 1 - 190 - 2 - 0 - 0 - 0 - ..\src\tx_thread_interrupt_disable.s - tx_thread_interrupt_disable.s - 0 - 0 - - - 1 - 191 - 2 - 0 - 0 - 0 - ..\src\tx_thread_interrupt_restore.s - tx_thread_interrupt_restore.s - 0 - 0 - - - 1 - 192 - 1 - 0 - 0 - 0 - ..\src\txe_thread_secure_stack_allocate.c - txe_thread_secure_stack_allocate.c - 0 - 0 - - - 1 - 193 - 1 - 0 - 0 - 0 - ..\src\txe_thread_secure_stack_free.c - txe_thread_secure_stack_free.c - 0 - 0 - - - 1 - 194 - 2 - 0 - 0 - 0 - ..\src\tx_thread_secure_stack_allocate.s - tx_thread_secure_stack_allocate.s - 0 - 0 - - - 1 - 195 - 2 - 0 - 0 - 0 - ..\src\tx_thread_secure_stack_free.s - tx_thread_secure_stack_free.s - 0 - 0 - - - 1 - 196 - 2 - 0 - 0 - 0 - .\tx_initialize_low_level.s - tx_initialize_low_level.s - 0 - 0 - - - 1 - 197 - 1 - 0 - 0 - 0 - ..\src\tx_thread_stack_error_handler.c - tx_thread_stack_error_handler.c - 0 - 0 - - - 1 - 198 - 1 - 0 - 0 - 0 - ..\src\tx_thread_stack_error_notify.c - tx_thread_stack_error_notify.c - 0 - 0 - - - - - ::CMSIS - 0 - 0 - 0 - 1 - - -
diff --git a/ports/cortex_m23/ac5/example_build/ThreadX_Library.uvprojx b/ports/cortex_m23/ac5/example_build/ThreadX_Library.uvprojx deleted file mode 100644 index d293390b..00000000 --- a/ports/cortex_m23/ac5/example_build/ThreadX_Library.uvprojx +++ /dev/null @@ -1,1423 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - ThreadX_Library_Project - 0x4 - ARM-ADS - 6140000::V6.14::ARMCLANG - 1 - - - ARMCM23_TZ - ARM - ARM.CMSIS.5.5.1 - http://www.keil.com/pack/ - IRAM(0x20000000,0x00020000) IRAM2(0x20200000,0x00020000) IROM(0x00000000,0x00200000) IROM2(0x00200000,0x00200000) CPUTYPE("Cortex-M23") TZ CLOCK(12000000) ESEL ELITTLE - - - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - 0 - $$Device:ARMCM23_TZ$Device\ARM\ARMCM23\Include\ARMCM23_TZ.h - - - - - - - - - - - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\ - ThreadX_Library - 0 - 1 - 0 - 1 - 1 - .\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 0 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - - - - - SARMV8M.DLL - -MPU - TCM.DLL - -pCM23 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4100 - - 1 - BIN\UL2V8M.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M23" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 8 - 0 - 1 - 0 - 0 - 4 - 4 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 1 - 0x0 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x200000 - - - 1 - 0x200000 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 0 - 0x20200000 - 0x20000 - - - - - - 0 - 7 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 0 - 0 - 0 - 0 - 3 - 3 - 1 - 1 - 0 - 0 - 0 - - - - - ..\..\..\..\common\inc, ..\inc - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 4 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - - - - - - - - - - - - Source Group - - - tx_block_allocate.c - 1 - ..\..\..\..\common\src\tx_block_allocate.c - - - tx_block_pool_cleanup.c - 1 - ..\..\..\..\common\src\tx_block_pool_cleanup.c - - - tx_block_pool_create.c - 1 - ..\..\..\..\common\src\tx_block_pool_create.c - - - tx_block_pool_delete.c - 1 - ..\..\..\..\common\src\tx_block_pool_delete.c - - - tx_block_pool_info_get.c - 1 - ..\..\..\..\common\src\tx_block_pool_info_get.c - - - tx_block_pool_initialize.c - 1 - ..\..\..\..\common\src\tx_block_pool_initialize.c - - - tx_block_pool_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_block_pool_performance_info_get.c - - - tx_block_pool_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c - - - tx_block_pool_prioritize.c - 1 - ..\..\..\..\common\src\tx_block_pool_prioritize.c - - - tx_block_release.c - 1 - ..\..\..\..\common\src\tx_block_release.c - - - tx_byte_allocate.c - 1 - ..\..\..\..\common\src\tx_byte_allocate.c - - - tx_byte_pool_cleanup.c - 1 - ..\..\..\..\common\src\tx_byte_pool_cleanup.c - - - tx_byte_pool_create.c - 1 - ..\..\..\..\common\src\tx_byte_pool_create.c - - - tx_byte_pool_delete.c - 1 - ..\..\..\..\common\src\tx_byte_pool_delete.c - - - tx_byte_pool_info_get.c - 1 - ..\..\..\..\common\src\tx_byte_pool_info_get.c - - - tx_byte_pool_initialize.c - 1 - ..\..\..\..\common\src\tx_byte_pool_initialize.c - - - tx_byte_pool_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_byte_pool_performance_info_get.c - - - tx_byte_pool_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c - - - tx_byte_pool_prioritize.c - 1 - ..\..\..\..\common\src\tx_byte_pool_prioritize.c - - - tx_byte_pool_search.c - 1 - ..\..\..\..\common\src\tx_byte_pool_search.c - - - tx_byte_release.c - 1 - ..\..\..\..\common\src\tx_byte_release.c - - - tx_event_flags_cleanup.c - 1 - ..\..\..\..\common\src\tx_event_flags_cleanup.c - - - tx_event_flags_create.c - 1 - ..\..\..\..\common\src\tx_event_flags_create.c - - - tx_event_flags_delete.c - 1 - ..\..\..\..\common\src\tx_event_flags_delete.c - - - tx_event_flags_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_get.c - - - tx_event_flags_info_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_info_get.c - - - tx_event_flags_initialize.c - 1 - ..\..\..\..\common\src\tx_event_flags_initialize.c - - - tx_event_flags_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_performance_info_get.c - - - tx_event_flags_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c - - - tx_event_flags_set.c - 1 - ..\..\..\..\common\src\tx_event_flags_set.c - - - tx_event_flags_set_notify.c - 1 - ..\..\..\..\common\src\tx_event_flags_set_notify.c - - - tx_initialize_high_level.c - 1 - ..\..\..\..\common\src\tx_initialize_high_level.c - - - tx_initialize_kernel_enter.c - 1 - ..\..\..\..\common\src\tx_initialize_kernel_enter.c - - - tx_initialize_kernel_setup.c - 1 - ..\..\..\..\common\src\tx_initialize_kernel_setup.c - - - tx_mutex_cleanup.c - 1 - ..\..\..\..\common\src\tx_mutex_cleanup.c - - - tx_mutex_create.c - 1 - ..\..\..\..\common\src\tx_mutex_create.c - - - tx_mutex_delete.c - 1 - ..\..\..\..\common\src\tx_mutex_delete.c - - - tx_mutex_get.c - 1 - ..\..\..\..\common\src\tx_mutex_get.c - - - tx_mutex_info_get.c - 1 - ..\..\..\..\common\src\tx_mutex_info_get.c - - - tx_mutex_initialize.c - 1 - ..\..\..\..\common\src\tx_mutex_initialize.c - - - tx_mutex_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_mutex_performance_info_get.c - - - tx_mutex_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_mutex_performance_system_info_get.c - - - tx_mutex_prioritize.c - 1 - ..\..\..\..\common\src\tx_mutex_prioritize.c - - - tx_mutex_priority_change.c - 1 - ..\..\..\..\common\src\tx_mutex_priority_change.c - - - tx_mutex_put.c - 1 - ..\..\..\..\common\src\tx_mutex_put.c - - - tx_queue_cleanup.c - 1 - ..\..\..\..\common\src\tx_queue_cleanup.c - - - tx_queue_create.c - 1 - ..\..\..\..\common\src\tx_queue_create.c - - - tx_queue_delete.c - 1 - ..\..\..\..\common\src\tx_queue_delete.c - - - tx_queue_flush.c - 1 - ..\..\..\..\common\src\tx_queue_flush.c - - - tx_queue_front_send.c - 1 - ..\..\..\..\common\src\tx_queue_front_send.c - - - tx_queue_info_get.c - 1 - ..\..\..\..\common\src\tx_queue_info_get.c - - - tx_queue_initialize.c - 1 - ..\..\..\..\common\src\tx_queue_initialize.c - - - tx_queue_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_queue_performance_info_get.c - - - tx_queue_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_queue_performance_system_info_get.c - - - tx_queue_prioritize.c - 1 - ..\..\..\..\common\src\tx_queue_prioritize.c - - - tx_queue_receive.c - 1 - ..\..\..\..\common\src\tx_queue_receive.c - - - tx_queue_send.c - 1 - ..\..\..\..\common\src\tx_queue_send.c - - - tx_queue_send_notify.c - 1 - ..\..\..\..\common\src\tx_queue_send_notify.c - - - tx_semaphore_ceiling_put.c - 1 - ..\..\..\..\common\src\tx_semaphore_ceiling_put.c - - - tx_semaphore_cleanup.c - 1 - ..\..\..\..\common\src\tx_semaphore_cleanup.c - - - tx_semaphore_create.c - 1 - ..\..\..\..\common\src\tx_semaphore_create.c - - - tx_semaphore_delete.c - 1 - ..\..\..\..\common\src\tx_semaphore_delete.c - - - tx_semaphore_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_get.c - - - tx_semaphore_info_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_info_get.c - - - tx_semaphore_initialize.c - 1 - ..\..\..\..\common\src\tx_semaphore_initialize.c - - - tx_semaphore_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_performance_info_get.c - - - tx_semaphore_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c - - - tx_semaphore_prioritize.c - 1 - ..\..\..\..\common\src\tx_semaphore_prioritize.c - - - tx_semaphore_put.c - 1 - ..\..\..\..\common\src\tx_semaphore_put.c - - - tx_semaphore_put_notify.c - 1 - ..\..\..\..\common\src\tx_semaphore_put_notify.c - - - tx_thread_create.c - 1 - ..\..\..\..\common\src\tx_thread_create.c - - - tx_thread_delete.c - 1 - ..\..\..\..\common\src\tx_thread_delete.c - - - tx_thread_entry_exit_notify.c - 1 - ..\..\..\..\common\src\tx_thread_entry_exit_notify.c - - - tx_thread_identify.c - 1 - ..\..\..\..\common\src\tx_thread_identify.c - - - tx_thread_info_get.c - 1 - ..\..\..\..\common\src\tx_thread_info_get.c - - - tx_thread_initialize.c - 1 - ..\..\..\..\common\src\tx_thread_initialize.c - - - tx_thread_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_thread_performance_info_get.c - - - tx_thread_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_thread_performance_system_info_get.c - - - tx_thread_preemption_change.c - 1 - ..\..\..\..\common\src\tx_thread_preemption_change.c - - - tx_thread_priority_change.c - 1 - ..\..\..\..\common\src\tx_thread_priority_change.c - - - tx_thread_relinquish.c - 1 - ..\..\..\..\common\src\tx_thread_relinquish.c - - - tx_thread_reset.c - 1 - ..\..\..\..\common\src\tx_thread_reset.c - - - tx_thread_resume.c - 1 - ..\..\..\..\common\src\tx_thread_resume.c - - - tx_thread_shell_entry.c - 1 - ..\..\..\..\common\src\tx_thread_shell_entry.c - - - tx_thread_sleep.c - 1 - ..\..\..\..\common\src\tx_thread_sleep.c - - - tx_thread_stack_analyze.c - 1 - ..\..\..\..\common\src\tx_thread_stack_analyze.c - - - tx_thread_suspend.c - 1 - ..\..\..\..\common\src\tx_thread_suspend.c - - - tx_thread_system_preempt_check.c - 1 - ..\..\..\..\common\src\tx_thread_system_preempt_check.c - - - tx_thread_system_resume.c - 1 - ..\..\..\..\common\src\tx_thread_system_resume.c - - - tx_thread_system_suspend.c - 1 - ..\..\..\..\common\src\tx_thread_system_suspend.c - - - tx_thread_terminate.c - 1 - ..\..\..\..\common\src\tx_thread_terminate.c - - - tx_thread_time_slice.c - 1 - ..\..\..\..\common\src\tx_thread_time_slice.c - - - tx_thread_time_slice_change.c - 1 - ..\..\..\..\common\src\tx_thread_time_slice_change.c - - - tx_thread_timeout.c - 1 - ..\..\..\..\common\src\tx_thread_timeout.c - - - tx_thread_wait_abort.c - 1 - ..\..\..\..\common\src\tx_thread_wait_abort.c - - - tx_time_get.c - 1 - ..\..\..\..\common\src\tx_time_get.c - - - tx_time_set.c - 1 - ..\..\..\..\common\src\tx_time_set.c - - - tx_timer_activate.c - 1 - ..\..\..\..\common\src\tx_timer_activate.c - - - tx_timer_change.c - 1 - ..\..\..\..\common\src\tx_timer_change.c - - - tx_timer_create.c - 1 - ..\..\..\..\common\src\tx_timer_create.c - - - tx_timer_deactivate.c - 1 - ..\..\..\..\common\src\tx_timer_deactivate.c - - - tx_timer_delete.c - 1 - ..\..\..\..\common\src\tx_timer_delete.c - - - tx_timer_expiration_process.c - 1 - ..\..\..\..\common\src\tx_timer_expiration_process.c - - - tx_timer_info_get.c - 1 - ..\..\..\..\common\src\tx_timer_info_get.c - - - tx_timer_initialize.c - 1 - ..\..\..\..\common\src\tx_timer_initialize.c - - - tx_timer_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_timer_performance_info_get.c - - - tx_timer_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_timer_performance_system_info_get.c - - - tx_timer_system_activate.c - 1 - ..\..\..\..\common\src\tx_timer_system_activate.c - - - tx_timer_system_deactivate.c - 1 - ..\..\..\..\common\src\tx_timer_system_deactivate.c - - - tx_timer_thread_entry.c - 1 - ..\..\..\..\common\src\tx_timer_thread_entry.c - - - tx_trace_disable.c - 1 - ..\..\..\..\common\src\tx_trace_disable.c - - - tx_trace_enable.c - 1 - ..\..\..\..\common\src\tx_trace_enable.c - - - tx_trace_initialize.c - 1 - ..\..\..\..\common\src\tx_trace_initialize.c - - - tx_trace_interrupt_control.c - 1 - ..\..\..\..\common\src\tx_trace_interrupt_control.c - - - tx_trace_isr_enter_insert.c - 1 - ..\..\..\..\common\src\tx_trace_isr_enter_insert.c - - - tx_trace_isr_exit_insert.c - 1 - ..\..\..\..\common\src\tx_trace_isr_exit_insert.c - - - tx_trace_object_register.c - 1 - ..\..\..\..\common\src\tx_trace_object_register.c - - - tx_trace_object_unregister.c - 1 - ..\..\..\..\common\src\tx_trace_object_unregister.c - - - tx_trace_user_event_insert.c - 1 - ..\..\..\..\common\src\tx_trace_user_event_insert.c - - - txe_block_allocate.c - 1 - ..\..\..\..\common\src\txe_block_allocate.c - - - txe_block_pool_create.c - 1 - ..\..\..\..\common\src\txe_block_pool_create.c - - - txe_block_pool_delete.c - 1 - ..\..\..\..\common\src\txe_block_pool_delete.c - - - txe_block_pool_info_get.c - 1 - ..\..\..\..\common\src\txe_block_pool_info_get.c - - - txe_block_pool_prioritize.c - 1 - ..\..\..\..\common\src\txe_block_pool_prioritize.c - - - txe_block_release.c - 1 - ..\..\..\..\common\src\txe_block_release.c - - - txe_byte_allocate.c - 1 - ..\..\..\..\common\src\txe_byte_allocate.c - - - txe_byte_pool_create.c - 1 - ..\..\..\..\common\src\txe_byte_pool_create.c - - - txe_byte_pool_delete.c - 1 - ..\..\..\..\common\src\txe_byte_pool_delete.c - - - txe_byte_pool_info_get.c - 1 - ..\..\..\..\common\src\txe_byte_pool_info_get.c - - - txe_byte_pool_prioritize.c - 1 - ..\..\..\..\common\src\txe_byte_pool_prioritize.c - - - txe_byte_release.c - 1 - ..\..\..\..\common\src\txe_byte_release.c - - - txe_event_flags_create.c - 1 - ..\..\..\..\common\src\txe_event_flags_create.c - - - txe_event_flags_delete.c - 1 - ..\..\..\..\common\src\txe_event_flags_delete.c - - - txe_event_flags_get.c - 1 - ..\..\..\..\common\src\txe_event_flags_get.c - - - txe_event_flags_info_get.c - 1 - ..\..\..\..\common\src\txe_event_flags_info_get.c - - - txe_event_flags_set.c - 1 - ..\..\..\..\common\src\txe_event_flags_set.c - - - txe_event_flags_set_notify.c - 1 - ..\..\..\..\common\src\txe_event_flags_set_notify.c - - - txe_mutex_create.c - 1 - ..\..\..\..\common\src\txe_mutex_create.c - - - txe_mutex_delete.c - 1 - ..\..\..\..\common\src\txe_mutex_delete.c - - - txe_mutex_get.c - 1 - ..\..\..\..\common\src\txe_mutex_get.c - - - txe_mutex_info_get.c - 1 - ..\..\..\..\common\src\txe_mutex_info_get.c - - - txe_mutex_prioritize.c - 1 - ..\..\..\..\common\src\txe_mutex_prioritize.c - - - txe_mutex_put.c - 1 - ..\..\..\..\common\src\txe_mutex_put.c - - - txe_queue_create.c - 1 - ..\..\..\..\common\src\txe_queue_create.c - - - txe_queue_delete.c - 1 - ..\..\..\..\common\src\txe_queue_delete.c - - - txe_queue_flush.c - 1 - ..\..\..\..\common\src\txe_queue_flush.c - - - txe_queue_front_send.c - 1 - ..\..\..\..\common\src\txe_queue_front_send.c - - - txe_queue_info_get.c - 1 - ..\..\..\..\common\src\txe_queue_info_get.c - - - txe_queue_prioritize.c - 1 - ..\..\..\..\common\src\txe_queue_prioritize.c - - - txe_queue_receive.c - 1 - ..\..\..\..\common\src\txe_queue_receive.c - - - txe_queue_send.c - 1 - ..\..\..\..\common\src\txe_queue_send.c - - - txe_queue_send_notify.c - 1 - ..\..\..\..\common\src\txe_queue_send_notify.c - - - txe_semaphore_ceiling_put.c - 1 - ..\..\..\..\common\src\txe_semaphore_ceiling_put.c - - - txe_semaphore_create.c - 1 - ..\..\..\..\common\src\txe_semaphore_create.c - - - txe_semaphore_delete.c - 1 - ..\..\..\..\common\src\txe_semaphore_delete.c - - - txe_semaphore_get.c - 1 - ..\..\..\..\common\src\txe_semaphore_get.c - - - txe_semaphore_info_get.c - 1 - ..\..\..\..\common\src\txe_semaphore_info_get.c - - - txe_semaphore_prioritize.c - 1 - ..\..\..\..\common\src\txe_semaphore_prioritize.c - - - txe_semaphore_put.c - 1 - ..\..\..\..\common\src\txe_semaphore_put.c - - - txe_semaphore_put_notify.c - 1 - ..\..\..\..\common\src\txe_semaphore_put_notify.c - - - txe_thread_create.c - 1 - ..\..\..\..\common\src\txe_thread_create.c - - - txe_thread_delete.c - 1 - ..\..\..\..\common\src\txe_thread_delete.c - - - txe_thread_entry_exit_notify.c - 1 - ..\..\..\..\common\src\txe_thread_entry_exit_notify.c - - - txe_thread_info_get.c - 1 - ..\..\..\..\common\src\txe_thread_info_get.c - - - txe_thread_preemption_change.c - 1 - ..\..\..\..\common\src\txe_thread_preemption_change.c - - - txe_thread_priority_change.c - 1 - ..\..\..\..\common\src\txe_thread_priority_change.c - - - txe_thread_relinquish.c - 1 - ..\..\..\..\common\src\txe_thread_relinquish.c - - - txe_thread_reset.c - 1 - ..\..\..\..\common\src\txe_thread_reset.c - - - txe_thread_resume.c - 1 - ..\..\..\..\common\src\txe_thread_resume.c - - - txe_thread_suspend.c - 1 - ..\..\..\..\common\src\txe_thread_suspend.c - - - txe_thread_terminate.c - 1 - ..\..\..\..\common\src\txe_thread_terminate.c - - - txe_thread_time_slice_change.c - 1 - ..\..\..\..\common\src\txe_thread_time_slice_change.c - - - txe_thread_wait_abort.c - 1 - ..\..\..\..\common\src\txe_thread_wait_abort.c - - - txe_timer_activate.c - 1 - ..\..\..\..\common\src\txe_timer_activate.c - - - txe_timer_change.c - 1 - ..\..\..\..\common\src\txe_timer_change.c - - - txe_timer_create.c - 1 - ..\..\..\..\common\src\txe_timer_create.c - - - txe_timer_deactivate.c - 1 - ..\..\..\..\common\src\txe_timer_deactivate.c - - - txe_timer_delete.c - 1 - ..\..\..\..\common\src\txe_timer_delete.c - - - txe_timer_info_get.c - 1 - ..\..\..\..\common\src\txe_timer_info_get.c - - - tx_timer_interrupt.s - 2 - ..\src\tx_timer_interrupt.s - - - tx_thread_context_restore.s - 2 - ..\src\tx_thread_context_restore.s - - - tx_thread_context_save.s - 2 - ..\src\tx_thread_context_save.s - - - tx_thread_interrupt_control.s - 2 - ..\src\tx_thread_interrupt_control.s - - - tx_thread_schedule.s - 2 - ..\src\tx_thread_schedule.s - - - tx_thread_stack_build.s - 2 - ..\src\tx_thread_stack_build.s - - - tx_thread_system_return.s - 2 - ..\src\tx_thread_system_return.s - - - tx_trace_buffer_full_notify.c - 1 - ..\..\..\..\common\src\tx_trace_buffer_full_notify.c - - - tx_trace_event_filter.c - 1 - ..\..\..\..\common\src\tx_trace_event_filter.c - - - tx_trace_event_unfilter.c - 1 - ..\..\..\..\common\src\tx_trace_event_unfilter.c - - - tx_thread_interrupt_disable.s - 2 - ..\src\tx_thread_interrupt_disable.s - - - tx_thread_interrupt_restore.s - 2 - ..\src\tx_thread_interrupt_restore.s - - - txe_thread_secure_stack_allocate.c - 1 - ..\src\txe_thread_secure_stack_allocate.c - - - txe_thread_secure_stack_free.c - 1 - ..\src\txe_thread_secure_stack_free.c - - - tx_thread_secure_stack_allocate.s - 2 - ..\src\tx_thread_secure_stack_allocate.s - - - tx_thread_secure_stack_free.s - 2 - ..\src\tx_thread_secure_stack_free.s - - - tx_initialize_low_level.s - 2 - .\tx_initialize_low_level.s - - - tx_thread_stack_error_handler.c - 1 - ..\src\tx_thread_stack_error_handler.c - - - tx_thread_stack_error_notify.c - 1 - ..\src\tx_thread_stack_error_notify.c - - - - - ::CMSIS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <Project Info> - - - - - - 0 - 1 - - - - -
diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/Abstract.txt b/ports/cortex_m23/ac5/example_build/demo_secure_zone/Abstract.txt deleted file mode 100644 index 0d1d8c52..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/Abstract.txt +++ /dev/null @@ -1,19 +0,0 @@ -This ARM Cortex-M33 secure/non-secure example project that -shows the setup of the CMSIS-RTOS2 RTX for TrustZone for -ARMv8-M applications. - -The application uses CMSIS and can be executed on a Fixed -Virtual Platform (FVP) simulation model. The application -demonstrates three RTOS threads. - - -Secure application: - - Setup code and start non-secure application. - -Non-secure application: - - Calls a secure function from non-secure state. - - Calls a secure function that call back to a non-secure function. - -Output: -Variables used in this application can be viewed in the Debugger -Watch window. \ No newline at end of file diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct b/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct deleted file mode 100644 index a833a90d..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct +++ /dev/null @@ -1,78 +0,0 @@ -#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m23 -xc -; command above MUST be in first line (no comment above!) - -/* -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------- -*/ - -/*--------------------- Flash Configuration ---------------------------------- -; Flash Configuration -; Flash Base Address <0x0-0xFFFFFFFF:8> -; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __ROM_BASE 0x00000000 -#define __ROM_SIZE 0x00080000 - -/*--------------------- Embedded RAM Configuration --------------------------- -; RAM Configuration -; RAM Base Address <0x0-0xFFFFFFFF:8> -; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __RAM_BASE 0x20000000 -#define __RAM_SIZE 0x00040000 - -/*--------------------- Stack / Heap Configuration --------------------------- -; Stack / Heap Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __STACK_SIZE 0x00000200 -#define __HEAP_SIZE 0x00000C00 - - -/*---------------------------------------------------------------------------- - User Stack & Heap boundery definition - *----------------------------------------------------------------------------*/ -#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ -#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ - - -/*---------------------------------------------------------------------------- - Scatter File Definitions definition - *----------------------------------------------------------------------------*/ -#define __RO_BASE __ROM_BASE -#define __RO_SIZE __ROM_SIZE - -#define __RW_BASE (__RAM_BASE ) -#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) - - - -LR_ROM __RO_BASE __RO_SIZE { ; load region size_region - ER_ROM __RO_BASE __RO_SIZE { ; load address = execution address - *.o (RESET, +First) - *(InRoot$$Sections) -; *(Veneer$$CMSE) ; uncomment for secure applications - .ANY (+RO) - .ANY (+XO) - } - - RW_RAM __RW_BASE __RW_SIZE { ; RW data - .ANY (+RW +ZI) - } - -#if __HEAP_SIZE > 0 - ARM_LIB_HEAP __HEAP_BASE EMPTY __HEAP_SIZE { ; Reserve empty region for heap - } -#endif - - ARM_LIB_STACK __STACK_TOP EMPTY -__STACK_SIZE { ; Reserve empty region for stack - } - SEAL +0 - { - *.o(.seal+FIRST) - } -} diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h b/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h deleted file mode 100644 index a7a090e7..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h +++ /dev/null @@ -1,832 +0,0 @@ -/**************************************************************************//** - * @file partition_ARMCM23.h - * @brief CMSIS-CORE Initial Setup for Secure / Non-Secure Zones for ARMCM23 - * @version V5.3.1 - * @date 09. July 2018 - ******************************************************************************/ -/* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PARTITION_ARMCM23_H -#define PARTITION_ARMCM23_H - -/* -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -*/ - -/* -// Initialize Security Attribution Unit (SAU) CTRL register -*/ -#define SAU_INIT_CTRL 1 - -/* -// Enable SAU -// Value for SAU->CTRL register bit ENABLE -*/ -#define SAU_INIT_CTRL_ENABLE 1 - -/* -// When SAU is disabled -// <0=> All Memory is Secure -// <1=> All Memory is Non-Secure -// Value for SAU->CTRL register bit ALLNS -// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. -*/ -#define SAU_INIT_CTRL_ALLNS 0 - -/* -// -*/ - -/* -// Initialize Security Attribution Unit (SAU) Address Regions -// SAU configuration specifies regions to be one of: -// - Secure and Non-Secure Callable -// - Non-Secure -// Note: All memory regions not configured by SAU are Secure -*/ -#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ - -/* -// Initialize SAU Region 0 -// Setup SAU Region 0 memory attributes -*/ -#define SAU_INIT_REGION0 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START0 0x00000000 /* start address of SAU region 0 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END0 0x001FFFFF /* end address of SAU region 0 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC0 1 -/* -// -*/ - -/* -// Initialize SAU Region 1 -// Setup SAU Region 1 memory attributes -*/ -#define SAU_INIT_REGION1 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START1 0x00200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END1 0x003FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC1 0 -/* -// -*/ - -/* -// Initialize SAU Region 2 -// Setup SAU Region 2 memory attributes -*/ -#define SAU_INIT_REGION2 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START2 0x20200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END2 0x203FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC2 0 -/* -// -*/ - -/* -// Initialize SAU Region 3 -// Setup SAU Region 3 memory attributes -*/ -#define SAU_INIT_REGION3 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START3 0x40000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END3 0x40040000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC3 0 -/* -// -*/ - -/* -// Initialize SAU Region 4 -// Setup SAU Region 4 memory attributes -*/ -#define SAU_INIT_REGION4 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START4 0x00000000 /* start address of SAU region 4 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END4 0x00000000 /* end address of SAU region 4 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC4 0 -/* -// -*/ - -/* -// Initialize SAU Region 5 -// Setup SAU Region 5 memory attributes -*/ -#define SAU_INIT_REGION5 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START5 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END5 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC5 0 -/* -// -*/ - -/* -// Initialize SAU Region 6 -// Setup SAU Region 6 memory attributes -*/ -#define SAU_INIT_REGION6 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START6 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END6 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC6 0 -/* -// -*/ - -/* -// Initialize SAU Region 7 -// Setup SAU Region 7 memory attributes -*/ -#define SAU_INIT_REGION7 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START7 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END7 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC7 0 -/* -// -*/ - -/* -// -*/ - -/* -// Setup behaviour of Sleep and Exception Handling -*/ -#define SCB_CSR_AIRCR_INIT 1 - -/* -// Deep Sleep can be enabled by -// <0=>Secure and Non-Secure state -// <1=>Secure state only -// Value for SCB->CSR register bit DEEPSLEEPS -*/ -#define SCB_CSR_DEEPSLEEPS_VAL 1 - -/* -// System reset request accessible from -// <0=> Secure and Non-Secure state -// <1=> Secure state only -// Value for SCB->AIRCR register bit SYSRESETREQS -*/ -#define SCB_AIRCR_SYSRESETREQS_VAL 1 - -/* -// Priority of Non-Secure exceptions is -// <0=> Not altered -// <1=> Lowered to 0x80-0xFF -// Value for SCB->AIRCR register bit PRIS -*/ -#define SCB_AIRCR_PRIS_VAL 1 - -/* -// BusFault, HardFault, and NMI target -// <0=> Secure state -// <1=> Non-Secure state -// Value for SCB->AIRCR register bit BFHFNMINS -*/ -#define SCB_AIRCR_BFHFNMINS_VAL 0 - -/* -// -*/ - - -/* -// Setup behaviour of single SysTick -*/ -#define SCB_ICSR_INIT 0 - -/* -// in a single SysTick implementation, SysTick is -// <0=>Secure -// <1=>Non-Secure -// Value for SCB->ICSR register bit STTNS -// only for single SysTick implementation -*/ -#define SCB_ICSR_STTNS_VAL 0 - -/* -// -*/ - - -/* -// Setup Interrupt Target -*/ - -/* -// Initialize ITNS 0 (Interrupts 0..31) -*/ -#define NVIC_INIT_ITNS0 1 - -/* -// Interrupts 0..31 -// Interrupt 0 <0=> Secure state <1=> Non-Secure state -// Interrupt 1 <0=> Secure state <1=> Non-Secure state -// Interrupt 2 <0=> Secure state <1=> Non-Secure state -// Interrupt 3 <0=> Secure state <1=> Non-Secure state -// Interrupt 4 <0=> Secure state <1=> Non-Secure state -// Interrupt 5 <0=> Secure state <1=> Non-Secure state -// Interrupt 6 <0=> Secure state <1=> Non-Secure state -// Interrupt 7 <0=> Secure state <1=> Non-Secure state -// Interrupt 8 <0=> Secure state <1=> Non-Secure state -// Interrupt 9 <0=> Secure state <1=> Non-Secure state -// Interrupt 10 <0=> Secure state <1=> Non-Secure state -// Interrupt 11 <0=> Secure state <1=> Non-Secure state -// Interrupt 12 <0=> Secure state <1=> Non-Secure state -// Interrupt 13 <0=> Secure state <1=> Non-Secure state -// Interrupt 14 <0=> Secure state <1=> Non-Secure state -// Interrupt 15 <0=> Secure state <1=> Non-Secure state -// Interrupt 16 <0=> Secure state <1=> Non-Secure state -// Interrupt 17 <0=> Secure state <1=> Non-Secure state -// Interrupt 18 <0=> Secure state <1=> Non-Secure state -// Interrupt 19 <0=> Secure state <1=> Non-Secure state -// Interrupt 20 <0=> Secure state <1=> Non-Secure state -// Interrupt 21 <0=> Secure state <1=> Non-Secure state -// Interrupt 22 <0=> Secure state <1=> Non-Secure state -// Interrupt 23 <0=> Secure state <1=> Non-Secure state -// Interrupt 24 <0=> Secure state <1=> Non-Secure state -// Interrupt 25 <0=> Secure state <1=> Non-Secure state -// Interrupt 26 <0=> Secure state <1=> Non-Secure state -// Interrupt 27 <0=> Secure state <1=> Non-Secure state -// Interrupt 28 <0=> Secure state <1=> Non-Secure state -// Interrupt 29 <0=> Secure state <1=> Non-Secure state -// Interrupt 30 <0=> Secure state <1=> Non-Secure state -// Interrupt 31 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS0_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 1 (Interrupts 32..63) -*/ -#define NVIC_INIT_ITNS1 1 - -/* -// Interrupts 32..63 -// Interrupt 32 <0=> Secure state <1=> Non-Secure state -// Interrupt 33 <0=> Secure state <1=> Non-Secure state -// Interrupt 34 <0=> Secure state <1=> Non-Secure state -// Interrupt 35 <0=> Secure state <1=> Non-Secure state -// Interrupt 36 <0=> Secure state <1=> Non-Secure state -// Interrupt 37 <0=> Secure state <1=> Non-Secure state -// Interrupt 38 <0=> Secure state <1=> Non-Secure state -// Interrupt 39 <0=> Secure state <1=> Non-Secure state -// Interrupt 40 <0=> Secure state <1=> Non-Secure state -// Interrupt 41 <0=> Secure state <1=> Non-Secure state -// Interrupt 42 <0=> Secure state <1=> Non-Secure state -// Interrupt 43 <0=> Secure state <1=> Non-Secure state -// Interrupt 44 <0=> Secure state <1=> Non-Secure state -// Interrupt 45 <0=> Secure state <1=> Non-Secure state -// Interrupt 46 <0=> Secure state <1=> Non-Secure state -// Interrupt 47 <0=> Secure state <1=> Non-Secure state -// Interrupt 48 <0=> Secure state <1=> Non-Secure state -// Interrupt 49 <0=> Secure state <1=> Non-Secure state -// Interrupt 50 <0=> Secure state <1=> Non-Secure state -// Interrupt 51 <0=> Secure state <1=> Non-Secure state -// Interrupt 52 <0=> Secure state <1=> Non-Secure state -// Interrupt 53 <0=> Secure state <1=> Non-Secure state -// Interrupt 54 <0=> Secure state <1=> Non-Secure state -// Interrupt 55 <0=> Secure state <1=> Non-Secure state -// Interrupt 56 <0=> Secure state <1=> Non-Secure state -// Interrupt 57 <0=> Secure state <1=> Non-Secure state -// Interrupt 58 <0=> Secure state <1=> Non-Secure state -// Interrupt 59 <0=> Secure state <1=> Non-Secure state -// Interrupt 60 <0=> Secure state <1=> Non-Secure state -// Interrupt 61 <0=> Secure state <1=> Non-Secure state -// Interrupt 62 <0=> Secure state <1=> Non-Secure state -// Interrupt 63 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS1_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 2 (Interrupts 64..95) -*/ -#define NVIC_INIT_ITNS2 0 - -/* -// Interrupts 64..95 -// Interrupt 64 <0=> Secure state <1=> Non-Secure state -// Interrupt 65 <0=> Secure state <1=> Non-Secure state -// Interrupt 66 <0=> Secure state <1=> Non-Secure state -// Interrupt 67 <0=> Secure state <1=> Non-Secure state -// Interrupt 68 <0=> Secure state <1=> Non-Secure state -// Interrupt 69 <0=> Secure state <1=> Non-Secure state -// Interrupt 70 <0=> Secure state <1=> Non-Secure state -// Interrupt 71 <0=> Secure state <1=> Non-Secure state -// Interrupt 72 <0=> Secure state <1=> Non-Secure state -// Interrupt 73 <0=> Secure state <1=> Non-Secure state -// Interrupt 74 <0=> Secure state <1=> Non-Secure state -// Interrupt 75 <0=> Secure state <1=> Non-Secure state -// Interrupt 76 <0=> Secure state <1=> Non-Secure state -// Interrupt 77 <0=> Secure state <1=> Non-Secure state -// Interrupt 78 <0=> Secure state <1=> Non-Secure state -// Interrupt 79 <0=> Secure state <1=> Non-Secure state -// Interrupt 80 <0=> Secure state <1=> Non-Secure state -// Interrupt 81 <0=> Secure state <1=> Non-Secure state -// Interrupt 82 <0=> Secure state <1=> Non-Secure state -// Interrupt 83 <0=> Secure state <1=> Non-Secure state -// Interrupt 84 <0=> Secure state <1=> Non-Secure state -// Interrupt 85 <0=> Secure state <1=> Non-Secure state -// Interrupt 86 <0=> Secure state <1=> Non-Secure state -// Interrupt 87 <0=> Secure state <1=> Non-Secure state -// Interrupt 88 <0=> Secure state <1=> Non-Secure state -// Interrupt 89 <0=> Secure state <1=> Non-Secure state -// Interrupt 90 <0=> Secure state <1=> Non-Secure state -// Interrupt 91 <0=> Secure state <1=> Non-Secure state -// Interrupt 92 <0=> Secure state <1=> Non-Secure state -// Interrupt 93 <0=> Secure state <1=> Non-Secure state -// Interrupt 94 <0=> Secure state <1=> Non-Secure state -// Interrupt 95 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS2_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 3 (Interrupts 96..127) -*/ -#define NVIC_INIT_ITNS3 0 - -/* -// Interrupts 96..127 -// Interrupt 96 <0=> Secure state <1=> Non-Secure state -// Interrupt 97 <0=> Secure state <1=> Non-Secure state -// Interrupt 98 <0=> Secure state <1=> Non-Secure state -// Interrupt 99 <0=> Secure state <1=> Non-Secure state -// Interrupt 100 <0=> Secure state <1=> Non-Secure state -// Interrupt 101 <0=> Secure state <1=> Non-Secure state -// Interrupt 102 <0=> Secure state <1=> Non-Secure state -// Interrupt 103 <0=> Secure state <1=> Non-Secure state -// Interrupt 104 <0=> Secure state <1=> Non-Secure state -// Interrupt 105 <0=> Secure state <1=> Non-Secure state -// Interrupt 106 <0=> Secure state <1=> Non-Secure state -// Interrupt 107 <0=> Secure state <1=> Non-Secure state -// Interrupt 108 <0=> Secure state <1=> Non-Secure state -// Interrupt 109 <0=> Secure state <1=> Non-Secure state -// Interrupt 110 <0=> Secure state <1=> Non-Secure state -// Interrupt 111 <0=> Secure state <1=> Non-Secure state -// Interrupt 112 <0=> Secure state <1=> Non-Secure state -// Interrupt 113 <0=> Secure state <1=> Non-Secure state -// Interrupt 114 <0=> Secure state <1=> Non-Secure state -// Interrupt 115 <0=> Secure state <1=> Non-Secure state -// Interrupt 116 <0=> Secure state <1=> Non-Secure state -// Interrupt 117 <0=> Secure state <1=> Non-Secure state -// Interrupt 118 <0=> Secure state <1=> Non-Secure state -// Interrupt 119 <0=> Secure state <1=> Non-Secure state -// Interrupt 120 <0=> Secure state <1=> Non-Secure state -// Interrupt 121 <0=> Secure state <1=> Non-Secure state -// Interrupt 122 <0=> Secure state <1=> Non-Secure state -// Interrupt 123 <0=> Secure state <1=> Non-Secure state -// Interrupt 124 <0=> Secure state <1=> Non-Secure state -// Interrupt 125 <0=> Secure state <1=> Non-Secure state -// Interrupt 126 <0=> Secure state <1=> Non-Secure state -// Interrupt 127 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS3_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 4 (Interrupts 128..159) -*/ -#define NVIC_INIT_ITNS4 0 - -/* -// Interrupts 128..159 -// Interrupt 128 <0=> Secure state <1=> Non-Secure state -// Interrupt 129 <0=> Secure state <1=> Non-Secure state -// Interrupt 130 <0=> Secure state <1=> Non-Secure state -// Interrupt 131 <0=> Secure state <1=> Non-Secure state -// Interrupt 132 <0=> Secure state <1=> Non-Secure state -// Interrupt 133 <0=> Secure state <1=> Non-Secure state -// Interrupt 134 <0=> Secure state <1=> Non-Secure state -// Interrupt 135 <0=> Secure state <1=> Non-Secure state -// Interrupt 136 <0=> Secure state <1=> Non-Secure state -// Interrupt 137 <0=> Secure state <1=> Non-Secure state -// Interrupt 138 <0=> Secure state <1=> Non-Secure state -// Interrupt 139 <0=> Secure state <1=> Non-Secure state -// Interrupt 140 <0=> Secure state <1=> Non-Secure state -// Interrupt 141 <0=> Secure state <1=> Non-Secure state -// Interrupt 142 <0=> Secure state <1=> Non-Secure state -// Interrupt 143 <0=> Secure state <1=> Non-Secure state -// Interrupt 144 <0=> Secure state <1=> Non-Secure state -// Interrupt 145 <0=> Secure state <1=> Non-Secure state -// Interrupt 146 <0=> Secure state <1=> Non-Secure state -// Interrupt 147 <0=> Secure state <1=> Non-Secure state -// Interrupt 148 <0=> Secure state <1=> Non-Secure state -// Interrupt 149 <0=> Secure state <1=> Non-Secure state -// Interrupt 150 <0=> Secure state <1=> Non-Secure state -// Interrupt 151 <0=> Secure state <1=> Non-Secure state -// Interrupt 152 <0=> Secure state <1=> Non-Secure state -// Interrupt 153 <0=> Secure state <1=> Non-Secure state -// Interrupt 154 <0=> Secure state <1=> Non-Secure state -// Interrupt 155 <0=> Secure state <1=> Non-Secure state -// Interrupt 156 <0=> Secure state <1=> Non-Secure state -// Interrupt 157 <0=> Secure state <1=> Non-Secure state -// Interrupt 158 <0=> Secure state <1=> Non-Secure state -// Interrupt 159 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS4_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 5 (Interrupts 160..191) -*/ -#define NVIC_INIT_ITNS5 0 - -/* -// Interrupts 160..191 -// Interrupt 160 <0=> Secure state <1=> Non-Secure state -// Interrupt 161 <0=> Secure state <1=> Non-Secure state -// Interrupt 162 <0=> Secure state <1=> Non-Secure state -// Interrupt 163 <0=> Secure state <1=> Non-Secure state -// Interrupt 164 <0=> Secure state <1=> Non-Secure state -// Interrupt 165 <0=> Secure state <1=> Non-Secure state -// Interrupt 166 <0=> Secure state <1=> Non-Secure state -// Interrupt 167 <0=> Secure state <1=> Non-Secure state -// Interrupt 168 <0=> Secure state <1=> Non-Secure state -// Interrupt 169 <0=> Secure state <1=> Non-Secure state -// Interrupt 170 <0=> Secure state <1=> Non-Secure state -// Interrupt 171 <0=> Secure state <1=> Non-Secure state -// Interrupt 172 <0=> Secure state <1=> Non-Secure state -// Interrupt 173 <0=> Secure state <1=> Non-Secure state -// Interrupt 174 <0=> Secure state <1=> Non-Secure state -// Interrupt 175 <0=> Secure state <1=> Non-Secure state -// Interrupt 176 <0=> Secure state <1=> Non-Secure state -// Interrupt 177 <0=> Secure state <1=> Non-Secure state -// Interrupt 178 <0=> Secure state <1=> Non-Secure state -// Interrupt 179 <0=> Secure state <1=> Non-Secure state -// Interrupt 180 <0=> Secure state <1=> Non-Secure state -// Interrupt 181 <0=> Secure state <1=> Non-Secure state -// Interrupt 182 <0=> Secure state <1=> Non-Secure state -// Interrupt 183 <0=> Secure state <1=> Non-Secure state -// Interrupt 184 <0=> Secure state <1=> Non-Secure state -// Interrupt 185 <0=> Secure state <1=> Non-Secure state -// Interrupt 186 <0=> Secure state <1=> Non-Secure state -// Interrupt 187 <0=> Secure state <1=> Non-Secure state -// Interrupt 188 <0=> Secure state <1=> Non-Secure state -// Interrupt 189 <0=> Secure state <1=> Non-Secure state -// Interrupt 190 <0=> Secure state <1=> Non-Secure state -// Interrupt 191 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS5_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 6 (Interrupts 192..223) -*/ -#define NVIC_INIT_ITNS6 0 - -/* -// Interrupts 192..223 -// Interrupt 192 <0=> Secure state <1=> Non-Secure state -// Interrupt 193 <0=> Secure state <1=> Non-Secure state -// Interrupt 194 <0=> Secure state <1=> Non-Secure state -// Interrupt 195 <0=> Secure state <1=> Non-Secure state -// Interrupt 196 <0=> Secure state <1=> Non-Secure state -// Interrupt 197 <0=> Secure state <1=> Non-Secure state -// Interrupt 198 <0=> Secure state <1=> Non-Secure state -// Interrupt 199 <0=> Secure state <1=> Non-Secure state -// Interrupt 200 <0=> Secure state <1=> Non-Secure state -// Interrupt 201 <0=> Secure state <1=> Non-Secure state -// Interrupt 202 <0=> Secure state <1=> Non-Secure state -// Interrupt 203 <0=> Secure state <1=> Non-Secure state -// Interrupt 204 <0=> Secure state <1=> Non-Secure state -// Interrupt 205 <0=> Secure state <1=> Non-Secure state -// Interrupt 206 <0=> Secure state <1=> Non-Secure state -// Interrupt 207 <0=> Secure state <1=> Non-Secure state -// Interrupt 208 <0=> Secure state <1=> Non-Secure state -// Interrupt 209 <0=> Secure state <1=> Non-Secure state -// Interrupt 210 <0=> Secure state <1=> Non-Secure state -// Interrupt 211 <0=> Secure state <1=> Non-Secure state -// Interrupt 212 <0=> Secure state <1=> Non-Secure state -// Interrupt 213 <0=> Secure state <1=> Non-Secure state -// Interrupt 214 <0=> Secure state <1=> Non-Secure state -// Interrupt 215 <0=> Secure state <1=> Non-Secure state -// Interrupt 216 <0=> Secure state <1=> Non-Secure state -// Interrupt 217 <0=> Secure state <1=> Non-Secure state -// Interrupt 218 <0=> Secure state <1=> Non-Secure state -// Interrupt 219 <0=> Secure state <1=> Non-Secure state -// Interrupt 220 <0=> Secure state <1=> Non-Secure state -// Interrupt 221 <0=> Secure state <1=> Non-Secure state -// Interrupt 222 <0=> Secure state <1=> Non-Secure state -// Interrupt 223 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS6_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 7 (Interrupts 224..255) -*/ -#define NVIC_INIT_ITNS7 0 - -/* -// Interrupts 224..255 -// Interrupt 224 <0=> Secure state <1=> Non-Secure state -// Interrupt 225 <0=> Secure state <1=> Non-Secure state -// Interrupt 226 <0=> Secure state <1=> Non-Secure state -// Interrupt 227 <0=> Secure state <1=> Non-Secure state -// Interrupt 228 <0=> Secure state <1=> Non-Secure state -// Interrupt 229 <0=> Secure state <1=> Non-Secure state -// Interrupt 230 <0=> Secure state <1=> Non-Secure state -// Interrupt 231 <0=> Secure state <1=> Non-Secure state -// Interrupt 232 <0=> Secure state <1=> Non-Secure state -// Interrupt 233 <0=> Secure state <1=> Non-Secure state -// Interrupt 234 <0=> Secure state <1=> Non-Secure state -// Interrupt 235 <0=> Secure state <1=> Non-Secure state -// Interrupt 236 <0=> Secure state <1=> Non-Secure state -// Interrupt 237 <0=> Secure state <1=> Non-Secure state -// Interrupt 238 <0=> Secure state <1=> Non-Secure state -// Interrupt 239 <0=> Secure state <1=> Non-Secure state -// Interrupt 240 <0=> Secure state <1=> Non-Secure state -// Interrupt 241 <0=> Secure state <1=> Non-Secure state -// Interrupt 242 <0=> Secure state <1=> Non-Secure state -// Interrupt 243 <0=> Secure state <1=> Non-Secure state -// Interrupt 244 <0=> Secure state <1=> Non-Secure state -// Interrupt 245 <0=> Secure state <1=> Non-Secure state -// Interrupt 246 <0=> Secure state <1=> Non-Secure state -// Interrupt 247 <0=> Secure state <1=> Non-Secure state -// Interrupt 248 <0=> Secure state <1=> Non-Secure state -// Interrupt 249 <0=> Secure state <1=> Non-Secure state -// Interrupt 250 <0=> Secure state <1=> Non-Secure state -// Interrupt 251 <0=> Secure state <1=> Non-Secure state -// Interrupt 252 <0=> Secure state <1=> Non-Secure state -// Interrupt 253 <0=> Secure state <1=> Non-Secure state -// Interrupt 254 <0=> Secure state <1=> Non-Secure state -// Interrupt 255 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS7_VAL 0x00000000 - -/* -// -*/ - -/* -// -*/ - - - -/* - max 128 SAU regions. - SAU regions are defined in partition.h - */ - -#define SAU_INIT_REGION(n) \ - SAU->RNR = (n & SAU_RNR_REGION_Msk); \ - SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ - SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ - ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U - -/** - \brief Setup a SAU Region - \details Writes the region information contained in SAU_Region to the - registers SAU_RNR, SAU_RBAR, and SAU_RLAR - */ -__STATIC_INLINE void TZ_SAU_Setup (void) -{ - -#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) - - #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) - SAU_INIT_REGION(0); - #endif - - #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) - SAU_INIT_REGION(1); - #endif - - #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) - SAU_INIT_REGION(2); - #endif - - #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) - SAU_INIT_REGION(3); - #endif - - #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) - SAU_INIT_REGION(4); - #endif - - #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) - SAU_INIT_REGION(5); - #endif - - #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) - SAU_INIT_REGION(6); - #endif - - #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) - SAU_INIT_REGION(7); - #endif - - /* repeat this for all possible SAU regions */ - -#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ - - - #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) - SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | - ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; - #endif - - #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) - SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | - ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); - - SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | - SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk) ) | - ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | - ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | - ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | - ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); - #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ - - #if defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U) - SCB->ICSR = (SCB->ICSR & ~(SCB_ICSR_STTNS_Msk )) | - ((SCB_ICSR_STTNS_VAL << SCB_ICSR_STTNS_Pos) & SCB_ICSR_STTNS_Msk); - #endif /* defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U) */ - - #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) - NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; - #endif - - #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) - NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; - #endif - - #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) - NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; - #endif - - #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) - NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; - #endif - - #if defined (NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U) - NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL; - #endif - - #if defined (NVIC_INIT_ITNS5) && (NVIC_INIT_ITNS5 == 1U) - NVIC->ITNS[5] = NVIC_INIT_ITNS5_VAL; - #endif - - #if defined (NVIC_INIT_ITNS6) && (NVIC_INIT_ITNS6 == 1U) - NVIC->ITNS[6] = NVIC_INIT_ITNS6_VAL; - #endif - - #if defined (NVIC_INIT_ITNS7) && (NVIC_INIT_ITNS7 == 1U) - NVIC->ITNS[7] = NVIC_INIT_ITNS7_VAL; - #endif - - /* repeat this for all possible ITNS elements */ - -} - -#endif /* PARTITION_ARMCM23_H */ diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c b/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c deleted file mode 100644 index eb5fdfc5..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c +++ /dev/null @@ -1,140 +0,0 @@ -/****************************************************************************** - * @file startup_ARMCM23.c - * @brief CMSIS-Core(M) Device Startup File for a Cortex-M23 Device - * @version V2.0.0 - * @date 04. June 2019 - ******************************************************************************/ -/* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM23) - #include "ARMCM23.h" -#elif defined (ARMCM23_TZ) - #include "ARMCM23_TZ.h" -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler Function Prototype - *----------------------------------------------------------------------------*/ -typedef void( *pFunc )( void ); - -/*---------------------------------------------------------------------------- - External References - *----------------------------------------------------------------------------*/ -extern uint32_t __INITIAL_SP; -extern uint32_t __STACK_LIMIT; - -extern __NO_RETURN void __PROGRAM_START(void); - -/*---------------------------------------------------------------------------- - Internal References - *----------------------------------------------------------------------------*/ -void __NO_RETURN Default_Handler(void); -void __NO_RETURN Reset_Handler (void); - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler - *----------------------------------------------------------------------------*/ -/* Exceptions */ -void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - -void Interrupt0_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt1_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt2_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt3_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt4_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt5_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt6_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt7_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt8_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt9_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - - -/*---------------------------------------------------------------------------- - Exception / Interrupt Vector table - *----------------------------------------------------------------------------*/ - -#if defined ( __GNUC__ ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#endif - -extern const pFunc __VECTOR_TABLE[240]; - const pFunc __VECTOR_TABLE[240] __VECTOR_TABLE_ATTRIBUTE = { - (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ - Reset_Handler, /* Reset Handler */ - NMI_Handler, /* -14 NMI Handler */ - HardFault_Handler, /* -13 Hard Fault Handler */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - SVC_Handler, /* -5 SVCall Handler */ - 0, /* Reserved */ - 0, /* Reserved */ - PendSV_Handler, /* -2 PendSV Handler */ - SysTick_Handler, /* -1 SysTick Handler */ - - /* Interrupts */ - Interrupt0_Handler, /* 0 Interrupt 0 */ - Interrupt1_Handler, /* 1 Interrupt 1 */ - Interrupt2_Handler, /* 2 Interrupt 2 */ - Interrupt3_Handler, /* 3 Interrupt 3 */ - Interrupt4_Handler, /* 4 Interrupt 4 */ - Interrupt5_Handler, /* 5 Interrupt 5 */ - Interrupt6_Handler, /* 6 Interrupt 6 */ - Interrupt7_Handler, /* 7 Interrupt 7 */ - Interrupt8_Handler, /* 8 Interrupt 8 */ - Interrupt9_Handler /* 9 Interrupt 9 */ - /* Interrupts 10 .. 223 are left out */ -}; - -#if defined ( __GNUC__ ) -#pragma GCC diagnostic pop -#endif - -/* The linker will place this value at the bottom of the stack to seal the secure main stack. */ -const int stack_seal __attribute__((section (".seal"))) = 0xFEF5EDA5; - -/*---------------------------------------------------------------------------- - Reset Handler called on controller reset - *----------------------------------------------------------------------------*/ -void Reset_Handler(void) -{ - __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); - - SystemInit(); /* CMSIS System Initialization */ - __PROGRAM_START(); /* Enter PreMain (C library entry point) */ -} - -/*---------------------------------------------------------------------------- - Default Handler for Exceptions / Interrupts - *----------------------------------------------------------------------------*/ -void Default_Handler(void) -{ - while(1); -} diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c b/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c deleted file mode 100644 index 1052b383..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************//** - * @file system_ARMCM23.c - * @brief CMSIS Device System Source File for - * ARMCM23 Device - * @version V5.3.1 - * @date 09. July 2018 - ******************************************************************************/ -/* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM23) - #include "ARMCM23.h" -#elif defined (ARMCM23_TZ) - #include "ARMCM23_TZ.h" - - #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - #include "partition_ARMCM23.h" - #endif -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Define clocks - *----------------------------------------------------------------------------*/ -#define XTAL (50000000UL) /* Oscillator frequency */ - -#define SYSTEM_CLOCK (XTAL / 2U) - - -/*---------------------------------------------------------------------------- - Externals - *----------------------------------------------------------------------------*/ -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - extern uint32_t __VECTOR_TABLE; -#endif - -/*---------------------------------------------------------------------------- - System Core Clock Variable - *----------------------------------------------------------------------------*/ -uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Core Clock Frequency */ - - -/*---------------------------------------------------------------------------- - System Core Clock update function - *----------------------------------------------------------------------------*/ -void SystemCoreClockUpdate (void) -{ - SystemCoreClock = SYSTEM_CLOCK; -} - -/*---------------------------------------------------------------------------- - System initialization function - *----------------------------------------------------------------------------*/ -void SystemInit (void) -{ - -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - SCB->VTOR = (uint32_t) &__VECTOR_TABLE; -#endif - -#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - TZ_SAU_Setup(); -#endif - - SystemCoreClock = SYSTEM_CLOCK; - - *(uint32_t *)0xE000ED24 = 0x000F0000; /* S: enable secure, usage, bus, mem faults */ - *(uint32_t *)0xE002ED24 = 0x000F0000; /* NS: enable secure, usage, bus, mem faults */ -} - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -void HardFault_Handler(void) -{ - while(1); - -} - -void UsageFault_Handler(void) -{ - while(1); -} -#endif diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h b/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h deleted file mode 100644 index a37b412e..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'demo_secure_zone' - * Target: 'FVP Simulation Model' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM23_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/demo_secure_zone.uvoptx b/ports/cortex_m23/ac5/example_build/demo_secure_zone/demo_secure_zone.uvoptx deleted file mode 100644 index 91ee646d..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/demo_secure_zone.uvoptx +++ /dev/null @@ -1,328 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - FVP Simulation Model - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\Listings\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 7 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 15 - - - - - - - - - - ..\Debug.ini - BIN\DbgFMv8M.DLL - - - - 0 - UL2V8M - UL2V8M(-S0 -C0 -P0 -FC1000 -FD20000000 - - - 0 - DbgFMv8M - -I -S -L"cpu0" -O4102 -C0 -MC".\FVP\MPS2_Cortex-M\FVP_MPS2_Cortex-M23_MDK.exe" -MF"..\ARMCM23_TZ_config.txt" -PF -MA - - - 0 - DLGTARM - (6010=3649,-370,4126,226,0)(6018=2033,530,2222,894,0)(6019=-1,-1,-1,-1,0)(6008=1847,-259,2141,-74,0)(6009=2148,-261,2442,-76,0)(6014=1836,-490,2094,241,0)(6015=-1,-1,-1,-1,0)(6003=-1,-1,-1,-1,0)(6000=75,104,528,436,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) - - - - - - 0 - 1 - _tx_thread_current_ptr - - - 1 - 1 - thread_0_counter - - - 2 - 1 - thread_1_counter - - - 3 - 1 - thread_2_counter - - - 4 - 1 - thread_3_counter - - - 5 - 1 - thread_4_counter - - - 6 - 1 - thread_5_counter - - - 7 - 1 - thread_6_counter - - - 8 - 1 - thread_7_counter - - - 9 - 1 - _tx_timer_system_clock - - - - - 1 - 2 - 0x2003ffd8 - 0 - - - - - 2 - 2 - 0xE000ED28 - 0 - - - - 0 - - - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - - - Secure Code - 1 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - ..\..\src\tx_thread_secure_stack.c - tx_thread_secure_stack.c - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - .\main_s.c - main_s.c - 0 - 0 - - - - - Interface - 1 - 0 - 0 - 0 - - 2 - 3 - 1 - 0 - 0 - 0 - .\interface.c - interface.c - 0 - 0 - - - - - ::CMSIS - 0 - 0 - 0 - 1 - - - - ::Device - 1 - 0 - 0 - 1 - - -
diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/demo_secure_zone.uvprojx b/ports/cortex_m23/ac5/example_build/demo_secure_zone/demo_secure_zone.uvprojx deleted file mode 100644 index 9b49855d..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/demo_secure_zone.uvprojx +++ /dev/null @@ -1,521 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - FVP Simulation Model - 0x4 - ARM-ADS - 6140000::V6.14::ARMCLANG - 1 - - - ARMCM23_TZ - ARM - ARM.CMSIS.5.7.0 - http://www.keil.com/pack/ - IRAM(0x20000000,0x00020000) IRAM2(0x20200000,0x00020000) IROM(0x00000000,0x00200000) IROM2(0x00200000,0x00200000) CPUTYPE("Cortex-M23") TZ CLOCK(12000000) ESEL ELITTLE - - - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - 0 - $$Device:ARMCM23_TZ$Device\ARM\ARMCM23\Include\ARMCM23_TZ.h - - - - - - - - - - - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\Objects\ - demo_secure_zone - 1 - 0 - 0 - 1 - 1 - .\Listings\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - - - - - SARMV8M.DLL - -MPU - TCM.DLL - -pCM23 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 0 - 4101 - - 1 - BIN\UL2V8M.DLL - "" () - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M23" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 8 - 1 - 1 - 0 - 1 - 4 - 4 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 1 - 0x0 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x200000 - - - 1 - 0x200000 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 0 - 0x20200000 - 0x20000 - - - - - - 1 - 7 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 0 - 0 - 0 - 0 - 3 - 3 - 1 - 1 - 0 - 0 - 0 - - - - - ..\..\..\..\..\common\inc, ..\..\inc - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - .\RTE\Device\ARMCM23_TZ\ARMCM23_ac6.sct - - - - - - - - - - - Secure Code - - - tx_thread_secure_stack.c - 1 - ..\..\src\tx_thread_secure_stack.c - - - main_s.c - 1 - .\main_s.c - - - - - Interface - - - interface.c - 1 - .\interface.c - - - - - ::CMSIS - - - ::Device - - - - - - - - - - - - - - - - - - - - - - - - RTE\CMSIS\RTX_Config.c - - - - - - RTE\Device\ARMCM23_TZ\ARMCM23_ac6.sct - - - - - - - - RTE\Device\ARMCM23_TZ\partition_ARMCM23.h - - - - - - - - RTE\Device\ARMCM23_TZ\startup_ARMCM23.c - - - - - - - - RTE\Device\ARMCM23_TZ\system_ARMCM23.c - - - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_ac6.sct - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\partition_ARMCM33.h - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.c - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\system_ARMCM33.c - - - - - - - - - - - <Project Info> - - - - - - 0 - 1 - - - - -
diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/interface.c b/ports/cortex_m23/ac5/example_build/demo_secure_zone/interface.c deleted file mode 100644 index 4e6e8eee..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/interface.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * interface.c Secure/non-secure callable application code - * - * Version 1.0 - * Initial Release - *---------------------------------------------------------------------------*/ - - -#include // CMSE definitions -#include "interface.h" // Header file with secure interface API - -/* typedef for non-secure callback functions */ -typedef funcptr funcptr_NS __attribute__((cmse_nonsecure_call)); - -/* Non-secure callable (entry) function */ -int func1(int x) __attribute__((cmse_nonsecure_entry)) { - return x+3; -} - -/* Non-secure callable (entry) function, calling a non-secure callback function */ -int func2(funcptr callback, int x) __attribute__((cmse_nonsecure_entry)) { - funcptr_NS callback_NS; // non-secure callback function pointer - int y; - - /* return function pointer with cleared LSB */ - callback_NS = (funcptr_NS)cmse_nsfptr_create(callback); - - y = callback_NS (x+1); - - return (y+2); -} diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/interface.h b/ports/cortex_m23/ac5/example_build/demo_secure_zone/interface.h deleted file mode 100644 index 8215d5a3..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/interface.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * interface.h API definition for the non-secure state - * - * Version 1.0 - * Initial Release - *---------------------------------------------------------------------------*/ - -/* Function pointer declaration */ -typedef int (*funcptr)(int); - -/* Non-secure callable functions */ -extern int func1(int x); -extern int func2(funcptr callback, int x); diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/main_ns.c b/ports/cortex_m23/ac5/example_build/demo_secure_zone/main_ns.c deleted file mode 100644 index 5d16e1bb..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/main_ns.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * main_ns.c Non-secure main function - RTOS demo - * - * Version 1.0 - * Initial Release - *---------------------------------------------------------------------------*/ - -#include "interface.h" // Interface API -//#include "cmsis_os2.h" // ARM::CMSIS:RTOS2:Keil RTX5 - -//static osStatus_t Status; - -//static osThreadId_t ThreadA_Id; -//static osThreadId_t ThreadB_Id; -//static osThreadId_t ThreadC_Id; - -void ThreadA (void *argument); -void ThreadB (void *argument); -void ThreadC (void *argument); - - -extern volatile int counterA; -extern volatile int counterB; -extern volatile int counterC; - -volatile int counterA; -volatile int counterB; -volatile int counterC; - -/* -static int callbackA (int val) { - return (val); -} - -__attribute__((noreturn)) -void ThreadA (void *argument) { - (void)argument; - - for (;;) { - counterA = func1 (counterA); - counterA = func2 (callbackA, counterA); - osDelay(2U); - } -} - -static int callbackB (int val) { - uint32_t flags; - - flags = osThreadFlagsWait (1U, osFlagsWaitAny, osWaitForever); - if (flags == 1U) { - return (val+1); - } else { - return (0); - } -} - - -__attribute__((noreturn)) -void ThreadB (void *argument) { - (void)argument; - - for (;;) { - counterB = func1 (counterB); - counterB = func2 (callbackB, counterB); - } -} - -__attribute__((noreturn)) -void ThreadC (void *argument) { - (void)argument; - - for (;;) { - counterC = counterC + 1; - if ((counterC % 0x10) == 0) { - osThreadFlagsSet (ThreadB_Id, 1); - } - osDelay(1U); - } -} - -static const osThreadAttr_t ThreadAttr = { - .tz_module = 1U, // indicate calls to secure mode -}; -*/ -#if 1 -int main (void) { - - for (;;); -} -#endif diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/main_s.c b/ports/cortex_m23/ac5/example_build/demo_secure_zone/main_s.c deleted file mode 100644 index 2c667821..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/main_s.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * $Date: 15. October 2016 - * $Revision: 1.1.0 - * - * Project: TrustZone for ARMv8-M - * Title: Code template for secure main function - * - *---------------------------------------------------------------------------*/ - -/* Use CMSE intrinsics */ -#include - #include -#include "RTE_Components.h" -#include CMSIS_device_header - -/* TZ_START_NS: Start address of non-secure application */ -#ifndef TZ_START_NS -#define TZ_START_NS (0x200000U) -#endif - -/* typedef for non-secure callback functions */ -typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call)); - -/* Secure main() */ -int main(void) { - funcptr_void NonSecure_ResetHandler; - - /* Add user setup code for secure part here*/ - - /* Set non-secure main stack (MSP_NS) */ - __TZ_set_MSP_NS(*((uint32_t *)(TZ_START_NS))); - - /* Get non-secure reset handler */ - NonSecure_ResetHandler = (funcptr_void)(*((uint32_t *)((TZ_START_NS) + 4U))); - - /* Start non-secure state software application */ - NonSecure_ResetHandler(); - - /* Non-secure software does not return, this code is not executed */ - while (1) { - __NOP(); - } -} diff --git a/ports/cortex_m23/ac5/example_build/demo_secure_zone/tz_context.c b/ports/cortex_m23/ac5/example_build/demo_secure_zone/tz_context.c deleted file mode 100644 index f3152890..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_secure_zone/tz_context.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2015-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------------- - * - * $Date: 15. October 2016 - * $Revision: 1.1.0 - * - * Project: TrustZone for ARMv8-M - * Title: Context Management for ARMv8-M TrustZone - Sample implementation - * - *---------------------------------------------------------------------------*/ - -#include "RTE_Components.h" -#include CMSIS_device_header -#include "tz_context.h" - -/// Number of process slots (threads may call secure library code) -#ifndef TZ_PROCESS_STACK_SLOTS -#define TZ_PROCESS_STACK_SLOTS 8U -#endif - -/// Stack size of the secure library code -#ifndef TZ_PROCESS_STACK_SIZE -#define TZ_PROCESS_STACK_SIZE 256U -#endif - -typedef struct { - uint32_t sp_top; // stack space top - uint32_t sp_limit; // stack space limit - uint32_t sp; // current stack pointer -} stack_info_t; - -static stack_info_t ProcessStackInfo [TZ_PROCESS_STACK_SLOTS]; -static uint64_t ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U]; -static uint32_t ProcessStackFreeSlot = 0xFFFFFFFFU; - - -/// Initialize secure context memory system -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_InitContextSystem_S (void) { - uint32_t n; - - if (__get_IPSR() == 0U) { - return 0U; // Thread Mode - } - - for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) { - ProcessStackInfo[n].sp = 0U; - ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n]; - ProcessStackInfo[n].sp_top = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE; - *((uint32_t *)ProcessStackMemory[n]) = n + 1U; - } - *((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU; - - ProcessStackFreeSlot = 0U; - - // Default process stack pointer and stack limit - __set_PSPLIM((uint32_t)ProcessStackMemory); - __set_PSP ((uint32_t)ProcessStackMemory); - - // Privileged Thread Mode using PSP - __set_CONTROL(0x02U); - - return 1U; // Success -} - - -/// Allocate context memory for calling secure software modules in TrustZone -/// \param[in] module identifies software modules called from non-secure mode -/// \return value != 0 id TrustZone memory slot identifier -/// \return value 0 no memory available or internal error -__attribute__((cmse_nonsecure_entry)) -TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) { - uint32_t slot; - - (void)module; // Ignore (fixed Stack size) - - if (__get_IPSR() == 0U) { - return 0U; // Thread Mode - } - - if (ProcessStackFreeSlot == 0xFFFFFFFFU) { - return 0U; // No slot available - } - - slot = ProcessStackFreeSlot; - ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]); - - ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top; - - return (slot + 1U); -} - - -/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S -/// \param[in] id TrustZone memory slot identifier -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) { - uint32_t slot; - - if (__get_IPSR() == 0U) { - return 0U; // Thread Mode - } - - if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { - return 0U; // Invalid ID - } - - slot = id - 1U; - - if (ProcessStackInfo[slot].sp == 0U) { - return 0U; // Inactive slot - } - ProcessStackInfo[slot].sp = 0U; - - *((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot; - ProcessStackFreeSlot = slot; - - return 1U; // Success -} - - -/// Load secure context (called on RTOS thread context switch) -/// \param[in] id TrustZone memory slot identifier -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) { - uint32_t slot; - - if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { - return 0U; // Thread Mode or using Main Stack for threads - } - - if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { - return 0U; // Invalid ID - } - - slot = id - 1U; - - if (ProcessStackInfo[slot].sp == 0U) { - return 0U; // Inactive slot - } - - // Setup process stack pointer and stack limit - __set_PSPLIM(ProcessStackInfo[slot].sp_limit); - __set_PSP (ProcessStackInfo[slot].sp); - - return 1U; // Success -} - - -/// Store secure context (called on RTOS thread context switch) -/// \param[in] id TrustZone memory slot identifier -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) { - uint32_t slot; - uint32_t sp; - - if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { - return 0U; // Thread Mode or using Main Stack for threads - } - - if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { - return 0U; // Invalid ID - } - - slot = id - 1U; - - if (ProcessStackInfo[slot].sp == 0U) { - return 0U; // Inactive slot - } - - sp = __get_PSP(); - if ((sp < ProcessStackInfo[slot].sp_limit) || - (sp > ProcessStackInfo[slot].sp_top)) { - return 0U; // SP out of range - } - ProcessStackInfo[slot].sp = sp; - - // Default process stack pointer and stack limit - __set_PSPLIM((uint32_t)ProcessStackMemory); - __set_PSP ((uint32_t)ProcessStackMemory); - - return 1U; // Success -} diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.c b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.c deleted file mode 100644 index e4871014..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2013-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * - * $Revision: V5.1.0 - * - * Project: CMSIS-RTOS RTX - * Title: RTX Configuration - * - * ----------------------------------------------------------------------------- - */ - -#include "cmsis_compiler.h" -#include "rtx_os.h" - -// OS Idle Thread -__WEAK __NO_RETURN void osRtxIdleThread (void *argument) { - (void)argument; - - for (;;) {} -} - -// OS Error Callback function -__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) { - (void)object_id; - - switch (code) { - case osRtxErrorStackUnderflow: - // Stack overflow detected for thread (thread_id=object_id) - break; - case osRtxErrorISRQueueOverflow: - // ISR Queue overflow detected when inserting object (object_id) - break; - case osRtxErrorTimerQueueOverflow: - // User Timer Callback Queue overflow detected for timer (timer_id=object_id) - break; - case osRtxErrorClibSpace: - // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM - break; - case osRtxErrorClibMutex: - // Standard C/C++ library mutex initialization failed - break; - default: - // Reserved - break; - } - for (;;) {} -//return 0U; -} diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.h b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.h deleted file mode 100644 index 3021efbc..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.h +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (c) 2013-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * - * $Revision: V5.5.0 - * - * Project: CMSIS-RTOS RTX - * Title: RTX Configuration definitions - * - * ----------------------------------------------------------------------------- - */ - -#ifndef RTX_CONFIG_H_ -#define RTX_CONFIG_H_ - -#ifdef _RTE_ -#include "RTE_Components.h" -#ifdef RTE_RTX_CONFIG_H -#include RTE_RTX_CONFIG_H -#endif -#endif - -//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- - -// System Configuration -// ======================= - -// Global Dynamic Memory size [bytes] <0-1073741824:8> -// Defines the combined global dynamic memory size. -// Default: 4096 -#ifndef OS_DYNAMIC_MEM_SIZE -#define OS_DYNAMIC_MEM_SIZE 4096 -#endif - -// Kernel Tick Frequency [Hz] <1-1000000> -// Defines base time unit for delays and timeouts. -// Default: 1000 (1ms tick) -#ifndef OS_TICK_FREQ -#define OS_TICK_FREQ 1000 -#endif - -// Round-Robin Thread switching -// Enables Round-Robin Thread switching. -#ifndef OS_ROBIN_ENABLE -#define OS_ROBIN_ENABLE 1 -#endif - -// Round-Robin Timeout <1-1000> -// Defines how many ticks a thread will execute before a thread switch. -// Default: 5 -#ifndef OS_ROBIN_TIMEOUT -#define OS_ROBIN_TIMEOUT 5 -#endif - -// - -// ISR FIFO Queue -// <4=> 4 entries <8=> 8 entries <12=> 12 entries <16=> 16 entries -// <24=> 24 entries <32=> 32 entries <48=> 48 entries <64=> 64 entries -// <96=> 96 entries <128=> 128 entries <196=> 196 entries <256=> 256 entries -// RTOS Functions called from ISR store requests to this buffer. -// Default: 16 entries -#ifndef OS_ISR_FIFO_QUEUE -#define OS_ISR_FIFO_QUEUE 16 -#endif - -// Object Memory usage counters -// Enables object memory usage counters (requires RTX source variant). -#ifndef OS_OBJ_MEM_USAGE -#define OS_OBJ_MEM_USAGE 0 -#endif - -// - -// Thread Configuration -// ======================= - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_THREAD_OBJ_MEM -#define OS_THREAD_OBJ_MEM 0 -#endif - -// Number of user Threads <1-1000> -// Defines maximum number of user threads that can be active at the same time. -// Applies to user threads with system provided memory for control blocks. -#ifndef OS_THREAD_NUM -#define OS_THREAD_NUM 1 -#endif - -// Number of user Threads with default Stack size <0-1000> -// Defines maximum number of user threads with default stack size. -// Applies to user threads with zero stack size specified. -#ifndef OS_THREAD_DEF_STACK_NUM -#define OS_THREAD_DEF_STACK_NUM 0 -#endif - -// Total Stack size [bytes] for user Threads with user-provided Stack size <0-1073741824:8> -// Defines the combined stack size for user threads with user-provided stack size. -// Applies to user threads with user-provided stack size and system provided memory for stack. -// Default: 0 -#ifndef OS_THREAD_USER_STACK_SIZE -#define OS_THREAD_USER_STACK_SIZE 0 -#endif - -// - -// Default Thread Stack size [bytes] <96-1073741824:8> -// Defines stack size for threads with zero stack size specified. -// Default: 256 -#ifndef OS_STACK_SIZE -#define OS_STACK_SIZE 256 -#endif - -// Idle Thread Stack size [bytes] <72-1073741824:8> -// Defines stack size for Idle thread. -// Default: 256 -#ifndef OS_IDLE_THREAD_STACK_SIZE -#define OS_IDLE_THREAD_STACK_SIZE 256 -#endif - -// Idle Thread TrustZone Module Identifier -// Defines TrustZone Thread Context Management Identifier. -// Applies only to cores with TrustZone technology. -// Default: 0 (not used) -#ifndef OS_IDLE_THREAD_TZ_MOD_ID -#define OS_IDLE_THREAD_TZ_MOD_ID 0 -#endif - -// Stack overrun checking -// Enables stack overrun check at thread switch. -// Enabling this option increases slightly the execution time of a thread switch. -#ifndef OS_STACK_CHECK -#define OS_STACK_CHECK 1 -#endif - -// Stack usage watermark -// Initializes thread stack with watermark pattern for analyzing stack usage. -// Enabling this option increases significantly the execution time of thread creation. -#ifndef OS_STACK_WATERMARK -#define OS_STACK_WATERMARK 0 -#endif - -// Processor mode for Thread execution -// <0=> Unprivileged mode -// <1=> Privileged mode -// Default: Privileged mode -#ifndef OS_PRIVILEGE_MODE -#define OS_PRIVILEGE_MODE 1 -#endif - -// - -// Timer Configuration -// ====================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_TIMER_OBJ_MEM -#define OS_TIMER_OBJ_MEM 0 -#endif - -// Number of Timer objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_TIMER_NUM -#define OS_TIMER_NUM 1 -#endif - -// - -// Timer Thread Priority -// <8=> Low -// <16=> Below Normal <24=> Normal <32=> Above Normal -// <40=> High -// <48=> Realtime -// Defines priority for timer thread -// Default: High -#ifndef OS_TIMER_THREAD_PRIO -#define OS_TIMER_THREAD_PRIO 40 -#endif - -// Timer Thread Stack size [bytes] <0-1073741824:8> -// Defines stack size for Timer thread. -// May be set to 0 when timers are not used. -// Default: 256 -#ifndef OS_TIMER_THREAD_STACK_SIZE -#define OS_TIMER_THREAD_STACK_SIZE 256 -#endif - -// Timer Thread TrustZone Module Identifier -// Defines TrustZone Thread Context Management Identifier. -// Applies only to cores with TrustZone technology. -// Default: 0 (not used) -#ifndef OS_TIMER_THREAD_TZ_MOD_ID -#define OS_TIMER_THREAD_TZ_MOD_ID 0 -#endif - -// Timer Callback Queue entries <0-256> -// Number of concurrent active timer callback functions. -// May be set to 0 when timers are not used. -// Default: 4 -#ifndef OS_TIMER_CB_QUEUE -#define OS_TIMER_CB_QUEUE 4 -#endif - -// - -// Event Flags Configuration -// ============================ - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_EVFLAGS_OBJ_MEM -#define OS_EVFLAGS_OBJ_MEM 0 -#endif - -// Number of Event Flags objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_EVFLAGS_NUM -#define OS_EVFLAGS_NUM 1 -#endif - -// - -// - -// Mutex Configuration -// ====================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_MUTEX_OBJ_MEM -#define OS_MUTEX_OBJ_MEM 0 -#endif - -// Number of Mutex objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_MUTEX_NUM -#define OS_MUTEX_NUM 1 -#endif - -// - -// - -// Semaphore Configuration -// ========================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_SEMAPHORE_OBJ_MEM -#define OS_SEMAPHORE_OBJ_MEM 0 -#endif - -// Number of Semaphore objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_SEMAPHORE_NUM -#define OS_SEMAPHORE_NUM 1 -#endif - -// - -// - -// Memory Pool Configuration -// ============================ - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_MEMPOOL_OBJ_MEM -#define OS_MEMPOOL_OBJ_MEM 0 -#endif - -// Number of Memory Pool objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_MEMPOOL_NUM -#define OS_MEMPOOL_NUM 1 -#endif - -// Data Storage Memory size [bytes] <0-1073741824:8> -// Defines the combined data storage memory size. -// Applies to objects with system provided memory for data storage. -// Default: 0 -#ifndef OS_MEMPOOL_DATA_SIZE -#define OS_MEMPOOL_DATA_SIZE 0 -#endif - -// - -// - -// Message Queue Configuration -// ============================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_MSGQUEUE_OBJ_MEM -#define OS_MSGQUEUE_OBJ_MEM 0 -#endif - -// Number of Message Queue objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_MSGQUEUE_NUM -#define OS_MSGQUEUE_NUM 1 -#endif - -// Data Storage Memory size [bytes] <0-1073741824:8> -// Defines the combined data storage memory size. -// Applies to objects with system provided memory for data storage. -// Default: 0 -#ifndef OS_MSGQUEUE_DATA_SIZE -#define OS_MSGQUEUE_DATA_SIZE 0 -#endif - -// - -// - -// Event Recorder Configuration -// =============================== - -// Global Initialization -// Initialize Event Recorder during 'osKernelInitialize'. -#ifndef OS_EVR_INIT -#define OS_EVR_INIT 0 -#endif - -// Start recording -// Start event recording after initialization. -#ifndef OS_EVR_START -#define OS_EVR_START 1 -#endif - -// Global Event Filter Setup -// Initial recording level applied to all components. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_LEVEL -#define OS_EVR_LEVEL 0x00U -#endif - -// RTOS Event Filter Setup -// Recording levels for RTX components. -// Only applicable if events for the respective component are generated. - -// Memory Management -// Recording level for Memory Management events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MEMORY_LEVEL -#define OS_EVR_MEMORY_LEVEL 0x01U -#endif - -// Kernel -// Recording level for Kernel events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_KERNEL_LEVEL -#define OS_EVR_KERNEL_LEVEL 0x01U -#endif - -// Thread -// Recording level for Thread events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_THREAD_LEVEL -#define OS_EVR_THREAD_LEVEL 0x05U -#endif - -// Generic Wait -// Recording level for Generic Wait events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_WAIT_LEVEL -#define OS_EVR_WAIT_LEVEL 0x01U -#endif - -// Thread Flags -// Recording level for Thread Flags events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_THFLAGS_LEVEL -#define OS_EVR_THFLAGS_LEVEL 0x01U -#endif - -// Event Flags -// Recording level for Event Flags events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_EVFLAGS_LEVEL -#define OS_EVR_EVFLAGS_LEVEL 0x01U -#endif - -// Timer -// Recording level for Timer events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_TIMER_LEVEL -#define OS_EVR_TIMER_LEVEL 0x01U -#endif - -// Mutex -// Recording level for Mutex events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MUTEX_LEVEL -#define OS_EVR_MUTEX_LEVEL 0x01U -#endif - -// Semaphore -// Recording level for Semaphore events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_SEMAPHORE_LEVEL -#define OS_EVR_SEMAPHORE_LEVEL 0x01U -#endif - -// Memory Pool -// Recording level for Memory Pool events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MEMPOOL_LEVEL -#define OS_EVR_MEMPOOL_LEVEL 0x01U -#endif - -// Message Queue -// Recording level for Message Queue events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MSGQUEUE_LEVEL -#define OS_EVR_MSGQUEUE_LEVEL 0x01U -#endif - -// - -// - -// RTOS Event Generation -// Enables event generation for RTX components (requires RTX source variant). - -// Memory Management -// Enables Memory Management event generation. -#ifndef OS_EVR_MEMORY -#define OS_EVR_MEMORY 1 -#endif - -// Kernel -// Enables Kernel event generation. -#ifndef OS_EVR_KERNEL -#define OS_EVR_KERNEL 1 -#endif - -// Thread -// Enables Thread event generation. -#ifndef OS_EVR_THREAD -#define OS_EVR_THREAD 1 -#endif - -// Generic Wait -// Enables Generic Wait event generation. -#ifndef OS_EVR_WAIT -#define OS_EVR_WAIT 1 -#endif - -// Thread Flags -// Enables Thread Flags event generation. -#ifndef OS_EVR_THFLAGS -#define OS_EVR_THFLAGS 1 -#endif - -// Event Flags -// Enables Event Flags event generation. -#ifndef OS_EVR_EVFLAGS -#define OS_EVR_EVFLAGS 1 -#endif - -// Timer -// Enables Timer event generation. -#ifndef OS_EVR_TIMER -#define OS_EVR_TIMER 1 -#endif - -// Mutex -// Enables Mutex event generation. -#ifndef OS_EVR_MUTEX -#define OS_EVR_MUTEX 1 -#endif - -// Semaphore -// Enables Semaphore event generation. -#ifndef OS_EVR_SEMAPHORE -#define OS_EVR_SEMAPHORE 1 -#endif - -// Memory Pool -// Enables Memory Pool event generation. -#ifndef OS_EVR_MEMPOOL -#define OS_EVR_MEMPOOL 1 -#endif - -// Message Queue -// Enables Message Queue event generation. -#ifndef OS_EVR_MSGQUEUE -#define OS_EVR_MSGQUEUE 1 -#endif - -// - -// - -// Number of Threads which use standard C/C++ library libspace -// (when thread specific memory allocation is not used). -#if (OS_THREAD_OBJ_MEM == 0) -#define OS_THREAD_LIBSPACE_NUM 4 -#else -#define OS_THREAD_LIBSPACE_NUM OS_THREAD_NUM -#endif - -//------------- <<< end of configuration section >>> --------------------------- - -#endif // RTX_CONFIG_H_ diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct deleted file mode 100644 index 7b796b29..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct +++ /dev/null @@ -1,74 +0,0 @@ -#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m23 -xc -; command above MUST be in first line (no comment above!) - -/* -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------- -*/ - -/*--------------------- Flash Configuration ---------------------------------- -; Flash Configuration -; Flash Base Address <0x0-0xFFFFFFFF:8> -; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __ROM_BASE 0x00200000 -#define __ROM_SIZE 0x00080000 - -/*--------------------- Embedded RAM Configuration --------------------------- -; RAM Configuration -; RAM Base Address <0x0-0xFFFFFFFF:8> -; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __RAM_BASE 0x20200000 -#define __RAM_SIZE 0x00040000 - -/*--------------------- Stack / Heap Configuration --------------------------- -; Stack / Heap Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __STACK_SIZE 0x00000200 -#define __HEAP_SIZE 0x00000C00 - - -/*---------------------------------------------------------------------------- - User Stack & Heap boundery definition - *----------------------------------------------------------------------------*/ -#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ -#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ - - -/*---------------------------------------------------------------------------- - Scatter File Definitions definition - *----------------------------------------------------------------------------*/ -#define __RO_BASE __ROM_BASE -#define __RO_SIZE __ROM_SIZE - -#define __RW_BASE (__RAM_BASE ) -#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) - - - -LR_ROM __RO_BASE __RO_SIZE { ; load region size_region - ER_ROM __RO_BASE __RO_SIZE { ; load address = execution address - *.o (RESET, +First) - *(InRoot$$Sections) -; *(Veneer$$CMSE) ; uncomment for secure applications - .ANY (+RO) - .ANY (+XO) - } - - RW_RAM __RW_BASE __RW_SIZE { ; RW data - .ANY (+RW +ZI) - } - -#if __HEAP_SIZE > 0 - ARM_LIB_HEAP __HEAP_BASE EMPTY __HEAP_SIZE { ; Reserve empty region for heap - } -#endif - - ARM_LIB_STACK __STACK_TOP EMPTY -__STACK_SIZE { ; Reserve empty region for stack - } -} diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h deleted file mode 100644 index a7a090e7..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h +++ /dev/null @@ -1,832 +0,0 @@ -/**************************************************************************//** - * @file partition_ARMCM23.h - * @brief CMSIS-CORE Initial Setup for Secure / Non-Secure Zones for ARMCM23 - * @version V5.3.1 - * @date 09. July 2018 - ******************************************************************************/ -/* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PARTITION_ARMCM23_H -#define PARTITION_ARMCM23_H - -/* -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -*/ - -/* -// Initialize Security Attribution Unit (SAU) CTRL register -*/ -#define SAU_INIT_CTRL 1 - -/* -// Enable SAU -// Value for SAU->CTRL register bit ENABLE -*/ -#define SAU_INIT_CTRL_ENABLE 1 - -/* -// When SAU is disabled -// <0=> All Memory is Secure -// <1=> All Memory is Non-Secure -// Value for SAU->CTRL register bit ALLNS -// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. -*/ -#define SAU_INIT_CTRL_ALLNS 0 - -/* -// -*/ - -/* -// Initialize Security Attribution Unit (SAU) Address Regions -// SAU configuration specifies regions to be one of: -// - Secure and Non-Secure Callable -// - Non-Secure -// Note: All memory regions not configured by SAU are Secure -*/ -#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ - -/* -// Initialize SAU Region 0 -// Setup SAU Region 0 memory attributes -*/ -#define SAU_INIT_REGION0 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START0 0x00000000 /* start address of SAU region 0 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END0 0x001FFFFF /* end address of SAU region 0 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC0 1 -/* -// -*/ - -/* -// Initialize SAU Region 1 -// Setup SAU Region 1 memory attributes -*/ -#define SAU_INIT_REGION1 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START1 0x00200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END1 0x003FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC1 0 -/* -// -*/ - -/* -// Initialize SAU Region 2 -// Setup SAU Region 2 memory attributes -*/ -#define SAU_INIT_REGION2 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START2 0x20200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END2 0x203FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC2 0 -/* -// -*/ - -/* -// Initialize SAU Region 3 -// Setup SAU Region 3 memory attributes -*/ -#define SAU_INIT_REGION3 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START3 0x40000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END3 0x40040000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC3 0 -/* -// -*/ - -/* -// Initialize SAU Region 4 -// Setup SAU Region 4 memory attributes -*/ -#define SAU_INIT_REGION4 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START4 0x00000000 /* start address of SAU region 4 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END4 0x00000000 /* end address of SAU region 4 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC4 0 -/* -// -*/ - -/* -// Initialize SAU Region 5 -// Setup SAU Region 5 memory attributes -*/ -#define SAU_INIT_REGION5 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START5 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END5 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC5 0 -/* -// -*/ - -/* -// Initialize SAU Region 6 -// Setup SAU Region 6 memory attributes -*/ -#define SAU_INIT_REGION6 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START6 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END6 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC6 0 -/* -// -*/ - -/* -// Initialize SAU Region 7 -// Setup SAU Region 7 memory attributes -*/ -#define SAU_INIT_REGION7 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START7 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END7 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC7 0 -/* -// -*/ - -/* -// -*/ - -/* -// Setup behaviour of Sleep and Exception Handling -*/ -#define SCB_CSR_AIRCR_INIT 1 - -/* -// Deep Sleep can be enabled by -// <0=>Secure and Non-Secure state -// <1=>Secure state only -// Value for SCB->CSR register bit DEEPSLEEPS -*/ -#define SCB_CSR_DEEPSLEEPS_VAL 1 - -/* -// System reset request accessible from -// <0=> Secure and Non-Secure state -// <1=> Secure state only -// Value for SCB->AIRCR register bit SYSRESETREQS -*/ -#define SCB_AIRCR_SYSRESETREQS_VAL 1 - -/* -// Priority of Non-Secure exceptions is -// <0=> Not altered -// <1=> Lowered to 0x80-0xFF -// Value for SCB->AIRCR register bit PRIS -*/ -#define SCB_AIRCR_PRIS_VAL 1 - -/* -// BusFault, HardFault, and NMI target -// <0=> Secure state -// <1=> Non-Secure state -// Value for SCB->AIRCR register bit BFHFNMINS -*/ -#define SCB_AIRCR_BFHFNMINS_VAL 0 - -/* -// -*/ - - -/* -// Setup behaviour of single SysTick -*/ -#define SCB_ICSR_INIT 0 - -/* -// in a single SysTick implementation, SysTick is -// <0=>Secure -// <1=>Non-Secure -// Value for SCB->ICSR register bit STTNS -// only for single SysTick implementation -*/ -#define SCB_ICSR_STTNS_VAL 0 - -/* -// -*/ - - -/* -// Setup Interrupt Target -*/ - -/* -// Initialize ITNS 0 (Interrupts 0..31) -*/ -#define NVIC_INIT_ITNS0 1 - -/* -// Interrupts 0..31 -// Interrupt 0 <0=> Secure state <1=> Non-Secure state -// Interrupt 1 <0=> Secure state <1=> Non-Secure state -// Interrupt 2 <0=> Secure state <1=> Non-Secure state -// Interrupt 3 <0=> Secure state <1=> Non-Secure state -// Interrupt 4 <0=> Secure state <1=> Non-Secure state -// Interrupt 5 <0=> Secure state <1=> Non-Secure state -// Interrupt 6 <0=> Secure state <1=> Non-Secure state -// Interrupt 7 <0=> Secure state <1=> Non-Secure state -// Interrupt 8 <0=> Secure state <1=> Non-Secure state -// Interrupt 9 <0=> Secure state <1=> Non-Secure state -// Interrupt 10 <0=> Secure state <1=> Non-Secure state -// Interrupt 11 <0=> Secure state <1=> Non-Secure state -// Interrupt 12 <0=> Secure state <1=> Non-Secure state -// Interrupt 13 <0=> Secure state <1=> Non-Secure state -// Interrupt 14 <0=> Secure state <1=> Non-Secure state -// Interrupt 15 <0=> Secure state <1=> Non-Secure state -// Interrupt 16 <0=> Secure state <1=> Non-Secure state -// Interrupt 17 <0=> Secure state <1=> Non-Secure state -// Interrupt 18 <0=> Secure state <1=> Non-Secure state -// Interrupt 19 <0=> Secure state <1=> Non-Secure state -// Interrupt 20 <0=> Secure state <1=> Non-Secure state -// Interrupt 21 <0=> Secure state <1=> Non-Secure state -// Interrupt 22 <0=> Secure state <1=> Non-Secure state -// Interrupt 23 <0=> Secure state <1=> Non-Secure state -// Interrupt 24 <0=> Secure state <1=> Non-Secure state -// Interrupt 25 <0=> Secure state <1=> Non-Secure state -// Interrupt 26 <0=> Secure state <1=> Non-Secure state -// Interrupt 27 <0=> Secure state <1=> Non-Secure state -// Interrupt 28 <0=> Secure state <1=> Non-Secure state -// Interrupt 29 <0=> Secure state <1=> Non-Secure state -// Interrupt 30 <0=> Secure state <1=> Non-Secure state -// Interrupt 31 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS0_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 1 (Interrupts 32..63) -*/ -#define NVIC_INIT_ITNS1 1 - -/* -// Interrupts 32..63 -// Interrupt 32 <0=> Secure state <1=> Non-Secure state -// Interrupt 33 <0=> Secure state <1=> Non-Secure state -// Interrupt 34 <0=> Secure state <1=> Non-Secure state -// Interrupt 35 <0=> Secure state <1=> Non-Secure state -// Interrupt 36 <0=> Secure state <1=> Non-Secure state -// Interrupt 37 <0=> Secure state <1=> Non-Secure state -// Interrupt 38 <0=> Secure state <1=> Non-Secure state -// Interrupt 39 <0=> Secure state <1=> Non-Secure state -// Interrupt 40 <0=> Secure state <1=> Non-Secure state -// Interrupt 41 <0=> Secure state <1=> Non-Secure state -// Interrupt 42 <0=> Secure state <1=> Non-Secure state -// Interrupt 43 <0=> Secure state <1=> Non-Secure state -// Interrupt 44 <0=> Secure state <1=> Non-Secure state -// Interrupt 45 <0=> Secure state <1=> Non-Secure state -// Interrupt 46 <0=> Secure state <1=> Non-Secure state -// Interrupt 47 <0=> Secure state <1=> Non-Secure state -// Interrupt 48 <0=> Secure state <1=> Non-Secure state -// Interrupt 49 <0=> Secure state <1=> Non-Secure state -// Interrupt 50 <0=> Secure state <1=> Non-Secure state -// Interrupt 51 <0=> Secure state <1=> Non-Secure state -// Interrupt 52 <0=> Secure state <1=> Non-Secure state -// Interrupt 53 <0=> Secure state <1=> Non-Secure state -// Interrupt 54 <0=> Secure state <1=> Non-Secure state -// Interrupt 55 <0=> Secure state <1=> Non-Secure state -// Interrupt 56 <0=> Secure state <1=> Non-Secure state -// Interrupt 57 <0=> Secure state <1=> Non-Secure state -// Interrupt 58 <0=> Secure state <1=> Non-Secure state -// Interrupt 59 <0=> Secure state <1=> Non-Secure state -// Interrupt 60 <0=> Secure state <1=> Non-Secure state -// Interrupt 61 <0=> Secure state <1=> Non-Secure state -// Interrupt 62 <0=> Secure state <1=> Non-Secure state -// Interrupt 63 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS1_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 2 (Interrupts 64..95) -*/ -#define NVIC_INIT_ITNS2 0 - -/* -// Interrupts 64..95 -// Interrupt 64 <0=> Secure state <1=> Non-Secure state -// Interrupt 65 <0=> Secure state <1=> Non-Secure state -// Interrupt 66 <0=> Secure state <1=> Non-Secure state -// Interrupt 67 <0=> Secure state <1=> Non-Secure state -// Interrupt 68 <0=> Secure state <1=> Non-Secure state -// Interrupt 69 <0=> Secure state <1=> Non-Secure state -// Interrupt 70 <0=> Secure state <1=> Non-Secure state -// Interrupt 71 <0=> Secure state <1=> Non-Secure state -// Interrupt 72 <0=> Secure state <1=> Non-Secure state -// Interrupt 73 <0=> Secure state <1=> Non-Secure state -// Interrupt 74 <0=> Secure state <1=> Non-Secure state -// Interrupt 75 <0=> Secure state <1=> Non-Secure state -// Interrupt 76 <0=> Secure state <1=> Non-Secure state -// Interrupt 77 <0=> Secure state <1=> Non-Secure state -// Interrupt 78 <0=> Secure state <1=> Non-Secure state -// Interrupt 79 <0=> Secure state <1=> Non-Secure state -// Interrupt 80 <0=> Secure state <1=> Non-Secure state -// Interrupt 81 <0=> Secure state <1=> Non-Secure state -// Interrupt 82 <0=> Secure state <1=> Non-Secure state -// Interrupt 83 <0=> Secure state <1=> Non-Secure state -// Interrupt 84 <0=> Secure state <1=> Non-Secure state -// Interrupt 85 <0=> Secure state <1=> Non-Secure state -// Interrupt 86 <0=> Secure state <1=> Non-Secure state -// Interrupt 87 <0=> Secure state <1=> Non-Secure state -// Interrupt 88 <0=> Secure state <1=> Non-Secure state -// Interrupt 89 <0=> Secure state <1=> Non-Secure state -// Interrupt 90 <0=> Secure state <1=> Non-Secure state -// Interrupt 91 <0=> Secure state <1=> Non-Secure state -// Interrupt 92 <0=> Secure state <1=> Non-Secure state -// Interrupt 93 <0=> Secure state <1=> Non-Secure state -// Interrupt 94 <0=> Secure state <1=> Non-Secure state -// Interrupt 95 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS2_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 3 (Interrupts 96..127) -*/ -#define NVIC_INIT_ITNS3 0 - -/* -// Interrupts 96..127 -// Interrupt 96 <0=> Secure state <1=> Non-Secure state -// Interrupt 97 <0=> Secure state <1=> Non-Secure state -// Interrupt 98 <0=> Secure state <1=> Non-Secure state -// Interrupt 99 <0=> Secure state <1=> Non-Secure state -// Interrupt 100 <0=> Secure state <1=> Non-Secure state -// Interrupt 101 <0=> Secure state <1=> Non-Secure state -// Interrupt 102 <0=> Secure state <1=> Non-Secure state -// Interrupt 103 <0=> Secure state <1=> Non-Secure state -// Interrupt 104 <0=> Secure state <1=> Non-Secure state -// Interrupt 105 <0=> Secure state <1=> Non-Secure state -// Interrupt 106 <0=> Secure state <1=> Non-Secure state -// Interrupt 107 <0=> Secure state <1=> Non-Secure state -// Interrupt 108 <0=> Secure state <1=> Non-Secure state -// Interrupt 109 <0=> Secure state <1=> Non-Secure state -// Interrupt 110 <0=> Secure state <1=> Non-Secure state -// Interrupt 111 <0=> Secure state <1=> Non-Secure state -// Interrupt 112 <0=> Secure state <1=> Non-Secure state -// Interrupt 113 <0=> Secure state <1=> Non-Secure state -// Interrupt 114 <0=> Secure state <1=> Non-Secure state -// Interrupt 115 <0=> Secure state <1=> Non-Secure state -// Interrupt 116 <0=> Secure state <1=> Non-Secure state -// Interrupt 117 <0=> Secure state <1=> Non-Secure state -// Interrupt 118 <0=> Secure state <1=> Non-Secure state -// Interrupt 119 <0=> Secure state <1=> Non-Secure state -// Interrupt 120 <0=> Secure state <1=> Non-Secure state -// Interrupt 121 <0=> Secure state <1=> Non-Secure state -// Interrupt 122 <0=> Secure state <1=> Non-Secure state -// Interrupt 123 <0=> Secure state <1=> Non-Secure state -// Interrupt 124 <0=> Secure state <1=> Non-Secure state -// Interrupt 125 <0=> Secure state <1=> Non-Secure state -// Interrupt 126 <0=> Secure state <1=> Non-Secure state -// Interrupt 127 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS3_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 4 (Interrupts 128..159) -*/ -#define NVIC_INIT_ITNS4 0 - -/* -// Interrupts 128..159 -// Interrupt 128 <0=> Secure state <1=> Non-Secure state -// Interrupt 129 <0=> Secure state <1=> Non-Secure state -// Interrupt 130 <0=> Secure state <1=> Non-Secure state -// Interrupt 131 <0=> Secure state <1=> Non-Secure state -// Interrupt 132 <0=> Secure state <1=> Non-Secure state -// Interrupt 133 <0=> Secure state <1=> Non-Secure state -// Interrupt 134 <0=> Secure state <1=> Non-Secure state -// Interrupt 135 <0=> Secure state <1=> Non-Secure state -// Interrupt 136 <0=> Secure state <1=> Non-Secure state -// Interrupt 137 <0=> Secure state <1=> Non-Secure state -// Interrupt 138 <0=> Secure state <1=> Non-Secure state -// Interrupt 139 <0=> Secure state <1=> Non-Secure state -// Interrupt 140 <0=> Secure state <1=> Non-Secure state -// Interrupt 141 <0=> Secure state <1=> Non-Secure state -// Interrupt 142 <0=> Secure state <1=> Non-Secure state -// Interrupt 143 <0=> Secure state <1=> Non-Secure state -// Interrupt 144 <0=> Secure state <1=> Non-Secure state -// Interrupt 145 <0=> Secure state <1=> Non-Secure state -// Interrupt 146 <0=> Secure state <1=> Non-Secure state -// Interrupt 147 <0=> Secure state <1=> Non-Secure state -// Interrupt 148 <0=> Secure state <1=> Non-Secure state -// Interrupt 149 <0=> Secure state <1=> Non-Secure state -// Interrupt 150 <0=> Secure state <1=> Non-Secure state -// Interrupt 151 <0=> Secure state <1=> Non-Secure state -// Interrupt 152 <0=> Secure state <1=> Non-Secure state -// Interrupt 153 <0=> Secure state <1=> Non-Secure state -// Interrupt 154 <0=> Secure state <1=> Non-Secure state -// Interrupt 155 <0=> Secure state <1=> Non-Secure state -// Interrupt 156 <0=> Secure state <1=> Non-Secure state -// Interrupt 157 <0=> Secure state <1=> Non-Secure state -// Interrupt 158 <0=> Secure state <1=> Non-Secure state -// Interrupt 159 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS4_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 5 (Interrupts 160..191) -*/ -#define NVIC_INIT_ITNS5 0 - -/* -// Interrupts 160..191 -// Interrupt 160 <0=> Secure state <1=> Non-Secure state -// Interrupt 161 <0=> Secure state <1=> Non-Secure state -// Interrupt 162 <0=> Secure state <1=> Non-Secure state -// Interrupt 163 <0=> Secure state <1=> Non-Secure state -// Interrupt 164 <0=> Secure state <1=> Non-Secure state -// Interrupt 165 <0=> Secure state <1=> Non-Secure state -// Interrupt 166 <0=> Secure state <1=> Non-Secure state -// Interrupt 167 <0=> Secure state <1=> Non-Secure state -// Interrupt 168 <0=> Secure state <1=> Non-Secure state -// Interrupt 169 <0=> Secure state <1=> Non-Secure state -// Interrupt 170 <0=> Secure state <1=> Non-Secure state -// Interrupt 171 <0=> Secure state <1=> Non-Secure state -// Interrupt 172 <0=> Secure state <1=> Non-Secure state -// Interrupt 173 <0=> Secure state <1=> Non-Secure state -// Interrupt 174 <0=> Secure state <1=> Non-Secure state -// Interrupt 175 <0=> Secure state <1=> Non-Secure state -// Interrupt 176 <0=> Secure state <1=> Non-Secure state -// Interrupt 177 <0=> Secure state <1=> Non-Secure state -// Interrupt 178 <0=> Secure state <1=> Non-Secure state -// Interrupt 179 <0=> Secure state <1=> Non-Secure state -// Interrupt 180 <0=> Secure state <1=> Non-Secure state -// Interrupt 181 <0=> Secure state <1=> Non-Secure state -// Interrupt 182 <0=> Secure state <1=> Non-Secure state -// Interrupt 183 <0=> Secure state <1=> Non-Secure state -// Interrupt 184 <0=> Secure state <1=> Non-Secure state -// Interrupt 185 <0=> Secure state <1=> Non-Secure state -// Interrupt 186 <0=> Secure state <1=> Non-Secure state -// Interrupt 187 <0=> Secure state <1=> Non-Secure state -// Interrupt 188 <0=> Secure state <1=> Non-Secure state -// Interrupt 189 <0=> Secure state <1=> Non-Secure state -// Interrupt 190 <0=> Secure state <1=> Non-Secure state -// Interrupt 191 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS5_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 6 (Interrupts 192..223) -*/ -#define NVIC_INIT_ITNS6 0 - -/* -// Interrupts 192..223 -// Interrupt 192 <0=> Secure state <1=> Non-Secure state -// Interrupt 193 <0=> Secure state <1=> Non-Secure state -// Interrupt 194 <0=> Secure state <1=> Non-Secure state -// Interrupt 195 <0=> Secure state <1=> Non-Secure state -// Interrupt 196 <0=> Secure state <1=> Non-Secure state -// Interrupt 197 <0=> Secure state <1=> Non-Secure state -// Interrupt 198 <0=> Secure state <1=> Non-Secure state -// Interrupt 199 <0=> Secure state <1=> Non-Secure state -// Interrupt 200 <0=> Secure state <1=> Non-Secure state -// Interrupt 201 <0=> Secure state <1=> Non-Secure state -// Interrupt 202 <0=> Secure state <1=> Non-Secure state -// Interrupt 203 <0=> Secure state <1=> Non-Secure state -// Interrupt 204 <0=> Secure state <1=> Non-Secure state -// Interrupt 205 <0=> Secure state <1=> Non-Secure state -// Interrupt 206 <0=> Secure state <1=> Non-Secure state -// Interrupt 207 <0=> Secure state <1=> Non-Secure state -// Interrupt 208 <0=> Secure state <1=> Non-Secure state -// Interrupt 209 <0=> Secure state <1=> Non-Secure state -// Interrupt 210 <0=> Secure state <1=> Non-Secure state -// Interrupt 211 <0=> Secure state <1=> Non-Secure state -// Interrupt 212 <0=> Secure state <1=> Non-Secure state -// Interrupt 213 <0=> Secure state <1=> Non-Secure state -// Interrupt 214 <0=> Secure state <1=> Non-Secure state -// Interrupt 215 <0=> Secure state <1=> Non-Secure state -// Interrupt 216 <0=> Secure state <1=> Non-Secure state -// Interrupt 217 <0=> Secure state <1=> Non-Secure state -// Interrupt 218 <0=> Secure state <1=> Non-Secure state -// Interrupt 219 <0=> Secure state <1=> Non-Secure state -// Interrupt 220 <0=> Secure state <1=> Non-Secure state -// Interrupt 221 <0=> Secure state <1=> Non-Secure state -// Interrupt 222 <0=> Secure state <1=> Non-Secure state -// Interrupt 223 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS6_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 7 (Interrupts 224..255) -*/ -#define NVIC_INIT_ITNS7 0 - -/* -// Interrupts 224..255 -// Interrupt 224 <0=> Secure state <1=> Non-Secure state -// Interrupt 225 <0=> Secure state <1=> Non-Secure state -// Interrupt 226 <0=> Secure state <1=> Non-Secure state -// Interrupt 227 <0=> Secure state <1=> Non-Secure state -// Interrupt 228 <0=> Secure state <1=> Non-Secure state -// Interrupt 229 <0=> Secure state <1=> Non-Secure state -// Interrupt 230 <0=> Secure state <1=> Non-Secure state -// Interrupt 231 <0=> Secure state <1=> Non-Secure state -// Interrupt 232 <0=> Secure state <1=> Non-Secure state -// Interrupt 233 <0=> Secure state <1=> Non-Secure state -// Interrupt 234 <0=> Secure state <1=> Non-Secure state -// Interrupt 235 <0=> Secure state <1=> Non-Secure state -// Interrupt 236 <0=> Secure state <1=> Non-Secure state -// Interrupt 237 <0=> Secure state <1=> Non-Secure state -// Interrupt 238 <0=> Secure state <1=> Non-Secure state -// Interrupt 239 <0=> Secure state <1=> Non-Secure state -// Interrupt 240 <0=> Secure state <1=> Non-Secure state -// Interrupt 241 <0=> Secure state <1=> Non-Secure state -// Interrupt 242 <0=> Secure state <1=> Non-Secure state -// Interrupt 243 <0=> Secure state <1=> Non-Secure state -// Interrupt 244 <0=> Secure state <1=> Non-Secure state -// Interrupt 245 <0=> Secure state <1=> Non-Secure state -// Interrupt 246 <0=> Secure state <1=> Non-Secure state -// Interrupt 247 <0=> Secure state <1=> Non-Secure state -// Interrupt 248 <0=> Secure state <1=> Non-Secure state -// Interrupt 249 <0=> Secure state <1=> Non-Secure state -// Interrupt 250 <0=> Secure state <1=> Non-Secure state -// Interrupt 251 <0=> Secure state <1=> Non-Secure state -// Interrupt 252 <0=> Secure state <1=> Non-Secure state -// Interrupt 253 <0=> Secure state <1=> Non-Secure state -// Interrupt 254 <0=> Secure state <1=> Non-Secure state -// Interrupt 255 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS7_VAL 0x00000000 - -/* -// -*/ - -/* -// -*/ - - - -/* - max 128 SAU regions. - SAU regions are defined in partition.h - */ - -#define SAU_INIT_REGION(n) \ - SAU->RNR = (n & SAU_RNR_REGION_Msk); \ - SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ - SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ - ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U - -/** - \brief Setup a SAU Region - \details Writes the region information contained in SAU_Region to the - registers SAU_RNR, SAU_RBAR, and SAU_RLAR - */ -__STATIC_INLINE void TZ_SAU_Setup (void) -{ - -#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) - - #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) - SAU_INIT_REGION(0); - #endif - - #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) - SAU_INIT_REGION(1); - #endif - - #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) - SAU_INIT_REGION(2); - #endif - - #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) - SAU_INIT_REGION(3); - #endif - - #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) - SAU_INIT_REGION(4); - #endif - - #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) - SAU_INIT_REGION(5); - #endif - - #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) - SAU_INIT_REGION(6); - #endif - - #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) - SAU_INIT_REGION(7); - #endif - - /* repeat this for all possible SAU regions */ - -#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ - - - #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) - SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | - ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; - #endif - - #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) - SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | - ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); - - SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | - SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk) ) | - ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | - ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | - ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | - ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); - #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ - - #if defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U) - SCB->ICSR = (SCB->ICSR & ~(SCB_ICSR_STTNS_Msk )) | - ((SCB_ICSR_STTNS_VAL << SCB_ICSR_STTNS_Pos) & SCB_ICSR_STTNS_Msk); - #endif /* defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U) */ - - #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) - NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; - #endif - - #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) - NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; - #endif - - #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) - NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; - #endif - - #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) - NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; - #endif - - #if defined (NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U) - NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL; - #endif - - #if defined (NVIC_INIT_ITNS5) && (NVIC_INIT_ITNS5 == 1U) - NVIC->ITNS[5] = NVIC_INIT_ITNS5_VAL; - #endif - - #if defined (NVIC_INIT_ITNS6) && (NVIC_INIT_ITNS6 == 1U) - NVIC->ITNS[6] = NVIC_INIT_ITNS6_VAL; - #endif - - #if defined (NVIC_INIT_ITNS7) && (NVIC_INIT_ITNS7 == 1U) - NVIC->ITNS[7] = NVIC_INIT_ITNS7_VAL; - #endif - - /* repeat this for all possible ITNS elements */ - -} - -#endif /* PARTITION_ARMCM23_H */ diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c deleted file mode 100644 index 30dc1dfd..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** - * @file startup_ARMCM23.c - * @brief CMSIS-Core(M) Device Startup File for a Cortex-M23 Device - * @version V2.0.0 - * @date 04. June 2019 - ******************************************************************************/ -/* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM23) - #include "ARMCM23.h" -#elif defined (ARMCM23_TZ) - #include "ARMCM23_TZ.h" -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler Function Prototype - *----------------------------------------------------------------------------*/ -typedef void( *pFunc )( void ); - -/*---------------------------------------------------------------------------- - External References - *----------------------------------------------------------------------------*/ -extern uint32_t __INITIAL_SP; -extern uint32_t __STACK_LIMIT; - -extern __NO_RETURN void __PROGRAM_START(void); - -/*---------------------------------------------------------------------------- - Internal References - *----------------------------------------------------------------------------*/ -void __NO_RETURN Default_Handler(void); -void __NO_RETURN Reset_Handler (void); - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler - *----------------------------------------------------------------------------*/ -/* Exceptions */ -void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - -void Interrupt0_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt1_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt2_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt3_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt4_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt5_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt6_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt7_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt8_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt9_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - - -/*---------------------------------------------------------------------------- - Exception / Interrupt Vector table - *----------------------------------------------------------------------------*/ - -#if defined ( __GNUC__ ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#endif - -extern const pFunc __VECTOR_TABLE[240]; - const pFunc __VECTOR_TABLE[240] __VECTOR_TABLE_ATTRIBUTE = { - (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ - Reset_Handler, /* Reset Handler */ - NMI_Handler, /* -14 NMI Handler */ - HardFault_Handler, /* -13 Hard Fault Handler */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - SVC_Handler, /* -5 SVCall Handler */ - 0, /* Reserved */ - 0, /* Reserved */ - PendSV_Handler, /* -2 PendSV Handler */ - SysTick_Handler, /* -1 SysTick Handler */ - - /* Interrupts */ - Interrupt0_Handler, /* 0 Interrupt 0 */ - Interrupt1_Handler, /* 1 Interrupt 1 */ - Interrupt2_Handler, /* 2 Interrupt 2 */ - Interrupt3_Handler, /* 3 Interrupt 3 */ - Interrupt4_Handler, /* 4 Interrupt 4 */ - Interrupt5_Handler, /* 5 Interrupt 5 */ - Interrupt6_Handler, /* 6 Interrupt 6 */ - Interrupt7_Handler, /* 7 Interrupt 7 */ - Interrupt8_Handler, /* 8 Interrupt 8 */ - Interrupt9_Handler /* 9 Interrupt 9 */ - /* Interrupts 10 .. 223 are left out */ -}; - -#if defined ( __GNUC__ ) -#pragma GCC diagnostic pop -#endif - -/*---------------------------------------------------------------------------- - Reset Handler called on controller reset - *----------------------------------------------------------------------------*/ -void Reset_Handler(void) -{ - __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); - - SystemInit(); /* CMSIS System Initialization */ - __PROGRAM_START(); /* Enter PreMain (C library entry point) */ -} - -/*---------------------------------------------------------------------------- - Default Handler for Exceptions / Interrupts - *----------------------------------------------------------------------------*/ -void Default_Handler(void) -{ - while(1); -} diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c deleted file mode 100644 index 61ef3fe6..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************//** - * @file system_ARMCM23.c - * @brief CMSIS Device System Source File for - * ARMCM23 Device - * @version V5.3.1 - * @date 09. July 2018 - ******************************************************************************/ -/* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM23) - #include "ARMCM23.h" -#elif defined (ARMCM23_TZ) - #include "ARMCM23_TZ.h" - - #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - #include "partition_ARMCM23.h" - #endif -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Define clocks - *----------------------------------------------------------------------------*/ -#define XTAL (50000000UL) /* Oscillator frequency */ - -#define SYSTEM_CLOCK (XTAL / 2U) - - -/*---------------------------------------------------------------------------- - Externals - *----------------------------------------------------------------------------*/ -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - extern uint32_t __VECTOR_TABLE; -#endif - -/*---------------------------------------------------------------------------- - System Core Clock Variable - *----------------------------------------------------------------------------*/ -uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Core Clock Frequency */ - - -/*---------------------------------------------------------------------------- - System Core Clock update function - *----------------------------------------------------------------------------*/ -void SystemCoreClockUpdate (void) -{ - SystemCoreClock = SYSTEM_CLOCK; -} - -/*---------------------------------------------------------------------------- - System initialization function - *----------------------------------------------------------------------------*/ -void SystemInit (void) -{ - -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - SCB->VTOR = (uint32_t) &__VECTOR_TABLE; -#endif - -#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - TZ_SAU_Setup(); -#endif - - SystemCoreClock = SYSTEM_CLOCK; -} diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h deleted file mode 100644 index 1cde6a79..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'demo_threadx_non-secure_zone' - * Target: 'FVP Simulation Model' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM23_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/_ThreadX_Library_Project/RTE_Components.h b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/_ThreadX_Library_Project/RTE_Components.h deleted file mode 100644 index 476361d7..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/RTE/_ThreadX_Library_Project/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'ThreadX_Library' - * Target: 'ThreadX_Library_Project' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM23_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt deleted file mode 100644 index 7ec4b36b..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt +++ /dev/null @@ -1,305 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - ThreadX_Demo - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 1 - 0 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 255 - - 1 - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - -1 - - - - - - - - - - - - - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGDARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(101=-1,-1,-1,-1,0)(102=-1,-1,-1,-1,0)(103=-1,-1,-1,-1,0)(104=-1,-1,-1,-1,0)(105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(163=-1,-1,-1,-1,0)(164=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0)(152=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1013=-1,-1,-1,-1,0)(171=-1,-1,-1,-1,0)(172=-1,-1,-1,-1,0)(173=-1,-1,-1,-1,0)(1014=-1,-1,-1,-1,0)(1016=-1,-1,-1,-1,0)(136=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - -T5F - - - 0 - UL2CM3 - -UV0289BJE -O14 -S0 -C0 -N00("ARM CoreSight JTAG-DP") -D00(3BA00477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0LM3S_16 -FS00 -FL04000 - - - - - - 0 - 1 - thread_0_counter - - - 1 - 1 - thread_1_counter - - - 2 - 1 - thread_2_counter - - - 3 - 1 - thread_3_counter - - - 4 - 1 - thread_4_counter - - - 5 - 1 - thread_5_counter - - - 6 - 1 - _tx_thread_current_ptr - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - - - Source Group - 1 - 0 - 0 - 0 - - 1 - 1 - 2 - 0 - 0 - 0 - .\tx_initialize_low_level.s - tx_initialize_low_level.s - 0 - 0 - - - 1 - 2 - 1 - 1 - 0 - 0 - .\demo_threadx.c - demo_threadx.c - 0 - 0 - - 44 - 0 - 1 - - -1 - -1 - - - -1 - -1 - - - 56 - 12 - 1633 - 671 - - - - - - - Library_Group - 1 - 0 - 0 - 0 - - 2 - 3 - 4 - 0 - 0 - 0 - .\ThreadX_Library.lib - ThreadX_Library.lib - 0 - 0 - - - -
diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj deleted file mode 100644 index 5f5dcbdb..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj +++ /dev/null @@ -1,556 +0,0 @@ - - - - 1.1 - -
### uVision Project, (C) Keil Software
- - - - ThreadX_Demo - 0x4 - ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC - 0 - - - Cortex-M4 FPU - ARM - CLOCK(12000000) CPUTYPE("Cortex-M4") ESEL ELITTLE FPU2 - - - - 5237 - - - - - - - - - - - - 0 - 0 - - - - Luminary\ - Luminary\ - - 0 - 0 - 0 - 0 - 1 - - .\ - threadx_demo - 1 - 0 - 0 - 1 - 1 - .\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 0 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - SARMCM3.DLL - - DCM.DLL - -pCM4F - SARMCM3.DLL - - TCM.DLL - -pCM4F - - - - 1 - 0 - 0 - 0 - 16 - - - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - - - 0 - 1 - 0 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - - 0 - -1 - - - - - - - - - - - - - - - - - - - 1 - 0 - 0 - 0 - 1 - 4096 - - 0 - BIN\UL2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M4" - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 1 - 0x0 - 0x40000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - - - - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - - - - - - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - - - - --first __tx_vectors --entry=__main - - - - - - - - Source Group - - - 0 - 1 - 1 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 11 - - - 0 - - - - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - - - - - - - - - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - - - - - - - - - - - - tx_initialize_low_level.s - 2 - .\tx_initialize_low_level.s - - - 2 - 0 - 0 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 11 - - - 1 - - - - 2 - 2 - 2 - 1 - 2 - 2 - 2 - 2 - 2 - 2 - - - - - - - - - - - - demo_threadx.c - 1 - .\demo_threadx.c - - - - - Library_Group - - - ThreadX_Library.lib - 4 - .\ThreadX_Library.lib - - - - - - - -
diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx.c b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx.c deleted file mode 100644 index 34ae21af..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx.c +++ /dev/null @@ -1,428 +0,0 @@ -/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight - threads of different priorities, using a message queue, semaphore, mutex, event flags group, - byte pool, and block pool. Please refer to Chapter 6 of the ThreadX User Guide for a complete - description of this demonstration. */ - -#include "tx_api.h" -#include "..\demo_secure_zone\interface.h" /* Interface to sample secure functions. */ - -#define DEMO_STACK_SIZE 1024 -#define DEMO_BYTE_POOL_SIZE 9120 -#define DEMO_BLOCK_POOL_SIZE 100 -#define DEMO_QUEUE_SIZE 100 - - -/* Define the ThreadX object control blocks... */ - -static TX_THREAD thread_0; -static TX_THREAD thread_1; -static TX_THREAD thread_2; -static TX_THREAD thread_3; -static TX_THREAD thread_4; -static TX_THREAD thread_5; -static TX_THREAD thread_6; -static TX_THREAD thread_7; -static TX_QUEUE queue_0; -static TX_SEMAPHORE semaphore_0; -static TX_MUTEX mutex_0; -static TX_EVENT_FLAGS_GROUP event_flags_0; -static TX_BYTE_POOL byte_pool_0; -static TX_BLOCK_POOL block_pool_0; - -/* Define byte pool memory. */ - -static UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE]; - - -/* Define event buffer. */ - -#ifdef TX_ENABLE_EVENT_TRACE -UCHAR trace_buffer[0x10000]; -#endif - - -/* Define the counters used in the demo application... */ - -static ULONG thread_0_counter; -static ULONG thread_1_counter; -static ULONG thread_1_messages_sent; -static ULONG thread_2_counter; -static ULONG thread_2_messages_received; -static ULONG thread_3_counter; -static ULONG thread_4_counter; -static ULONG thread_5_counter; -static ULONG thread_6_counter; -static ULONG thread_7_counter; - - -/* Define thread prototypes. */ - -void thread_0_entry(ULONG thread_input); -void thread_1_entry(ULONG thread_input); -void thread_2_entry(ULONG thread_input); -void thread_3_and_4_entry(ULONG thread_input); -void thread_5_entry(ULONG thread_input); -void thread_6_and_7_entry(ULONG thread_input); - - -/* Define main entry point. */ - -int main() -{ - - /* Please refer to Chapter 6 of the ThreadX User Guide for a complete - description of this demonstration. */ - - - /* Enter the ThreadX kernel. */ - tx_kernel_enter(); -} - - -/* Define what the initial system looks like. */ - -void tx_application_define(void *first_unused_memory) -{ - -CHAR *pointer; - - (VOID)first_unused_memory; /* unused parameter. */ - -#ifdef TX_ENABLE_EVENT_TRACE - tx_trace_enable(trace_buffer, sizeof(trace_buffer), 32); -#endif - - /* Create a byte memory pool from which to allocate the thread stacks. */ - tx_byte_pool_create(&byte_pool_0, "byte pool 0", byte_pool_memory, DEMO_BYTE_POOL_SIZE); - - /* Put system definition stuff in here, e.g. thread creates and other assorted - create information. */ - - /* Allocate the stack for thread 0. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create the main thread. */ - tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, - pointer, DEMO_STACK_SIZE, - 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_0,256); - - /* Allocate the stack for thread 1. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create threads 1 and 2. These threads pass information through a ThreadX - message queue. It is also interesting to note that these threads have a time - slice. */ - tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, - pointer, DEMO_STACK_SIZE, - 16, 16, 4, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_1,256); - - /* Allocate the stack for thread 2. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, - pointer, DEMO_STACK_SIZE, - 16, 16, 4, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_2,256); - - /* Allocate the stack for thread 3. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore. - An interesting thing here is that both threads share the same instruction area. */ - tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_3,256); - - /* Allocate the stack for thread 4. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_4,256); - - /* Allocate the stack for thread 5. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create thread 5. This thread simply pends on an event flag which will be set - by thread_0. */ - tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, - pointer, DEMO_STACK_SIZE, - 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_5,256); - - /* Allocate the stack for thread 6. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */ - tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_6,256); - - /* Allocate the stack for thread 7. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate secure stack space for thread. */ - tx_thread_secure_stack_allocate(&thread_7,256); - - /* Allocate the message queue. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT); - - /* Create the message queue shared by threads 1 and 2. */ - tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG)); - - /* Create the semaphore used by threads 3 and 4. */ - tx_semaphore_create(&semaphore_0, "semaphore 0", 1); - - /* Create the event flags group used by threads 1 and 5. */ - tx_event_flags_create(&event_flags_0, "event flags 0"); - - /* Create the mutex used by thread 6 and 7 without priority inheritance. */ - tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); - - /* Allocate the memory for a small block pool. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT); - - /* Create a block memory pool to allocate a message buffer from. */ - tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE); - - /* Allocate a block and release the block memory. */ - tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT); - - /* Release the block back to the pool. */ - tx_block_release(pointer); -} - -static int callbackA (int val) -{ - return (val+1); -} - -/* Define the test threads. */ - -void thread_0_entry(ULONG thread_input) -{ -UINT status; -INT test_secure; - - (VOID)thread_input; /* unused parameter. */ - - #if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) - /* Secure call and callback example. - Only to be used when not running in a single mode. */ - test_secure = func1(3); - test_secure = func2(callbackA, test_secure); - tx_thread_secure_stack_free(&thread_0); - #endif - - /* This thread simply sits in while-forever-sleep loop. */ - while(1) - { - - /* Increment the thread counter. */ - thread_0_counter++; - - /* Sleep for 10 ticks. */ - tx_thread_sleep(10); - - /* Set event flag 0 to wakeup thread 5. */ - status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - } -} - - -void thread_1_entry(ULONG thread_input) -{ - -UINT status; - - (VOID)thread_input; /* unused parameter. */ - - /* This thread simply sends messages to a queue shared by thread 2. */ - while(1) - { - /* Increment the thread counter. */ - thread_1_counter++; - - /* Send message to queue 0. */ - status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER); - - /* Check completion status. */ - if (status != TX_SUCCESS) - break; - - /* Increment the message sent. */ - thread_1_messages_sent++; - } -} - - -void thread_2_entry(ULONG thread_input) -{ - -ULONG received_message; -UINT status; - - (VOID)thread_input; /* unused parameter. */ - - /* This thread retrieves messages placed on the queue by thread 1. */ - while(1) - { - - /* Increment the thread counter. */ - thread_2_counter++; - - /* Retrieve a message from the queue. */ - status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER); - - /* Check completion status and make sure the message is what we - expected. */ - if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received)) - break; - - /* Otherwise, all is okay. Increment the received message count. */ - thread_2_messages_received++; - } -} - - -void thread_3_and_4_entry(ULONG thread_input) -{ - -UINT status; - - /* This function is executed from thread 3 and thread 4. As the loop - below shows, these function compete for ownership of semaphore_0. */ - while(1) - { - - /* Increment the thread counter. */ - if (thread_input == 3) - thread_3_counter++; - else - thread_4_counter++; - - /* Get the semaphore with suspension. */ - status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Sleep for 2 ticks to hold the semaphore. */ - tx_thread_sleep(2); - - /* Release the semaphore. */ - status = tx_semaphore_put(&semaphore_0); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - } -} - - -void thread_5_entry(ULONG thread_input) -{ - -UINT status; -ULONG actual_flags; - - (VOID)thread_input; /* unused parameter. */ - - /* This thread simply waits for an event in a forever loop. */ - while(1) - { - - /* Increment the thread counter. */ - thread_5_counter++; - - /* Wait for event flag 0. */ - status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR, - &actual_flags, TX_WAIT_FOREVER); - - /* Check status. */ - if ((status != TX_SUCCESS) || (actual_flags != 0x1)) - break; - } -} - - -void thread_6_and_7_entry(ULONG thread_input) -{ - -UINT status; - - - /* This function is executed from thread 6 and thread 7. As the loop - below shows, these function compete for ownership of mutex_0. */ - while(1) - { - - /* Increment the thread counter. */ - if (thread_input == 6) - thread_6_counter++; - else - thread_7_counter++; - - /* Get the mutex with suspension. */ - status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Get the mutex again with suspension. This shows - that an owning thread may retrieve the mutex it - owns multiple times. */ - status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Sleep for 2 ticks to hold the mutex. */ - tx_thread_sleep(2); - - /* Release the mutex. */ - status = tx_mutex_put(&mutex_0); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Release the mutex again. This will actually - release ownership since it was obtained twice. */ - status = tx_mutex_put(&mutex_0); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - } -} diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx deleted file mode 100644 index d3d8bdd6..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx +++ /dev/null @@ -1,357 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - FVP Simulation Model - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\Listings\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 7 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 15 - - - - - - - - - - ..\Debug.ini - BIN\DbgFMv8M.DLL - - - - 0 - UL2V8M - UL2V8M(-S0 -C0 -P0 -FC1000 -FD20000000 - - - 0 - DbgFMv8M - -I -S -L"cpu0" -O4102 -C0 -MC".\FVP\MPS2_Cortex-M\FVP_MPS2_Cortex-M23_MDK.exe" -MF"..\ARMCM23_TZ_config.txt" -PF -MA - - - 0 - PWSTATINFO - 200,50,700 - - - 0 - DLGTARM - (6010=3439,45,3916,641,1)(6018=1284,352,1473,701,0)(6019=1328,34,1517,370,0)(6008=1878,-297,2172,-112,1)(6009=2170,-278,2464,-93,1)(6014=1111,129,1369,860,0)(6015=872,146,1130,768,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - (105=150,186,829,544,0)(106=511,345,1277,659,0)(107=-1,-1,-1,-1,0) - - - - - 0 - 0 - 246 - 1 -
8470
- 0 - 0 - 0 - 0 - 0 - 1 - <3>.\tx_initialize_low_level.s - - \\demo_secure_zone\tx_initialize_low_level.s\246 -
-
- - - 0 - 1 - thread_0_counter - - - 1 - 1 - thread_1_counter - - - 2 - 1 - thread_2_counter - - - 3 - 1 - thread_3_counter - - - 4 - 1 - thread_4_counter - - - 5 - 1 - thread_5_counter - - - 6 - 1 - thread_6_counter - - - 7 - 1 - thread_7_counter - - - 8 - 1 - _tx_thread_current_ptr - - - - - 1 - 2 - 0x2023ffb8 - 0 - - - - - 2 - 2 - 0xE000ED28 - 0 - - - - 0 - - - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - -
-
- - - Non-secure Code - 1 - 0 - 0 - 0 - - 1 - 1 - 4 - 0 - 0 - 0 - ..\ThreadX_Library.lib - ThreadX_Library.lib - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - .\demo_threadx.c - demo_threadx.c - 0 - 0 - - - - - CMSE Library - 1 - 0 - 0 - 0 - - 2 - 3 - 5 - 0 - 0 - 0 - ..\demo_secure_zone\interface.h - interface.h - 0 - 0 - - - 2 - 4 - 3 - 0 - 0 - 0 - ..\demo_secure_zone\Objects\demo_secure_zone_CMSE_Lib.o - demo_secure_zone_CMSE_Lib.o - 0 - 0 - - - - - ::CMSIS - 1 - 0 - 0 - 1 - - - - ::Device - 1 - 0 - 0 - 1 - - -
diff --git a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx b/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx deleted file mode 100644 index ef9a5e79..00000000 --- a/ports/cortex_m23/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx +++ /dev/null @@ -1,602 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - FVP Simulation Model - 0x4 - ARM-ADS - 6140000::V6.14::ARMCLANG - 1 - - - ARMCM23_TZ - ARM - ARM.CMSIS.5.7.0 - http://www.keil.com/pack/ - IRAM(0x20000000,0x00020000) IRAM2(0x20200000,0x00020000) IROM(0x00000000,0x00200000) IROM2(0x00200000,0x00200000) CPUTYPE("Cortex-M23") TZ CLOCK(12000000) ESEL ELITTLE - - - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - 0 - $$Device:ARMCM23_TZ$Device\ARM\ARMCM23\Include\ARMCM23_TZ.h - - - - - - - - - - - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\Objects\ - demo_threadx_non-secure_zone - 1 - 0 - 0 - 1 - 1 - .\Listings\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - - - - - SARMV8M.DLL - -MPU - TCM.DLL - -pCM23 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 0 - -1 - - 1 - BIN\UL2V8M.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M23" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 8 - 1 - 1 - 0 - 0 - 4 - 4 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 1 - 0x0 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x200000 - - - 1 - 0x200000 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 0 - 0x20200000 - 0x20000 - - - - - - 1 - 2 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 0 - 3 - 1 - 1 - 1 - 0 - 0 - 0 - - -Wno-unused-function -Wno-visibility - - - ..\..\..\..\..\common\inc, ..\..\inc - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - .\RTE\Device\ARMCM23_TZ\ARMCM23_ac6.sct - - - - - - - - - - - Non-secure Code - - - ThreadX_Library.lib - 4 - ..\ThreadX_Library.lib - - - demo_threadx.c - 1 - .\demo_threadx.c - - - - - CMSE Library - - - interface.h - 5 - ..\demo_secure_zone\interface.h - - - demo_secure_zone_CMSE_Lib.o - 3 - ..\demo_secure_zone\Objects\demo_secure_zone_CMSE_Lib.o - - - - - ::CMSIS - - - ::Device - - - - - - - - - - - - - - - - - - - - - - - - RTE\CMSIS\RTX_Config.c - - - - - - RTE\CMSIS\RTX_Config.h - - - - - - RTE\Device\ARMCM23_TZ\ARMCM23_ac6.sct - - - - - - - - RTE\Device\ARMCM23_TZ\partition_ARMCM23.h - - - - - - RTE\Device\ARMCM23_TZ\startup_ARMCM23.c - - - - - - - - RTE\Device\ARMCM23_TZ\system_ARMCM23.c - - - - - - - - RTE\Device\ARMCM33_DSP_FP\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_DSP_FP\system_ARMCM33.c - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_ac6.sct - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\partition_ARMCM33.h - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.c - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\system_ARMCM33.c - - - - - - RTE\Device\ARMCM33_TZ\partition_ARMCM33.h - - - - - - RTE\Device\ARMCM33_TZ\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_TZ\system_ARMCM33.c - - - - - - RTE\Device\ARMv8MBL\partition_ARMv8MBL.h - - - - - - RTE\Device\ARMv8MBL\startup_ARMv8MBL.s - - - - - - RTE\Device\ARMv8MBL\system_ARMv8MBL.c - - - - - - RTE\Device\CMSDK_ARMv8MBL\RTE_Device.h - - - - - - RTE\Device\CMSDK_ARMv8MBL\partition_CMSDK_ARMv8MBL.h - - - - - - RTE\Device\CMSDK_ARMv8MBL\startup_CMSDK_ARMv8MBL.s - - - - - - RTE\Device\CMSDK_ARMv8MBL\system_CMSDK_ARMv8MBL.c - - - - - - - - - - - <Project Info> - - - - - - 0 - 1 - - - - -
diff --git a/ports/cortex_m23/ac5/example_build/tx_initialize_low_level.S b/ports/cortex_m23/ac5/example_build/tx_initialize_low_level.S deleted file mode 100644 index 44135051..00000000 --- a/ports/cortex_m23/ac5/example_build/tx_initialize_low_level.S +++ /dev/null @@ -1,240 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IMPORT _tx_thread_system_stack_ptr - IMPORT _tx_initialize_unused_memory - IMPORT _tx_thread_context_save - IMPORT _tx_thread_context_restore - IMPORT _tx_timer_interrupt - IMPORT __main - IMPORT |Image$$RW_RAM$$ZI$$Limit| - IMPORT __Vectors - IMPORT SystemInit - IMPORT _tx_thread_current_ptr - IMPORT _tx_thread_stack_error_handler -; -; -SYSTEM_CLOCK EQU 6000000 -SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 100) -1) -; -; -;/* Setup the stack and heap areas. */ -; -STACK_SIZE EQU 0x00000400 -HEAP_SIZE EQU 0x00000000 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -StackMem - SPACE STACK_SIZE -__initial_sp - - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -HeapMem - SPACE HEAP_SIZE -__heap_limit - - - AREA ||.text||, CODE, READONLY - PRESERVE8 - - -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_initialize_low_level Cortex-M23/AC5 */ -;/* 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) -;{ - EXPORT _tx_initialize_low_level -_tx_initialize_low_level FUNCTION -; -; /* 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$$RW_RAM$$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 - MOV 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 - ENDFUNC -;} -; -; -;/* Define initial heap/stack routine for the ARM startup code. -; This routine will set the initial stack and heap locations. */ -; - EXPORT __user_initial_stackheap -__user_initial_stackheap FUNCTION - LDR r0, =HeapMem - LDR r1, =(StackMem + STACK_SIZE) - LDR r2, =(HeapMem + HEAP_SIZE) - LDR r3, =StackMem - BX lr - ENDFUNC -; -; -;/* Define shells for each of the unused vectors. */ -; - EXPORT __tx_BadHandler -__tx_BadHandler FUNCTION - B __tx_BadHandler - ENDFUNC - - EXPORT __tx_IntHandler -__tx_IntHandler FUNCTION -; 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 -; } - ENDFUNC - - - EXPORT __tx_SysTickHandler - EXPORT SysTick_Handler -SysTick_Handler FUNCTION -__tx_SysTickHandler -; 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 -; } - ENDFUNC - - - EXPORT HardFault_Handler -HardFault_Handler FUNCTION - ; 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 - ENDFUNC - - ALIGN - LTORG - END diff --git a/ports/cortex_m23/ac5/readme_threadx.txt b/ports/cortex_m23/ac5/readme_threadx.txt deleted file mode 100644 index 1753a961..00000000 --- a/ports/cortex_m23/ac5/readme_threadx.txt +++ /dev/null @@ -1,156 +0,0 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M23 - - Using the AC5 Tools in Keil uVision - -1. Import the ThreadX Projects - -In order to build the ThreadX library and the ThreadX demonstration, first open -the AzureRTOS.uvmpw workspace (located in the "example_build" directory) -into Keil. - - -2. Building the ThreadX run-time Library - -Building the ThreadX library is easy; simply set the ThreadX_Library project -as active, then then build the library. You should now observe the compilation -and assembly of the ThreadX library. This project build produces the ThreadX -library file ThreadX_Library.lib. - - -3. Demonstration System - -The ThreadX demonstration is designed to execute under the Keil debugger on the -FVP_MPS2_Cortex-M23_MDK simulator. - -Building the demonstration is easy; simply select the "Batch Build" button. -You should now observe the compilation and assembly of the ThreadX demonstration of -both the demo_secure_zone and demo_threadx_non-secure_zone projects. -Then click the Start/Stop Debug Session button to start the simulator and begin debugging. -You are now ready to execute the ThreadX demonstration. - - -4. System Initialization - -The entry point in ThreadX for the Cortex-M23 using AC5 tools uses the standard AC5 -Cortex-M23 reset sequence. From the reset vector the C runtime will be initialized. - -The ThreadX tx_initialize_low_level.S file is responsible for setting up -various system data structures, the vector area, and a periodic timer interrupt -source. - -In addition, _tx_initialize_low_level determines the first available -address for use by the application, which is supplied as the sole input -parameter to your application definition function, tx_application_define. - - -5. Register Usage and Stack Frames - -The following defines the saved context stack frames for context switches -that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M23 version of -ThreadX. The top of the suspended thread's stack is pointed to by -tx_thread_stack_ptr in the associated thread control block TX_THREAD. - - - Stack Offset Stack Contents - - 0x00 LR Interrupted LR (LR at time of PENDSV) - 0x04 r8 - 0x08 r9 - 0x0C r10 - 0x10 r11 - 0x14 r4 - 0x18 r5 - 0x1C r6 - 0x20 r7 - 0x24 r0 (Hardware stack starts here!!) - 0x28 r1 - 0x2C r2 - 0x30 r3 - 0x34 r12 - 0x38 lr - 0x3C pc - 0x40 xPSR - - -6. Improving Performance - -To make ThreadX and the application(s) run faster, you can enable -all compiler optimizations. - -In addition, you can eliminate the ThreadX basic API error checking by -compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING -defined. - - -7. Interrupt Handling - -ThreadX provides complete and high-performance interrupt handling for Cortex-M23 -targets. There are a certain set of requirements that are defined in the -following sub-sections: - - -7.1 Vector Area - -The Cortex-M23 vectors start at the label __Vectors or similar. The application may modify -the vector area according to its needs. There is code in tx_initialize_low_level() that will -configure the vector base register. - - -7.2 Managed Interrupts - -ISRs can be written completely in C (or assembly language) without any calls to -_tx_thread_context_save or _tx_thread_context_restore. These ISRs are allowed access to the -ThreadX API that is available to ISRs. - -ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): - -void your_C_isr(void) -{ - - /* ISR processing goes here, including any needed function calls. */ -} - -ISRs written in assembly language will take the form: - - - .global your_assembly_isr - .thumb_func -your_assembly_isr: -; VOID your_assembly_isr(VOID) -; { - PUSH {r0, lr} -; -; /* Do interrupt handler work here */ -; /* BL */ - - POP {r0, r1} - MOV lr, r1 - BX lr -; } - - -Note: the Cortex-M23 requires exception handlers to be thumb labels, this implies bit 0 set. -To accomplish this, the declaration of the label has to be preceded by the assembler directive -.thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to -be inserted in the correct location in the interrupt vector table. This table is typically -located in either your runtime startup file or in the tx_initialize_low_level.S file. - - -8. Revision History - -For generic code revision information, please refer to the readme_threadx_generic.txt -file, which is included in your distribution. The following details the revision -information associated with this specific port of ThreadX: - -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M23 using AC5 tools. - - -Copyright(c) 1996-2020 Microsoft Corporation - - -https://azure.com/rtos - diff --git a/ports/cortex_m23/ac5/src/tx_thread_interrupt_disable.s b/ports/cortex_m23/ac5/src/tx_thread_interrupt_disable.s deleted file mode 100644 index 89ada0be..00000000 --- a/ports/cortex_m23/ac5/src/tx_thread_interrupt_disable.s +++ /dev/null @@ -1,77 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_disable Cortex-M23/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_interrupt_disable -_tx_thread_interrupt_disable FUNCTION -; -; /* Return current interrupt lockout posture. */ -; - MRS r0, PRIMASK - CPSID i - BX lr -; -;} - ENDFUNC - END diff --git a/ports/cortex_m23/ac5/src/tx_thread_interrupt_restore.s b/ports/cortex_m23/ac5/src/tx_thread_interrupt_restore.s deleted file mode 100644 index 30723b44..00000000 --- a/ports/cortex_m23/ac5/src/tx_thread_interrupt_restore.s +++ /dev/null @@ -1,76 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M23/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_interrupt_restore -_tx_thread_interrupt_restore FUNCTION -; -; /* Restore previous interrupt lockout posture. */ -; - MSR PRIMASK, r0 - BX lr -; -;} - ENDFUNC - END diff --git a/ports/cortex_m23/ac5/src/tx_thread_schedule.s b/ports/cortex_m23/ac5/src/tx_thread_schedule.s deleted file mode 100644 index 84ac8c15..00000000 --- a/ports/cortex_m23/ac5/src/tx_thread_schedule.s +++ /dev/null @@ -1,347 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IMPORT _tx_thread_current_ptr - IMPORT _tx_thread_execute_ptr - IMPORT _tx_timer_time_slice - IMPORT _tx_thread_system_stack_ptr - IMPORT _tx_thread_preempt_disable - - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY - IMPORT _tx_execution_thread_enter - IMPORT _tx_execution_thread_exit - ENDIF - - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: TX_SINGLE_MODE_NON_SECURE - IMPORT _tx_thread_secure_stack_context_restore - IMPORT _tx_thread_secure_stack_context_save - IMPORT _tx_thread_secure_mode_stack_allocate - IMPORT _tx_thread_secure_mode_stack_free - ENDIF -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M23/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_schedule -_tx_thread_schedule FUNCTION -; -; /* This function should only ever be called on Cortex-M -; from the first schedule request. Subsequent scheduling occurs -; from the PendSV handling routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 - ENDFUNC -;} -; -; /* Generic context switching PendSV handler. */ -; - EXPORT PendSV_Handler -PendSV_Handler FUNCTION -; -; /* Get current thread value and new thread pointer. */ -; -__tx_ts_handler - - IF :DEF: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 - - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 its stack pointer - - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: 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. */ -; - MOVS 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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - 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 - - IF :DEF: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 :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: 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. */ -; - IF :DEF: 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! - IF :DEF: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 - ENDFUNC - - - - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: TX_SINGLE_MODE_NON_SECURE - ; SVC_Handler is not needed when ThreadX is running in single mode. - EXPORT SVC_Handler -SVC_Handler FUNCTION - MOVS 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 - ENDFUNC - ENDIF ; End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE - - ALIGN - LTORG - END diff --git a/ports/cortex_m23/ac5/src/tx_thread_secure_stack.c b/ports/cortex_m23/ac5/src/tx_thread_secure_stack.c deleted file mode 100644 index ad4a7119..00000000 --- a/ports/cortex_m23/ac5/src/tx_thread_secure_stack.c +++ /dev/null @@ -1,485 +0,0 @@ -/**************************************************************************/ -/* */ -/* 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 - -/* 8 bytes added to stack size to "seal" stack. */ -#define TX_THREAD_STACK_SEAL_SIZE 8 -#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5 - -/* 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/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* added stack sealing, */ -/* resulting in version 6.1.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 & seal. */ - stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_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; - - /* Seal bottom of stack. */ - *(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE; - - /* 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/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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 diff --git a/ports/cortex_m23/ac5/src/tx_thread_secure_stack_allocate.s b/ports/cortex_m23/ac5/src/tx_thread_secure_stack_allocate.s deleted file mode 100644 index ffceb7ec..00000000 --- a/ports/cortex_m23/ac5/src/tx_thread_secure_stack_allocate.s +++ /dev/null @@ -1,82 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_secure_stack_allocate Cortex-M23/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_secure_stack_allocate -_tx_thread_secure_stack_allocate FUNCTION - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: 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 - MOV32 r0, #0xFF ; Feature not enabled - ENDIF -_alloc_return_interrupt_enabled - BX lr - ENDFUNC - END diff --git a/ports/cortex_m23/ac5/src/tx_thread_secure_stack_free.s b/ports/cortex_m23/ac5/src/tx_thread_secure_stack_free.s deleted file mode 100644 index efee2766..00000000 --- a/ports/cortex_m23/ac5/src/tx_thread_secure_stack_free.s +++ /dev/null @@ -1,80 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_secure_stack_free Cortex-M23/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_secure_stack_free -_tx_thread_secure_stack_free FUNCTION - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: 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 - MOV32 r0, #0xFF ; Feature not enabled - ENDIF -_free_return_interrupt_enabled - BX lr - ENDFUNC - END diff --git a/ports/cortex_m23/ac5/src/tx_timer_interrupt.s b/ports/cortex_m23/ac5/src/tx_timer_interrupt.s deleted file mode 100644 index 73705511..00000000 --- a/ports/cortex_m23/ac5/src/tx_timer_interrupt.s +++ /dev/null @@ -1,259 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IMPORT _tx_timer_time_slice - IMPORT _tx_timer_system_clock - IMPORT _tx_timer_current_ptr - IMPORT _tx_timer_list_start - IMPORT _tx_timer_list_end - IMPORT _tx_timer_expired_time_slice - IMPORT _tx_timer_expired - IMPORT _tx_thread_time_slice - IMPORT _tx_timer_expiration_process - IMPORT _tx_thread_preempt_disable - IMPORT _tx_thread_current_ptr - IMPORT _tx_thread_execute_ptr -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M23/AC5 */ -;/* 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 */ -;/* the expiration functions are called. */ -;/* */ -;/* 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) -;{ - EXPORT _tx_timer_interrupt -_tx_timer_interrupt FUNCTION -; -; /* 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++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of 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) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 -; -;} - ENDFUNC - ALIGN - LTORG - END diff --git a/ports/cortex_m23/ac6/example_build/ThreadX_Library.uvprojx b/ports/cortex_m23/ac6/example_build/ThreadX_Library.uvprojx index 9cb2c7c0..90156215 100644 --- a/ports/cortex_m23/ac6/example_build/ThreadX_Library.uvprojx +++ b/ports/cortex_m23/ac6/example_build/ThreadX_Library.uvprojx @@ -1373,6 +1373,11 @@ 1 ..\src\tx_thread_stack_error_notify.c + + tx_thread_secure_stack_initialize.S + 2 + ..\src\tx_thread_secure_stack_initialize.S + diff --git a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct index a833a90d..8c9eba2b 100644 --- a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct +++ b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/ARMCM23_ac6.sct @@ -11,8 +11,8 @@ ; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> ; *----------------------------------------------------------------------------*/ -#define __ROM_BASE 0x00000000 -#define __ROM_SIZE 0x00080000 +#define __ROM_BASE 0x00000000 +#define __ROM_SIZE 0x00080000 /*--------------------- Embedded RAM Configuration --------------------------- ; RAM Configuration @@ -20,8 +20,8 @@ ; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> ; *----------------------------------------------------------------------------*/ -#define __RAM_BASE 0x20000000 -#define __RAM_SIZE 0x00040000 +#define __RAM_BASE 0x20000000 +#define __RAM_SIZE 0x00040000 /*--------------------- Stack / Heap Configuration --------------------------- ; Stack / Heap Configuration @@ -29,26 +29,29 @@ ; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> ; *----------------------------------------------------------------------------*/ -#define __STACK_SIZE 0x00000200 -#define __HEAP_SIZE 0x00000C00 +#define __STACK_SIZE 0x00000200 +#define __HEAP_SIZE 0x00000C00 + +/* +;------------- <<< end of configuration section >>> --------------------------- +*/ /*---------------------------------------------------------------------------- - User Stack & Heap boundery definition + User Stack & Heap boundary definition *----------------------------------------------------------------------------*/ -#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ -#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ +#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ +#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ /*---------------------------------------------------------------------------- Scatter File Definitions definition *----------------------------------------------------------------------------*/ -#define __RO_BASE __ROM_BASE -#define __RO_SIZE __ROM_SIZE - -#define __RW_BASE (__RAM_BASE ) -#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) +#define __RO_BASE __ROM_BASE +#define __RO_SIZE __ROM_SIZE +#define __RW_BASE __RAM_BASE +#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) LR_ROM __RO_BASE __RO_SIZE { ; load region size_region diff --git a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h index a7a090e7..77383657 100644 --- a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h +++ b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/partition_ARMCM23.h @@ -1,7 +1,7 @@ /**************************************************************************//** * @file partition_ARMCM23.h * @brief CMSIS-CORE Initial Setup for Secure / Non-Secure Zones for ARMCM23 - * @version V5.3.1 + * @version V1.0.0 * @date 09. July 2018 ******************************************************************************/ /* diff --git a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c index eb5fdfc5..3a70c740 100644 --- a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c +++ b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/startup_ARMCM23.c @@ -1,11 +1,11 @@ /****************************************************************************** * @file startup_ARMCM23.c * @brief CMSIS-Core(M) Device Startup File for a Cortex-M23 Device - * @version V2.0.0 - * @date 04. June 2019 + * @version V2.0.3 + * @date 31. March 2020 ******************************************************************************/ /* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -30,11 +30,6 @@ #error device not specified! #endif -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler Function Prototype - *----------------------------------------------------------------------------*/ -typedef void( *pFunc )( void ); - /*---------------------------------------------------------------------------- External References *----------------------------------------------------------------------------*/ @@ -46,15 +41,15 @@ extern __NO_RETURN void __PROGRAM_START(void); /*---------------------------------------------------------------------------- Internal References *----------------------------------------------------------------------------*/ -void __NO_RETURN Default_Handler(void); -void __NO_RETURN Reset_Handler (void); +__NO_RETURN void Reset_Handler (void); + void Default_Handler(void); /*---------------------------------------------------------------------------- Exception / Interrupt Handler *----------------------------------------------------------------------------*/ /* Exceptions */ void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void HardFault_Handler (void) __attribute__ ((weak)); void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); @@ -80,9 +75,9 @@ void Interrupt9_Handler (void) __attribute__ ((weak, alias("Default_Handler" #pragma GCC diagnostic ignored "-Wpedantic" #endif -extern const pFunc __VECTOR_TABLE[240]; - const pFunc __VECTOR_TABLE[240] __VECTOR_TABLE_ATTRIBUTE = { - (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ +extern const VECTOR_TABLE_Type __VECTOR_TABLE[240]; + const VECTOR_TABLE_Type __VECTOR_TABLE[240] __VECTOR_TABLE_ATTRIBUTE = { + (VECTOR_TABLE_Type)(&__INITIAL_SP), /* Initial Stack Pointer */ Reset_Handler, /* Reset Handler */ NMI_Handler, /* -14 NMI Handler */ HardFault_Handler, /* -13 Hard Fault Handler */ @@ -123,7 +118,7 @@ const int stack_seal __attribute__((section (".seal"))) = 0xFEF5EDA5; /*---------------------------------------------------------------------------- Reset Handler called on controller reset *----------------------------------------------------------------------------*/ -void Reset_Handler(void) +__NO_RETURN void Reset_Handler(void) { __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); @@ -131,6 +126,20 @@ void Reset_Handler(void) __PROGRAM_START(); /* Enter PreMain (C library entry point) */ } + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wmissing-noreturn" +#endif + +/*---------------------------------------------------------------------------- + Hard Fault Handler + *----------------------------------------------------------------------------*/ +void HardFault_Handler(void) +{ + while(1); +} + /*---------------------------------------------------------------------------- Default Handler for Exceptions / Interrupts *----------------------------------------------------------------------------*/ @@ -138,3 +147,8 @@ void Default_Handler(void) { while(1); } + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop +#endif + diff --git a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c index 1052b383..cf78a4ed 100644 --- a/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c +++ b/ports/cortex_m23/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM23_TZ/system_ARMCM23.c @@ -2,11 +2,11 @@ * @file system_ARMCM23.c * @brief CMSIS Device System Source File for * ARMCM23 Device - * @version V5.3.1 - * @date 09. July 2018 + * @version V1.0.1 + * @date 15. November 2019 ******************************************************************************/ /* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -42,13 +42,11 @@ #define SYSTEM_CLOCK (XTAL / 2U) - /*---------------------------------------------------------------------------- - Externals + Exception / Interrupt Vector table *----------------------------------------------------------------------------*/ -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - extern uint32_t __VECTOR_TABLE; -#endif +extern const VECTOR_TABLE_Type __VECTOR_TABLE[240]; + /*---------------------------------------------------------------------------- System Core Clock Variable @@ -71,7 +69,7 @@ void SystemInit (void) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - SCB->VTOR = (uint32_t) &__VECTOR_TABLE; + SCB->VTOR = (uint32_t) &(__VECTOR_TABLE[0]); #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) diff --git a/ports/cortex_m23/ac6/inc/tx_port.h b/ports/cortex_m23/ac6/inc/tx_port.h index 0e3f401c..baa59bfd 100644 --- a/ports/cortex_m23/ac6/inc/tx_port.h +++ b/ports/cortex_m23/ac6/inc/tx_port.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M23/AC6 */ -/* 6.1.5 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ @@ -51,6 +51,11 @@ /* 03-02-2021 Scott Larson Modified comment(s), added */ /* ULONG64_DEFINED, */ /* resulting in version 6.1.5 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), removed */ +/* unneeded header file, added */ +/* conditional compilation */ +/* for ARMv8-M (Cortex M23/33) */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -71,7 +76,6 @@ #include #include #include -#include "ARMCM23_TZ.h" /* For intrinsic functions. */ /* Define ThreadX basic types for this port. */ @@ -94,6 +98,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" @@ -279,7 +289,6 @@ ULONG _tx_misra_time_stamp_get(VOID); #ifndef TX_MISRA_ENABLE -//register unsigned int _ipsr __asm ("MRS %[result], ipsr" : [result] "=r" (_ipsr) : ); inline static unsigned int _get_ipsr(void); inline static unsigned int _get_ipsr(void) { @@ -410,7 +419,7 @@ unsigned int was_masked; #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/AC6 Version 6.1 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/AC6 Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; diff --git a/ports/cortex_m23/ac6/readme_threadx.txt b/ports/cortex_m23/ac6/readme_threadx.txt index 45188e83..787881bc 100644 --- a/ports/cortex_m23/ac6/readme_threadx.txt +++ b/ports/cortex_m23/ac6/readme_threadx.txt @@ -145,6 +145,13 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +06-02-2021 Release 6.1.7 changes: + tx_port.h Remove unneeded include file + tx_thread_secure_stack_initialize.S New file + tx_thread_schedule.S Added secure stack initialize to SVC hander + tx_thread_secure_stack.c Fixed stack pointer save, initialize in handler mode + + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition tx_thread_schedule.s Added low power support diff --git a/ports/cortex_m23/ac6/src/tx_thread_context_restore.s b/ports/cortex_m23/ac6/src/tx_thread_context_restore.s index b2989990..ec3fe294 100644 --- a/ports/cortex_m23/ac6/src/tx_thread_context_restore.s +++ b/ports/cortex_m23/ac6/src/tx_thread_context_restore.s @@ -19,6 +19,9 @@ /** */ /**************************************************************************/ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif /**************************************************************************/ @@ -68,7 +71,14 @@ .thumb_func .type _tx_thread_context_restore, function _tx_thread_context_restore: - /* Return to interrupt processing. */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr // } .end diff --git a/ports/cortex_m23/ac6/src/tx_thread_context_save.s b/ports/cortex_m23/ac6/src/tx_thread_context_save.s index fefeb7b0..6a7db9ff 100644 --- a/ports/cortex_m23/ac6/src/tx_thread_context_save.s +++ b/ports/cortex_m23/ac6/src/tx_thread_context_save.s @@ -21,6 +21,9 @@ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_enter +#endif /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -68,7 +71,16 @@ .thumb_func .type _tx_thread_context_save, function _tx_thread_context_save: - /* Return to interrupt processing. */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr // } .end diff --git a/ports/cortex_m23/ac6/src/tx_thread_schedule.s b/ports/cortex_m23/ac6/src/tx_thread_schedule.s index dfe83983..a8c6f78c 100644 --- a/ports/cortex_m23/ac6/src/tx_thread_schedule.s +++ b/ports/cortex_m23/ac6/src/tx_thread_schedule.s @@ -21,6 +21,10 @@ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit +#endif /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -62,6 +66,9 @@ /* 04-02-2021 Scott Larson Modified comment(s), added */ /* low power code, */ /* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Added secure stack initialize */ +/* in SVC handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -113,13 +120,13 @@ __tx_wait_here: PendSV_Handler: __tx_ts_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 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 + MOV lr, r1 // CPSIE i // Enable interrupts #endif @@ -207,11 +214,11 @@ __tx_ts_restore: STR r5, [r4] // Setup global time-slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) /* Call the thread entry function to indicate the thread is executing. */ - PUSH {r0, r1} // Save r0/r1 + PUSH {r0, r1} // Save r0 and r1 BL _tx_execution_thread_enter // Call the thread execution enter function - POP {r0, r1} // Recover r0/r1 + POP {r0, r1} // Recover r0 and r1 #endif #if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) @@ -248,7 +255,7 @@ _skip_secure_restore: 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 + 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: @@ -278,13 +285,12 @@ __tx_ts_wait: 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 + /* 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 + STR r7, [r5] // Clear any PendSV /* Re-enable interrupts and restore new thread. */ CPSIE i // Enable interrupts @@ -320,9 +326,12 @@ _tx_got_sp: CMP r1, #2 // Is it a secure stack free request? BEQ _tx_svc_secure_free // Yes, go there + CMP r1, #3 // Is it a secure stack init request? + BEQ _tx_svc_secure_init // 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 @@ -339,6 +348,12 @@ _tx_svc_secure_free: 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 +_tx_svc_secure_init: + PUSH {r0,lr} // Save SP and EXC_RETURN + BL _tx_thread_secure_mode_stack_initialize + POP {r1, r2} // Restore SP and EXC_RETURN + MOV lr, r2 + BX lr +#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE .end diff --git a/ports/cortex_m23/ac6/src/tx_thread_secure_stack.c b/ports/cortex_m23/ac6/src/tx_thread_secure_stack.c index 311e67b6..0ecf2ac9 100644 --- a/ports/cortex_m23/ac6/src/tx_thread_secure_stack.c +++ b/ports/cortex_m23/ac6/src/tx_thread_secure_stack.c @@ -62,8 +62,8 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_secure_stack_initialize Cortex-M23/AC6 */ -/* 6.1.1 */ +/* _tx_thread_secure_mode_stack_initialize Cortex-M23/AC6 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -78,7 +78,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* OUTPUT */ /* */ -/* None */ +/* status */ /* */ /* CALLS */ /* */ @@ -98,21 +98,35 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Modified comment(s), and */ +/* changed name, execute in */ +/* handler mode, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) -void _tx_thread_secure_stack_initialize(void) +UINT _tx_thread_secure_mode_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; +UINT status; + + /* Make sure function is called from interrupt (threads should not call). */ + if (__get_IPSR() == 0) + { + status = TX_CALLER_ERROR; + } + else + { + /* 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); + + status = TX_SUCCESS; + } + return status; } @@ -335,7 +349,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M23/AC6 */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -370,6 +384,8 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -402,7 +418,7 @@ ULONG sp; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports/cortex_m23/ac6/src/tx_thread_secure_stack_initialize.S b/ports/cortex_m23/ac6/src/tx_thread_secure_stack_initialize.S new file mode 100644 index 00000000..06dc8812 --- /dev/null +++ b/ports/cortex_m23/ac6/src/tx_thread_secure_stack_initialize.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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_initialize Cortex-M23/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enters the SVC handler to initialize a secure stack. */ +/* */ +/* INPUT */ +/* */ +/* none */ +/* */ +/* OUTPUT */ +/* */ +/* none */ +/* */ +/* CALLS */ +/* */ +/* SVC 3 */ +/* */ +/* CALLED BY */ +/* */ +/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_secure_stack_initialize(VOID) +// { + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global _tx_thread_secure_stack_initialize + .thumb_func +.type _tx_thread_secure_stack_initialize, function +_tx_thread_secure_stack_initialize: +#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) + CPSIE i // Enable interrupts for SVC call + SVC 3 + CPSID i // Disable interrupts +#else + MOV r0, #0xFF // Feature not enabled +#endif + BX lr + .end diff --git a/ports/cortex_m23/gnu/inc/tx_port.h b/ports/cortex_m23/gnu/inc/tx_port.h index d09ff80b..b941492d 100644 --- a/ports/cortex_m23/gnu/inc/tx_port.h +++ b/ports/cortex_m23/gnu/inc/tx_port.h @@ -53,6 +53,10 @@ /* use builtins, added */ /* ULONG64_DEFINED, */ /* resulting in version 6.1.5 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), added */ +/* conditional compilation */ +/* for ARMv8-M (Cortex M23/33) */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -87,6 +91,12 @@ typedef short SHORT; typedef unsigned short USHORT; #define ULONG64_DEFINED +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* Function prototypes for this port. */ struct TX_THREAD_STRUCT; UINT _txe_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *thread_ptr, ULONG stack_size); diff --git a/ports/cortex_m23/gnu/readme_threadx.txt b/ports/cortex_m23/gnu/readme_threadx.txt index 435e3cb9..08a8ca82 100644 --- a/ports/cortex_m23/gnu/readme_threadx.txt +++ b/ports/cortex_m23/gnu/readme_threadx.txt @@ -128,6 +128,11 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +06-02-2021 Release 6.1.7 changes: + tx_thread_secure_stack_initialize.S New file + tx_thread_schedule.S Added secure stack initialize to SVC hander + tx_thread_secure_stack.c Fixed stack pointer save, initialize in handler mode + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition tx_thread_schedule.s Added low power support diff --git a/ports/cortex_m23/gnu/src/tx_thread_context_restore.s b/ports/cortex_m23/gnu/src/tx_thread_context_restore.s index 14d772fb..2ebed08a 100644 --- a/ports/cortex_m23/gnu/src/tx_thread_context_restore.s +++ b/ports/cortex_m23/gnu/src/tx_thread_context_restore.s @@ -19,6 +19,9 @@ /** */ /**************************************************************************/ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif /**************************************************************************/ @@ -68,7 +71,14 @@ .thumb_func .type _tx_thread_context_restore, function _tx_thread_context_restore: - /* Return to interrupt processing. */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr // } .end diff --git a/ports/cortex_m23/gnu/src/tx_thread_context_save.s b/ports/cortex_m23/gnu/src/tx_thread_context_save.s index 25050678..61ccafd8 100644 --- a/ports/cortex_m23/gnu/src/tx_thread_context_save.s +++ b/ports/cortex_m23/gnu/src/tx_thread_context_save.s @@ -68,7 +68,16 @@ .thumb_func .type _tx_thread_context_save, function _tx_thread_context_save: - /* Return to interrupt processing. */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr // } .end diff --git a/ports/cortex_m23/gnu/src/tx_thread_schedule.s b/ports/cortex_m23/gnu/src/tx_thread_schedule.s index 24d64e64..4cdd9773 100644 --- a/ports/cortex_m23/gnu/src/tx_thread_schedule.s +++ b/ports/cortex_m23/gnu/src/tx_thread_schedule.s @@ -62,6 +62,9 @@ /* 04-02-2021 Scott Larson Modified comment(s), added */ /* low power code, */ /* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Added secure stack initialize */ +/* in SVC handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -113,13 +116,13 @@ __tx_wait_here: PendSV_Handler: __tx_ts_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 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 + MOV lr, r1 // CPSIE i // Enable interrupts #endif @@ -207,11 +210,11 @@ __tx_ts_restore: STR r5, [r4] // Setup global time-slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) /* Call the thread entry function to indicate the thread is executing. */ - PUSH {r0, r1} // Save r0/r1 + PUSH {r0, r1} // Save r0 and r1 BL _tx_execution_thread_enter // Call the thread execution enter function - POP {r0, r1} // Recover r0/r1 + POP {r0, r1} // Recover r0 and r1 #endif #if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) @@ -248,7 +251,7 @@ _skip_secure_restore: 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 + 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: @@ -278,13 +281,12 @@ __tx_ts_wait: 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 + /* 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 + STR r7, [r5] // Clear any PendSV /* Re-enable interrupts and restore new thread. */ CPSIE i // Enable interrupts @@ -320,9 +322,12 @@ _tx_got_sp: CMP r1, #2 // Is it a secure stack free request? BEQ _tx_svc_secure_free // Yes, go there + CMP r1, #3 // Is it a secure stack init request? + BEQ _tx_svc_secure_init // 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 @@ -339,6 +344,12 @@ _tx_svc_secure_free: 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 +_tx_svc_secure_init: + PUSH {r0,lr} // Save SP and EXC_RETURN + BL _tx_thread_secure_mode_stack_initialize + POP {r1, r2} // Restore SP and EXC_RETURN + MOV lr, r2 + BX lr +#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE .end diff --git a/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c b/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c index 0e8cbde0..57864edd 100644 --- a/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c +++ b/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c @@ -61,8 +61,8 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_secure_stack_initialize Cortex-M23/GNU */ -/* 6.1.3 */ +/* _tx_thread_secure_mode_stack_initialize Cortex-M23/GNU */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -77,7 +77,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* OUTPUT */ /* */ -/* None */ +/* status */ /* */ /* CALLS */ /* */ @@ -94,27 +94,39 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ -/* 12-31-2020 Scott Larson Modified comment(s), and */ -/* fixed M23 GCC build, */ -/* resulting in version 6.1.3 */ +/* 06-02-2021 Scott Larson Modified comment(s), changed */ +/* name, execute in handler */ +/* mode, disable optimization, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ -__attribute__((cmse_nonsecure_entry)) -void _tx_thread_secure_stack_initialize(void) +__attribute__((cmse_nonsecure_entry, optimize(0))) +UINT _tx_thread_secure_mode_stack_initialize(void) { - ULONG control; - - /* Set secure mode to use PSP. */ - asm volatile("MRS %0, CONTROL" : "=r" (control)); /* Get CONTROL register. */ - control |= 2; /* Use PSP. */ - asm volatile("MSR CONTROL, %0" :: "r" (control)); /* Set CONTROL register. */ - - /* 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. */ - asm volatile("MSR PSPLIM, %0" :: "r" (0)); - asm volatile("MSR PSP, %0" :: "r" (0)); - - return; +UINT status; +ULONG control; + + /* Make sure function is called from interrupt (threads should not call). */ + asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */ + if (ipsr == 0) + { + status = TX_CALLER_ERROR; + } + else + { + /* Set secure mode to use PSP. */ + asm volatile("MRS %0, CONTROL" : "=r" (control)); /* Get CONTROL register. */ + control |= 2; /* Use PSP. */ + asm volatile("MSR CONTROL, %0" :: "r" (control)); /* Set CONTROL register. */ + + /* 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. */ + asm volatile("MSR PSPLIM, %0" :: "r" (0)); + asm volatile("MSR PSP, %0" :: "r" (0)); + + status = TX_SUCCESS; + } + return status; } @@ -342,7 +354,7 @@ ULONG ipsr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M23/GNU */ -/* 6.1.3 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -377,6 +389,8 @@ ULONG ipsr; /* 12-31-2020 Scott Larson Modified comment(s), and */ /* fixed M23 GCC build, */ /* resulting in version 6.1.3 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -411,7 +425,7 @@ ULONG ipsr; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports/cortex_m23/gnu/src/tx_thread_secure_stack_initialize.S b/ports/cortex_m23/gnu/src/tx_thread_secure_stack_initialize.S new file mode 100644 index 00000000..2d8bb868 --- /dev/null +++ b/ports/cortex_m23/gnu/src/tx_thread_secure_stack_initialize.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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_initialize Cortex-M23/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enters the SVC handler to initialize a secure stack. */ +/* */ +/* INPUT */ +/* */ +/* none */ +/* */ +/* OUTPUT */ +/* */ +/* none */ +/* */ +/* CALLS */ +/* */ +/* SVC 3 */ +/* */ +/* CALLED BY */ +/* */ +/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_secure_stack_initialize(VOID) +// { + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global _tx_thread_secure_stack_initialize + .thumb_func +.type _tx_thread_secure_stack_initialize, function +_tx_thread_secure_stack_initialize: +#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) + CPSIE i // Enable interrupts for SVC call + SVC 3 + CPSID i // Disable interrupts +#else + MOV r0, #0xFF // Feature not enabled +#endif + BX lr + .end diff --git a/ports/cortex_m23/iar/inc/tx_port.h b/ports/cortex_m23/iar/inc/tx_port.h index f62f6aec..82e2ed90 100644 --- a/ports/cortex_m23/iar/inc/tx_port.h +++ b/ports/cortex_m23/iar/inc/tx_port.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M23/IAR */ -/* 6.1.5 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ @@ -51,6 +51,10 @@ /* 03-02-2021 Scott Larson Modified comment(s), added */ /* ULONG64_DEFINED, */ /* resulting in version 6.1.5 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), added */ +/* conditional compilation */ +/* for ARMv8-M (Cortex M23/33) */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -97,6 +101,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" @@ -258,13 +268,7 @@ ULONG _tx_misra_time_stamp_get(VOID); #endif - -#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 -#else -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; -#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -385,7 +389,7 @@ extern void _tx_thread_secure_stack_initialize(void); #ifndef TX_DISABLE_INLINE -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m))); +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); #endif @@ -433,21 +437,11 @@ __istate_t interrupt_save; #endif -/* Define the interrupt lockout macros for each ThreadX object. */ - -#define TX_BLOCK_POOL_DISABLE TX_DISABLE -#define TX_BYTE_POOL_DISABLE TX_DISABLE -#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE -#define TX_MUTEX_DISABLE TX_DISABLE -#define TX_QUEUE_DISABLE TX_DISABLE -#define TX_SEMAPHORE_DISABLE TX_DISABLE - - /* 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/IAR Version 6.1 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/IAR Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; diff --git a/ports/cortex_m23/iar/readme_threadx.txt b/ports/cortex_m23/iar/readme_threadx.txt index 11717ae3..bd190400 100644 --- a/ports/cortex_m23/iar/readme_threadx.txt +++ b/ports/cortex_m23/iar/readme_threadx.txt @@ -136,6 +136,11 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +06-02-2021 Release 6.1.7 changes: + tx_thread_secure_stack_initialize.s New file + tx_thread_schedule.s Added secure stack initialize to SVC hander + tx_thread_secure_stack.c Fixed stack pointer save, initialize in handler mode + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition tx_thread_schedule.s Added low power support diff --git a/ports/cortex_m23/iar/src/tx_thread_context_restore.s b/ports/cortex_m23/iar/src/tx_thread_context_restore.s index 48300c4d..51704008 100644 --- a/ports/cortex_m23/iar/src/tx_thread_context_restore.s +++ b/ports/cortex_m23/iar/src/tx_thread_context_restore.s @@ -64,9 +64,14 @@ ;{ PUBLIC _tx_thread_context_restore _tx_thread_context_restore: -; -; /* Return to interrupt processing. */ -; + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr ;} END diff --git a/ports/cortex_m23/iar/src/tx_thread_context_save.s b/ports/cortex_m23/iar/src/tx_thread_context_save.s index f666d4a4..68219205 100644 --- a/ports/cortex_m23/iar/src/tx_thread_context_save.s +++ b/ports/cortex_m23/iar/src/tx_thread_context_save.s @@ -64,9 +64,16 @@ ;{ PUBLIC _tx_thread_context_save _tx_thread_context_save: -; -; /* Return to interrupt processing. */ -; + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr ;} END diff --git a/ports/cortex_m23/iar/src/tx_thread_schedule.s b/ports/cortex_m23/iar/src/tx_thread_schedule.s index 2acf2f77..8b5ebf20 100644 --- a/ports/cortex_m23/iar/src/tx_thread_schedule.s +++ b/ports/cortex_m23/iar/src/tx_thread_schedule.s @@ -1,26 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_timer_time_slice @@ -32,326 +31,320 @@ EXTERN _tx_thread_secure_stack_context_save EXTERN _tx_thread_secure_mode_stack_allocate EXTERN _tx_thread_secure_mode_stack_free + EXTERN _tx_thread_secure_mode_stack_initialize #ifdef TX_LOW_POWER EXTERN tx_low_power_enter EXTERN tx_low_power_exit #endif -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M23/IAR */ -;/* 6.1.6 */ -;/* 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 */ -;/* 04-02-2021 Scott Larson Modified comment(s), added */ -;/* low power code, */ -;/* resulting in version 6.1.6 */ -;/* */ -;/**************************************************************************/ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M23/IAR */ +/* 6.1.7 */ +/* 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 */ +/* 04-02-2021 Scott Larson Modified comment(s), added */ +/* low power code, */ +/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Added secure stack initialize */ +/* in SVC handler, */ +/* resulting in version 6.1.7 */ +/* */ +/**************************************************************************/ ;VOID _tx_thread_schedule(VOID) ;{ PUBLIC _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 */ -; + /* 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. */ + MOV 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. */ -; + + /* 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. */ -; + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + PUBLIC PendSV_Handler PendSV_Handler: -; -; /* Get current thread value and new thread pointer. */ -; __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 +#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 + 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 - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 its stack pointer + MOV32 r0, _tx_thread_current_ptr // Build current thread pointer address + MOV32 r2, _tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 +#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. */ -; - MOVS 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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - 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 + /* 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. */ + + MOVS 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 + MOV32 r4, _tx_timer_time_slice // Build address of time-slice variable + 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and 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) +#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. */ -; + /* 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 + // 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. */ -; + 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! + 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_LOW_POWER PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode + BL tx_low_power_enter // Possibly enter low power mode POP {r0-r3} #endif #ifdef TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode + BL tx_low_power_exit // Exit low power mode POP {r0-r3} #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! */ -; + 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 + 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. +#if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) + // SVC_Handler is not needed when ThreadX is running in single mode. PUBLIC SVC_Handler SVC_Handler: MOVS r0, #4 MOV r1, lr - TST r1, r0 ; Determine return stack from EXC_RETURN bit 2 + 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 + 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 + 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 + 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, #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 + CMP r1, #2 // Is it a secure stack free request? + BEQ _tx_svc_secure_free // Yes, go there + + CMP r1, #3 // Is it a secure stack init request? + BEQ _tx_svc_secure_init // Yes, go there - ; Unknown SVC argument - just return + // 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 + 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 + 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 + 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 + 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 +_tx_svc_secure_init: + PUSH {r0,lr} // Save SP and EXC_RETURN + BL _tx_thread_secure_mode_stack_initialize + POP {r1, r2} // Restore SP and EXC_RETURN + MOV lr, r2 + BX lr +#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE END diff --git a/ports/cortex_m23/iar/src/tx_thread_secure_stack.c b/ports/cortex_m23/iar/src/tx_thread_secure_stack.c index b9ba72ff..4ffc8d10 100644 --- a/ports/cortex_m23/iar/src/tx_thread_secure_stack.c +++ b/ports/cortex_m23/iar/src/tx_thread_secure_stack.c @@ -62,8 +62,8 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_secure_stack_initialize Cortex-M23/IAR */ -/* 6.1.1 */ +/* _tx_thread_secure_mode_stack_initialize Cortex-M23/IAR */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -78,7 +78,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* OUTPUT */ /* */ -/* None */ +/* status */ /* */ /* CALLS */ /* */ @@ -98,21 +98,35 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Modified comment(s), changed */ +/* name, execute in handler */ +/* mode, disable optimization, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) -void _tx_thread_secure_stack_initialize(void) +UINT _tx_thread_secure_mode_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; +UINT status; + + /* Make sure function is called from interrupt (threads should not call). */ + if (__get_IPSR() == 0) + { + status = TX_CALLER_ERROR; + } + else + { + /* 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); + + status = TX_SUCCESS; + } + return status; } @@ -335,7 +349,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M23/IAR */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -370,6 +384,8 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -402,7 +418,7 @@ ULONG sp; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports/cortex_m23/iar/src/tx_thread_secure_stack_initialize.s b/ports/cortex_m23/iar/src/tx_thread_secure_stack_initialize.s new file mode 100644 index 00000000..092ed49c --- /dev/null +++ b/ports/cortex_m23/iar/src/tx_thread_secure_stack_initialize.s @@ -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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + SECTION `.text`:CODE:NOROOT(2) + THUMB +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_secure_stack_initialize Cortex-M23/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enters the SVC handler to initialize a secure stack. */ +/* */ +/* INPUT */ +/* */ +/* none */ +/* */ +/* OUTPUT */ +/* */ +/* none */ +/* */ +/* CALLS */ +/* */ +/* SVC 3 */ +/* */ +/* CALLED BY */ +/* */ +/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_secure_stack_initialize(VOID) +// { + EXPORT _tx_thread_secure_stack_initialize +_tx_thread_secure_stack_initialize: +#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) + CPSIE i // Enable interrupts for SVC call + SVC 3 + CPSID i // Disable interrupts +#else + MOV r0, #0xFF // Feature not enabled +#endif + BX lr + END diff --git a/ports/cortex_m3/ac5/inc/tx_port.h b/ports/cortex_m3/ac5/inc/tx_port.h index 8f2ce32d..80bfc9d6 100644 --- a/ports/cortex_m3/ac5/inc/tx_port.h +++ b/ports/cortex_m3/ac5/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M3/AC5 */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,7 +156,7 @@ typedef unsigned short USHORT; #ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -144,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -162,7 +199,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 @@ -176,13 +213,24 @@ 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -196,11 +244,11 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -208,18 +256,181 @@ ULONG _tx_misra_time_stamp_get(VOID); tx_thread_shell_entry, and tx_thread_terminate. */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else #define TX_THREAD_CREATE_EXTENSION(thread_ptr) #define TX_THREAD_DELETE_EXTENSION(thread_ptr) -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) + +#ifdef TX_MISRA_ENABLE + +ULONG _tx_misra_control_get(void); +void _tx_misra_control_set(ULONG value); +ULONG _tx_misra_fpccr_get(void); +void _tx_misra_vfp_touch(void); + +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + + +/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA + in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } +#else + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } #endif +/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. + If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating + this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush + the lazy FPU save, then restore the CONTROL.FPCA state. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } +#else + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } +#endif + +#else /* No VFP in use */ + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ + /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -243,16 +454,38 @@ register unsigned int _ipsr __asm("ipsr"); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -261,35 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -#ifdef TX_DISABLE_INLINE +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -297,42 +684,22 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); - -#define _tx_thread_system_return _tx_thread_system_return_inline +#endif /* TX_DISABLE_INLINE */ -static void _tx_thread_system_return_inline(void) -{ -unsigned int was_masked; - - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (_ipsr == 0) - { - was_masked = __disable_irq(); - __enable_irq(); - if (was_masked != 0) - __disable_irq(); - } -} -#endif +/* Define FPU extension for the Cortex-M. 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); /* 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-M3/AC5 Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/AC5 Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; diff --git a/ports/cortex_m3/ac5/readme_threadx.txt b/ports/cortex_m3/ac5/readme_threadx.txt index cc441de0..b7b7cee9 100644 --- a/ports/cortex_m3/ac5/readme_threadx.txt +++ b/ports/cortex_m3/ac5/readme_threadx.txt @@ -1,15 +1,14 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M3 - - Using ARM Compiler 5 (AC5) + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using ARM Compiler 5 (AC5) 1. Building the ThreadX run-time Library -First make sure you are in the "example_build" directory. Also, make sure that +Navigate to the "example_build" directory. Ensure that you have setup your path and other environment variables necessary for the AC5 -development environment. At this point you may run the build_threadx.bat batch -file. This will build the ThreadX run-time environment in the "example_build" -directory. +compiler. At this point you may run the build_threadx.bat batch file. This will +build the ThreadX run-time environment in the "example_build" directory. You should observe assembly and compilation of a series of ThreadX source files. At the end of the batch file, they are all combined into the @@ -19,20 +18,21 @@ application in order to use ThreadX. 2. Demonstration System -The ThreadX demonstration is designed to execute under the ARM -Windows-based simulator. +The ThreadX demonstration is designed to execute under the ARM DS Cortex-M +simulator. Building the demonstration is easy; simply execute the build_threadx_sample.bat -batch file while inside the "example_build" directory. +batch file while inside the "example_build" directory. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.axf -is a binary file that can be downloaded and executed on the ARM simulator. +is a binary file that can be downloaded and executed on the ARM DS Cortex-M +simulator. 3. System Initialization -The entry point in ThreadX for the Cortex-M3 using AC5 tools is at label +The entry point in ThreadX for the Cortex-M using AC5 tools is at label __main. This is defined within the AC5 compiler's startup code. In addition, this is where all static and global pre-set C variable initialization processing takes place. @@ -50,29 +50,86 @@ parameter to your application definition function, tx_application_define. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M3 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. +Non-FPU Stack Frame: - Stack Offset Stack Contents + Stack Offset Stack Contents - 0x00 r4 - 0x04 r5 - 0x08 r6 - 0x0C r7 - 0x10 r8 - 0x14 r9 - 0x18 r10 - 0x1C r11 - 0x20 r0 (Hardware stack starts here!!) - 0x24 r1 - 0x28 r2 - 0x2C r3 - 0x30 r12 - 0x34 lr - 0x38 pc - 0x3C xPSR + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 r4 Software stacked GP registers + 0x08 r5 + 0x0C r6 + 0x10 r7 + 0x14 r8 + 0x18 r9 + 0x1C r10 + 0x20 r11 + 0x24 r0 Hardware stacked registers + 0x28 r1 + 0x2C r2 + 0x30 r3 + 0x34 r12 + 0x38 lr + 0x3C pc + 0x40 xPSR + +FPU Stack Frame (only interrupted thread with FPU enabled): + + Stack Offset Stack Contents + + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 s16 Software stacked FPU registers + 0x08 s17 + 0x0C s18 + 0x10 s19 + 0x14 s20 + 0x18 s21 + 0x1C s22 + 0x20 s23 + 0x24 s24 + 0x28 s25 + 0x2C s26 + 0x30 s27 + 0x34 s28 + 0x38 s29 + 0x3C s30 + 0x40 s31 + 0x44 r4 Software stacked registers + 0x48 r5 + 0x4C r6 + 0x50 r7 + 0x54 r8 + 0x58 r9 + 0x5C r10 + 0x60 r11 + 0x64 r0 Hardware stacked registers + 0x68 r1 + 0x6C r2 + 0x70 r3 + 0x74 r12 + 0x78 lr + 0x7C pc + 0x80 xPSR + 0x84 s0 Hardware stacked FPU registers + 0x88 s1 + 0x8C s2 + 0x90 s3 + 0x94 s4 + 0x98 s5 + 0x9C s6 + 0xA0 s7 + 0xA4 s8 + 0xA8 s9 + 0xAC s10 + 0xB0 s11 + 0xB4 s12 + 0xB8 s13 + 0xBC s14 + 0xC0 s15 + 0xC4 fpscr 5. Improving Performance @@ -80,8 +137,8 @@ tx_thread_stack_ptr in the associated thread control block TX_THREAD. The distribution version of ThreadX is built without any compiler optimizations. This makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. Of course, this costs some -performance. To make it run faster, you can change the ThreadX_Library.Uv2 -project to debugging and enable all compiler optimizations. +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING @@ -90,14 +147,14 @@ defined. 6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M3 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: 6.1 Vector Area -The Cortex-M3 vectors start at the label __tx_vectors. The application may modify +The Cortex-M vectors start at the label __tx_vectors. The application may modify the vector area according to its needs. @@ -128,24 +185,23 @@ your_assembly_isr BX lr +7. FPU Support -7. Revision History +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads +can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread +context - no additional setup by the application. + + +8. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - tx_thread_schedule.s Fix compilation error - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M3 using AC5 tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using AC5 tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m3/ac5/src/tx_thread_context_restore.s b/ports/cortex_m3/ac5/src/tx_thread_context_restore.s index 14b1da0e..75d971d2 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_context_restore.s +++ b/ports/cortex_m3/ac5/src/tx_thread_context_restore.s @@ -1,91 +1,83 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_exit - ENDIF -; -; +#endif + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function restores the interrupt context if it is processing a */ -;/* nested interrupt. If not, it returns to the interrupt thread if no */ -;/* preemption is necessary. Otherwise, if preemption is necessary or */ -;/* if no thread was running, the function returns to the scheduler. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* _tx_thread_schedule Thread scheduling routine */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs Interrupt Service Routines */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_restore(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M3/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { EXPORT _tx_thread_context_restore _tx_thread_context_restore - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR exit function to indicate an ISR is complete. */ -; - PUSH {r0,lr} ; Save ISR lr - BL _tx_execution_isr_exit ; Call the ISR exit function - POP {r0,lr} ; Restore ISR lr - ENDIF -; - POP {lr} + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -;} +// } ALIGN LTORG END diff --git a/ports/cortex_m3/ac5/src/tx_thread_context_save.s b/ports/cortex_m3/ac5/src/tx_thread_context_save.s index ae21c768..d9f27da5 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_context_save.s +++ b/ports/cortex_m3/ac5/src/tx_thread_context_save.s @@ -1,91 +1,85 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_enter - ENDIF -; -; +#endif + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_save Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function saves the context of an executing thread in the */ -;/* beginning of interrupt processing. The function also ensures that */ -;/* the system stack is used upon return to the calling ISR. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* None */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M3/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { EXPORT _tx_thread_context_save _tx_thread_context_save - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR enter function to indicate an ISR is executing. */ -; - PUSH {r0, lr} ; Save ISR lr - BL _tx_execution_isr_enter ; Call the ISR enter function - POP {r0, lr} ; Recover ISR lr - ENDIF -; -; /* Return to interrupt processing. */ -; - BX lr ; Return to interrupt processing caller -;} + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + + BX lr +// } ALIGN LTORG END diff --git a/ports/cortex_m3/ac5/src/tx_thread_interrupt_control.s b/ports/cortex_m3/ac5/src/tx_thread_interrupt_control.s index 3c0f1768..bca3df55 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_interrupt_control.s +++ b/ports/cortex_m3/ac5/src/tx_thread_interrupt_control.s @@ -1,76 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_control Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_control(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M3/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { EXPORT _tx_thread_interrupt_control _tx_thread_interrupt_control -; -; /* Pickup current interrupt lockout posture. */ -; - MRS r1, PRIMASK - MSR PRIMASK, r0 - MOV r0, r1 - BX lr -; -;} +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } END diff --git a/ports/cortex_m3/ac5/src/tx_thread_interrupt_disable.s b/ports/cortex_m3/ac5/src/tx_thread_interrupt_disable.s index d66a11f0..6a9c4c8e 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_interrupt_disable.s +++ b/ports/cortex_m3/ac5/src/tx_thread_interrupt_disable.s @@ -1,75 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_disable Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_disable(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M3/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { EXPORT _tx_thread_interrupt_disable _tx_thread_interrupt_disable -; -; /* Return current interrupt lockout posture. */ -; + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else MRS r0, PRIMASK CPSID i +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m3/ac5/src/tx_thread_interrupt_restore.s b/ports/cortex_m3/ac5/src/tx_thread_interrupt_restore.s index 361af42f..ca929f18 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_interrupt_restore.s +++ b/ports/cortex_m3/ac5/src/tx_thread_interrupt_restore.s @@ -1,74 +1,75 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_disable(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M3/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { EXPORT _tx_thread_interrupt_restore _tx_thread_interrupt_restore -; -; /* Restore previous interrupt lockout posture. */ -; + + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else MSR PRIMASK, r0 +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m3/ac5/src/tx_thread_schedule.s b/ports/cortex_m3/ac5/src/tx_thread_schedule.s index b8bc8478..61371a3b 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_schedule.s +++ b/ports/cortex_m3/ac5/src/tx_thread_schedule.s @@ -1,263 +1,285 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IMPORT _tx_thread_current_ptr IMPORT _tx_thread_execute_ptr IMPORT _tx_timer_time_slice IMPORT _tx_thread_system_stack_ptr IMPORT _tx_thread_preempt_disable - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_thread_enter IMPORT _tx_execution_thread_exit - ENDIF - IF :DEF:TX_LOW_POWER - IMPORT tx_low_power_enter - IMPORT tx_low_power_exit - ENDIF -; -; - AREA ||.text||, CODE, READONLY +#endif + + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M3/AC5 */ -;/* 6.1.5 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* _tx_thread_context_restore Restore thread's context */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* 03-02-2021 Scott Larson Modified comment(s), add */ -;/* low power code, */ -;/* resulting in version 6.1.5 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_schedule(VOID) -;{ - EXPORT _tx_thread_schedule +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M3/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { + EXPORT _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 the interrupts */ -; + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __TARGET_FPU_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register +#endif + + /* Enable interrupts */ CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR - DSB ; Complete all memory accesses - ISB ; Flush pipeline -; -; /* Wait here for the PendSV to take place. */ -; + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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. */ -; + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + EXPORT __tx_PendSVHandler EXPORT PendSV_Handler __tx_PendSVHandler PendSV_Handler -; -; /* Get current thread value and new thread pointer. */ -; + + /* Get current thread value and new thread pointer. */ + __tx_ts_handler - IF :DEF: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, lr} ; Recover LR - CPSIE i ; Enable interrupts - ENDIF - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack -; -; /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -; - LDR r5, [r4] ; Pickup current time-slice - STR r12, [r1, #8] ; Save the thread stack pointer - 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. */ -; - STR r3, [r4] ; Clear time-slice -; -; /* Executing thread is now completely preserved!!! */ -; +#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 + 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 + CPSIE i // Enable interrupts +#endif + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __TARGET_FPU_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_save + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers +_skip_vfp_save +#endif + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack + + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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. */ -; + + /* 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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 + LDR r7, [r1, #4] // Pickup the current thread run count + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 +#endif + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __TARGET_FPU_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers +_skip_vfp_restore +#endif + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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. */ - IF :DEF: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 r3 - ENDIF -; -; /* Restore the thread context and PSP. */ -; - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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! + 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! - IF :DEF:TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode - POP {r0-r3} - ENDIF +#ifdef TX_LOW_POWER + BL tx_low_power_enter // Possibly enter low power mode +#endif - IF :DEF:TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed - ENDIF +#ifdef TX_ENABLE_WFI + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed +#endif - IF :DEF:TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode - POP {r0-r3} - ENDIF +#ifdef TX_LOW_POWER + BL tx_low_power_exit // Exit low power mode +#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! */ - 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 - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __TARGET_FPU_VFP + EXPORT tx_thread_fpu_enable +tx_thread_fpu_enable + EXPORT tx_thread_fpu_disable +tx_thread_fpu_disable + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller + + EXPORT _tx_vfp_access +_tx_vfp_access + VMOV.F32 s0, s0 // Simply access the VFP + BX lr // Return to caller + +#endif ALIGN LTORG diff --git a/ports/cortex_m3/ac5/src/tx_thread_stack_build.s b/ports/cortex_m3/ac5/src/tx_thread_stack_build.s index 0e0e1c9d..3c263ba8 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_stack_build.s +++ b/ports/cortex_m3/ac5/src/tx_thread_stack_build.s @@ -1,128 +1,131 @@ -;/**************************************************************************/ -;/* */ -;/* Copyright (c) Microsoft Corporation. All rights reserved. */ -;/* */ -;/**************************************************************************/ -; -; -;/**************************************************************************/ -;/**************************************************************************/ -;/** */ -;/** ThreadX Component */ -;/** */ -;/** Thread */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_stack_build Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M3/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { EXPORT _tx_thread_stack_build _tx_thread_stack_build -; -; -; /* Build a fake interrupt frame. The form of the fake interrupt stack -; on the Cortex-M3 should look like the following after it is built: -; -; Stack Top: -; LR Interrupted LR (LR at time of PENDSV) -; r4 Initial value for r4 -; r5 Initial value for r5 -; r6 Initial value for r6 -; r7 Initial value for r7 -; r8 Initial value for r8 -; r9 Initial value for r9 -; r10 Initial value for r10 -; r11 Initial value for r11 -; 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 - BIC r2, r2, #0x7 ; Align frame for 8-byte alignment - SUB r2, r2, #68 ; Subtract frame size - LDR r3, =0xFFFFFFFD ; Build initial LR value - STR r3, [r2, #0] ; Save on the stack -; -; /* Actually build the stack frame. */ -; - MOV r3, #0 ; Build initial register value - STR r3, [r2, #4] ; Store initial r4 - STR r3, [r2, #8] ; Store initial r5 - STR r3, [r2, #12] ; Store initial r6 - STR r3, [r2, #16] ; Store initial r7 - STR r3, [r2, #20] ; Store initial r8 - STR r3, [r2, #24] ; Store initial r9 - STR r3, [r2, #28] ; Store initial r10 - STR r3, [r2, #32] ; Store initial r11 -; -; /* 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 - MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value - STR r3, [r2, #56] ; Store initial lr - STR r1, [r2, #60] ; Store initial pc - MOV 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 -;} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 diff --git a/ports/cortex_m3/ac5/src/tx_thread_system_return.s b/ports/cortex_m3/ac5/src/tx_thread_system_return.s index 4988ce82..6b7d3ec3 100644 --- a/ports/cortex_m3/ac5/src/tx_thread_system_return.s +++ b/ports/cortex_m3/ac5/src/tx_thread_system_return.s @@ -1,80 +1,91 @@ -;/**************************************************************************/ -;/* */ -;/* Copyright (c) Microsoft Corporation. All rights reserved. */ -;/* */ -;/**************************************************************************/ -; -; -;/**************************************************************************/ -;/**************************************************************************/ -;/** */ -;/** ThreadX Component */ -;/** */ -;/** Thread */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_system_return Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_system_return(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M3/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { EXPORT _tx_thread_system_return _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. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 + + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif _isr_context - BX lr ; Return to caller -;} + BX lr // Return to caller +// } END diff --git a/ports/cortex_m3/ac5/src/tx_timer_interrupt.s b/ports/cortex_m3/ac5/src/tx_timer_interrupt.s index 8c20a222..60717ba3 100644 --- a/ports/cortex_m3/ac5/src/tx_timer_interrupt.s +++ b/ports/cortex_m3/ac5/src/tx_timer_interrupt.s @@ -1,21 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* Copyright (c) Microsoft Corporation. All rights reserved. */ -;/* */ -;/**************************************************************************/ -; -; -;/**************************************************************************/ -;/**************************************************************************/ -;/** */ -;/** ThreadX Component */ -;/** */ -;/** Timer */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IMPORT _tx_timer_time_slice IMPORT _tx_timer_system_clock IMPORT _tx_timer_current_ptr @@ -28,227 +32,223 @@ IMPORT _tx_thread_preempt_disable IMPORT _tx_thread_current_ptr IMPORT _tx_thread_execute_ptr -; -; + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M3/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_timer_interrupt(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M3/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { EXPORT _tx_timer_interrupt _tx_timer_interrupt -; -; /* Upon entry to this routine, it is assumed that context save has already -; been called, and therefore the compiler scratch registers are available -; for use. */ -; -; /* Increment the system clock. */ -; _tx_timer_system_clock++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock - LDR r0, [r1, #0] ; Pickup system clock - ADD r0, r0, #1 ; Increment system clock - STR r0, [r1, #0] ; Store new system clock -; -; /* Test for time-slice expiration. */ -; if (_tx_timer_time_slice) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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--; -; - SUB 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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++; -; - ADD r0, r0, #4 ; Move to next timer -; -; /* Check for wrap-around. */ -; if (_tx_timer_current_ptr == _tx_timer_list_end) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + +__tx_something_expired + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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 -; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for -; -; } -; + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired - DSB ; Complete all memory access - BX lr ; Return to caller -; -;} + DSB // Complete all memory access + BX lr // Return to caller +// } ALIGN LTORG END diff --git a/ports/cortex_m3/ac6/inc/tx_port.h b/ports/cortex_m3/ac6/inc/tx_port.h index c5a10d9c..3b23f8a8 100644 --- a/ports/cortex_m3/ac6/inc/tx_port.h +++ b/ports/cortex_m3/ac6/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M3/AC6 */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -131,46 +154,83 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#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 logic. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#endif /* 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -184,11 +244,11 @@ typedef unsigned short USHORT; #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -196,11 +256,181 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif + +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) + +#ifdef TX_MISRA_ENABLE + +ULONG _tx_misra_control_get(void); +void _tx_misra_control_set(ULONG value); +ULONG _tx_misra_fpccr_get(void); +void _tx_misra_vfp_touch(void); + +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + + +/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA + in order to ensure no lazy stacking will occur. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } +#else + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + +#endif + +/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. + If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating + this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush + the lazy FPU save, then restore the CONTROL.FPCA state. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } +#else + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } +#endif + +#else /* No VFP in use */ + #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ + /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -224,137 +454,259 @@ typedef unsigned short USHORT; #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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++; -/* This 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 +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - #endif -#ifndef TX_DISABLE_INLINE -/* Define AC6 specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; -unsigned int primask_value; + int_posture = __get_interrupt_posture(); - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) -{ - - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); -} - -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) -{ - -unsigned int primask_value; - - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); -} - -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) -{ - - __asm__ volatile (" CPSIE i": : : "memory" ); -} - - __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_ipsr_value() == 0) { - interrupt_save = __get_primask_value(); + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ #define _tx_thread_system_return _tx_thread_system_return_inline -#else +#else /* TX_DISABLE_INLINE is defined */ -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. 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); /* 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-M3/AC6 Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/AC6 Version 6.1.7 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - - #endif - - - +#endif diff --git a/ports/cortex_m3/ac6/readme_threadx.txt b/ports/cortex_m3/ac6/readme_threadx.txt index 0772cdbf..d98c90cb 100644 --- a/ports/cortex_m3/ac6/readme_threadx.txt +++ b/ports/cortex_m3/ac6/readme_threadx.txt @@ -1,41 +1,39 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M3 + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using ARM Compiler 6 (AC6) - Using the AC6 Tools -1. Import the ThreadX Projects +1. Building the ThreadX run-time Library In order to build the ThreadX library and the ThreadX demonstration, first import the 'tx' and 'sample_threadx' projects (located in the "example_build" directory) into your DS workspace. - -2. Building the ThreadX run-time Library - Building the ThreadX library is easy; simply right-click the Eclipse project "tx" and then select the "Build Project" button. You should now observe the compilation and assembly of the ThreadX library. This project build produces the ThreadX library file tx.a. -3. Demonstration System +2. Demonstration System The ThreadX demonstration is designed to execute under the DS debugger on the -MPS2_Cortex_M3 Bare Metal simulator. +MPS2_Cortex_Mx Bare Metal simulator. Building the demonstration is easy; simply right-click the Eclipse project "sample_threadx" and then select the "Build Project" button. You should now observe the compilation and assembly of the ThreadX demonstration. This project build produces the ThreadX library file sample_threadx.axf. Next, expand the demo ThreadX project folder -in the Project Explorer window, right-click on the 'cortex-m3_tx.launch' file, click -'Debug As', and then click 'cortex-m3_tx' from the submenu. This will cause the +in the Project Explorer window, right-click on the 'cortex-mx_tx.launch' file, click +'Debug As', and then click 'cortex-mx_tx' from the submenu. This will cause the debugger to load the sample_threadx.axf ELF file and run to main. You are now ready to execute the ThreadX demonstration. -4. System Initialization +3. System Initialization -The entry point in ThreadX for the Cortex-M3 using AC6 tools uses the standard AC6 -Cortex-M3 reset sequence. From the reset vector the C runtime will be initialized. +The entry point in ThreadX for the Cortex-M using AC6 tools uses the standard GNU +Cortex-M reset sequence. From the reset vector the C runtime will be initialized. The ThreadX tx_initialize_low_level.S file is responsible for setting up various system data structures, the vector area, and a periodic timer interrupt @@ -46,86 +44,133 @@ address for use by the application, which is supplied as the sole input parameter to your application definition function, tx_application_define. -5. Register Usage and Stack Frames +4. Register Usage and Stack Frames The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M3 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. +Non-FPU Stack Frame: - Stack Offset Stack Contents + Stack Offset Stack Contents - 0x00 r4 - 0x04 r5 - 0x08 r6 - 0x0C r7 - 0x10 r8 - 0x14 r9 - 0x18 r10 - 0x1C r11 - 0x20 r0 (Hardware stack starts here!!) - 0x24 r1 - 0x28 r2 - 0x2C r3 - 0x30 r12 - 0x34 lr - 0x38 pc - 0x3C xPSR + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 r4 Software stacked GP registers + 0x08 r5 + 0x0C r6 + 0x10 r7 + 0x14 r8 + 0x18 r9 + 0x1C r10 + 0x20 r11 + 0x24 r0 Hardware stacked registers + 0x28 r1 + 0x2C r2 + 0x30 r3 + 0x34 r12 + 0x38 lr + 0x3C pc + 0x40 xPSR + +FPU Stack Frame (only interrupted thread with FPU enabled): + + Stack Offset Stack Contents + + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 s16 Software stacked FPU registers + 0x08 s17 + 0x0C s18 + 0x10 s19 + 0x14 s20 + 0x18 s21 + 0x1C s22 + 0x20 s23 + 0x24 s24 + 0x28 s25 + 0x2C s26 + 0x30 s27 + 0x34 s28 + 0x38 s29 + 0x3C s30 + 0x40 s31 + 0x44 r4 Software stacked registers + 0x48 r5 + 0x4C r6 + 0x50 r7 + 0x54 r8 + 0x58 r9 + 0x5C r10 + 0x60 r11 + 0x64 r0 Hardware stacked registers + 0x68 r1 + 0x6C r2 + 0x70 r3 + 0x74 r12 + 0x78 lr + 0x7C pc + 0x80 xPSR + 0x84 s0 Hardware stacked FPU registers + 0x88 s1 + 0x8C s2 + 0x90 s3 + 0x94 s4 + 0x98 s5 + 0x9C s6 + 0xA0 s7 + 0xA4 s8 + 0xA8 s9 + 0xAC s10 + 0xB0 s11 + 0xB4 s12 + 0xB8 s13 + 0xBC s14 + 0xC0 s15 + 0xC4 fpscr -6. Improving Performance +5. Improving Performance -The distribution version of ThreadX is built without any compiler optimizations. -This makes it easy to debug because you can trace or set breakpoints inside of -ThreadX itself. Of course, this costs some performance. To make it run faster, -you can change the build_threadx.bat file to remove the -g option and enable -all compiler optimizations. +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING defined. -7. Interrupt Handling +6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M3 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: -7.1 Vector Area +6.1 Vector Area -The Cortex-M3 vectors start at the label __tx_vectors or similar. The application may modify +The Cortex-M vectors start at the label __tx_vectors or similar. The application may modify the vector area according to its needs. There is code in tx_initialize_low_level() that will configure the vector base register. -7.2 Managed Interrupts +6.2 Managed Interrupts -ISRs can be written completely in C (or assembly language) without any calls to -_tx_thread_context_save or _tx_thread_context_restore. These ISRs are allowed access to the -ThreadX API that is available to ISRs. - -ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): - -void your_C_isr(void) -{ - - /* ISR processing goes here, including any needed function calls. */ -} - -ISRs written in assembly language will take the form: +A ThreadX managed interrupt is defined below. By following these conventions, the +application ISR is then allowed access to various ThreadX services from the ISR. +Here is the standard template for managed ISRs in ThreadX: - .global your_assembly_isr + .global __tx_IntHandler .thumb_func -your_assembly_isr: -; VOID your_assembly_isr(VOID) +__tx_IntHandler: +; VOID InterruptHandler (VOID) ; { PUSH {r0, lr} -; + ; /* Do interrupt handler work here */ ; /* BL */ @@ -133,29 +178,31 @@ your_assembly_isr: BX lr ; } -Note: the Cortex-M3 requires exception handlers to be thumb labels, this implies bit 0 set. + +Note: the Cortex-M requires exception handlers to be thumb labels, this implies bit 0 set. To accomplish this, the declaration of the label has to be preceded by the assembler directive .thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to be inserted in the correct location in the interrupt vector table. This table is typically located in either your runtime startup file or in the tx_initialize_low_level.S file. +7. FPU Support + +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads +can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread +context - no additional setup by the application. + + 8. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M3 using AC6 tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using AC6 tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m3/ac6/src/tx_thread_context_restore.S b/ports/cortex_m3/ac6/src/tx_thread_context_restore.S index db417745..5159d0a3 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_context_restore.S +++ b/ports/cortex_m3/ac6/src/tx_thread_context_restore.S @@ -1,86 +1,81 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr - .global _tx_thread_system_stack_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_schedule - .global _tx_thread_preempt_disable -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_restore Cortex-M3/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function restores the interrupt context if it is processing a */ -@/* nested interrupt. If not, it returns to the interrupt thread if no */ -@/* preemption is necessary. Otherwise, if preemption is necessary or */ -@/* if no thread was running, the function returns to the scheduler. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* _tx_thread_schedule Thread scheduling routine */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs Interrupt Service Routines */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_restore(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M3/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { .global _tx_thread_context_restore .thumb_func _tx_thread_context_restore: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -@} +// } diff --git a/ports/cortex_m3/ac6/src/tx_thread_context_save.S b/ports/cortex_m3/ac6/src/tx_thread_context_save.S index e6acd5bb..0e8dd3bd 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_context_save.S +++ b/ports/cortex_m3/ac6/src/tx_thread_context_save.S @@ -1,80 +1,83 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_save Cortex-M3/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function saves the context of an executing thread in the */ -@/* beginning of interrupt processing. The function also ensures that */ -@/* the system stack is used upon return to the calling ISR. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* None */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_save(VOID) -@{ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_enter +#endif +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M3/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { .global _tx_thread_context_save .thumb_func _tx_thread_context_save: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr -@} +// } diff --git a/ports/cortex_m3/ac6/src/tx_thread_interrupt_control.S b/ports/cortex_m3/ac6/src/tx_thread_interrupt_control.S index ce0f19de..1f6a3f11 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_interrupt_control.S +++ b/ports/cortex_m3/ac6/src/tx_thread_interrupt_control.S @@ -1,81 +1,79 @@ -@/**************************************************************************/ -@/* */ -@/* 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. */ -@/* */ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ - +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_interrupt_control Cortex-M3/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* UINT _tx_thread_interrupt_control(UINT new_posture) -{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M3/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { .global _tx_thread_interrupt_control .thumb_func _tx_thread_interrupt_control: - -@/* Pickup current interrupt lockout posture. */ - - MRS r1, PRIMASK @ Pickup current interrupt lockout - -@/* Apply the new interrupt posture. */ - - MSR PRIMASK, r0 @ Apply the new interrupt lockout - MOV r0, r1 @ Transfer old to return register - BX lr @ Return to caller - -@/* } */ +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } diff --git a/ports/cortex_m3/ac6/src/tx_thread_interrupt_disable.S b/ports/cortex_m3/ac6/src/tx_thread_interrupt_disable.S new file mode 100644 index 00000000..93159485 --- /dev/null +++ b/ports/cortex_m3/ac6/src/tx_thread_interrupt_disable.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M3/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { + .global _tx_thread_interrupt_disable + .thumb_func +_tx_thread_interrupt_disable: + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else + MRS r0, PRIMASK + CPSID i +#endif + BX lr +// } diff --git a/ports/cortex_m33/ac5/src/tx_thread_stack_error_notify.c b/ports/cortex_m3/ac6/src/tx_thread_interrupt_restore.S similarity index 73% rename from ports/cortex_m33/ac5/src/tx_thread_stack_error_notify.c rename to ports/cortex_m3/ac6/src/tx_thread_interrupt_restore.S index 0ad24a46..c060ec5f 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_stack_error_notify.c +++ b/ports/cortex_m3/ac6/src/tx_thread_interrupt_restore.S @@ -20,41 +20,31 @@ /**************************************************************************/ /**************************************************************************/ -#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); - + .text 32 + .align 4 + .syntax unified /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_stack_error_notify Cortex-M33 */ -/* 6.1 */ +/* _tx_thread_interrupt_restore Cortex-M3/AC6 */ +/* 6.1.7 */ /* 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. */ -/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ /* */ /* INPUT */ /* */ -/* stack_error_handler Pointer to stack error */ -/* handler, TX_NULL to disable */ +/* previous_posture Previous interrupt posture */ /* */ /* OUTPUT */ /* */ -/* status Service return status */ +/* None */ /* */ /* CALLS */ /* */ @@ -68,29 +58,19 @@ extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr) /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ -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); -} +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { + .global _tx_thread_interrupt_restore + .thumb_func +_tx_thread_interrupt_restore: + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else + MSR PRIMASK, r0 +#endif + BX lr +// } diff --git a/ports/cortex_m3/ac6/src/tx_thread_schedule.S b/ports/cortex_m3/ac6/src/tx_thread_schedule.S index 1998d02a..f93ea4e2 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_schedule.S +++ b/ports/cortex_m3/ac6/src/tx_thread_schedule.S @@ -1,262 +1,286 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_current_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_system_stack_ptr +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_thread_current_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit +#endif #ifdef TX_LOW_POWER .global tx_low_power_enter .global tx_low_power_exit #endif - -@ -@ .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_schedule Cortex-M3/AC6 */ -@/* 6.1.5 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* _tx_thread_context_restore Restore thread's context */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* 03-02-2021 Scott Larson Modified comment(s), add */ -@/* low power code, */ -@/* resulting in version 6.1.5 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_schedule(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M3/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { .global _tx_thread_schedule .thumb_func _tx_thread_schedule: -@ -@ /* This function should only ever be called on Cortex-M3 -@ from the first schedule request. Subsequent scheduling occurs -@ from the PendSV handling routines below. */ -@ -@ /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -@ - MOV 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 */ -@ + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __ARM_PCS_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register +#endif + + /* Enable interrupts */ CPSIE i -@ -@ /* Enter the scheduler for the first time. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ Set PENDSVBIT in ICSR - DSB @ Complete all memory accesses - ISB @ Flush pipeline -@ -@ /* Wait here for the PendSV to take place. */ -@ + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 switch-out switch-in handler... Note that this handler is -@ common for both PendSV and SVCall. */ -@ + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + .global PendSV_Handler .global __tx_PendSVHandler + .syntax unified .thumb_func PendSV_Handler: .thumb_func __tx_PendSVHandler: -@ -@ /* Get current thread value and new thread pointer. */ -@ + + /* Get current thread value and new thread pointer. */ + __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, lr} @ Recover LR - CPSIE i @ Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - MOV 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 r12, PSP @ Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} @ Save its remaining registers - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - STMDB r12!, {LR} @ Save LR on the stack -@ -@ /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -@ - LDR r5, [r4] @ Pickup current time-slice - STR r12, [r1, #8] @ Save the thread stack pointer - 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. */ -@ - STR r3, [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 - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - LDR r5, [r1, #24] @ Pickup thread's current time-slice - ADD 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 r3 + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_save + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers +_skip_vfp_save: #endif -@ -@ /* Restore the thread context and PSP. */ -@ - LDR r12, [r1, #8] @ Pickup thread's stack pointer - LDMIA r12!, {LR} @ Pickup LR - LDMIA r12!, {r4-r11} @ Recover thread's registers - MSR PSP, r12 @ 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. */ -@ + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack + + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 +#endif + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers +_skip_vfp_restore: +#endif + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter @ Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB @ Ensure no outstanding memory transactions - WFI @ Wait for interrupt - ISB @ Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit @ Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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! */ -@ + 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: - MOV r7, #0x08000000 @ Build clear PendSV value - MOV r8, #0xE000E000 @ Build base NVIC address - STR r7, [r8, #0xD04] @ Clear any PendSV -@ -@ /* Re-enable interrupts and restore new thread. */ -@ - CPSIE i @ Enable interrupts - B __tx_ts_restore @ Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __ARM_PCS_VFP + + .global tx_thread_fpu_enable + .thumb_func +tx_thread_fpu_enable: + .global tx_thread_fpu_disable + .thumb_func +tx_thread_fpu_disable: + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller + +#endif diff --git a/ports/cortex_m3/ac6/src/tx_thread_stack_build.S b/ports/cortex_m3/ac6/src/tx_thread_stack_build.S index 5643695f..70aec7a7 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_stack_build.S +++ b/ports/cortex_m3/ac6/src/tx_thread_stack_build.S @@ -1,135 +1,133 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_stack_build Cortex-M3/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M3/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { .global _tx_thread_stack_build .thumb_func _tx_thread_stack_build: -@ -@ -@ /* Build a fake interrupt frame. The form of the fake interrupt stack -@ on the Cortex-M3 should look like the following after it is built: -@ -@ Stack Top: -@ LR Interrupted LR (LR at time of PENDSV) -@ r4 Initial value for r4 -@ r5 Initial value for r5 -@ r6 Initial value for r6 -@ r7 Initial value for r7 -@ r8 Initial value for r8 -@ r9 Initial value for r9 -@ r10 Initial value for r10 -@ r11 Initial value for r11 -@ 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 - BIC r2, r2, #0x7 @ Align frame - SUB r2, r2, #68 @ Subtract frame size - LDR r3, =0xFFFFFFFD @ Build initial LR value - STR r3, [r2, #0] @ Save on the stack -@ -@ /* Actually build the stack frame. */ -@ - MOV r3, #0 @ Build initial register value - STR r3, [r2, #4] @ Store initial r4 - STR r3, [r2, #8] @ Store initial r5 - STR r3, [r2, #12] @ Store initial r6 - STR r3, [r2, #16] @ Store initial r7 - STR r3, [r2, #20] @ Store initial r8 - STR r3, [r2, #24] @ Store initial r9 - STR r3, [r2, #28] @ Store initial r10 - STR r3, [r2, #32] @ Store initial r11 -@ -@ /* 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 - MOV r3, #0xFFFFFFFF @ Poison EXC_RETURN value - STR r3, [r2, #56] @ Store initial lr - STR r1, [r2, #60] @ Store initial pc - MOV 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 -@} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 +// } diff --git a/ports/cortex_m3/ac6/src/tx_thread_system_return.S b/ports/cortex_m3/ac6/src/tx_thread_system_return.S index cccfcb9c..3a24f007 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m3/ac6/src/tx_thread_system_return.S @@ -1,88 +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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_system_return Cortex-M3/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* VOID _tx_thread_system_return(VOID) -@{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M3/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { .thumb_func .global _tx_thread_system_return _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. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ 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 -@/* } */ + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif +_isr_context: + BX lr // Return to caller +// } diff --git a/ports/cortex_m3/ac6/src/tx_timer_interrupt.S b/ports/cortex_m3/ac6/src/tx_timer_interrupt.S index 35edc665..752e337f 100644 --- a/ports/cortex_m3/ac6/src/tx_timer_interrupt.S +++ b/ports/cortex_m3/ac6/src/tx_timer_interrupt.S @@ -1,257 +1,250 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_timer_time_slice - .global _tx_timer_system_clock - .global _tx_timer_current_ptr - .global _tx_timer_list_start - .global _tx_timer_list_end - .global _tx_timer_expired_time_slice - .global _tx_timer_expired - .global _tx_thread_time_slice - .global _tx_timer_expiration_process -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_timer_time_slice + .global _tx_timer_system_clock + .global _tx_timer_current_ptr + .global _tx_timer_list_start + .global _tx_timer_list_end + .global _tx_timer_expired_time_slice + .global _tx_timer_expired + .global _tx_thread_time_slice + .global _tx_timer_expiration_process + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_timer_interrupt Cortex-M3/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_timer_interrupt(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M3/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { .global _tx_timer_interrupt .thumb_func _tx_timer_interrupt: -@ -@ /* Upon entry to this routine, it is assumed that context save has already -@ been called, and therefore the compiler scratch registers are available -@ for use. */ -@ -@ /* Increment the system clock. */ -@ _tx_timer_system_clock++; -@ - LDR r1, =_tx_timer_system_clock @ Pickup address of system clock - LDR r0, [r1, #0] @ Pickup system clock - ADD r0, r0, #1 @ Increment system clock - STR r0, [r1, #0] @ Store new system clock -@ -@ /* Test for time-slice expiration. */ -@ if (_tx_timer_time_slice) -@ { -@ - LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice - LDR r2, [r3, #0] @ Pickup time-slice - CMP r2, #0 @ Is it non-active? - BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing -@ -@ /* Decrement the time_slice. */ -@ _tx_timer_time_slice--; -@ - SUB 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) -@ - CMP r2, #0 @ Has it expired? - BNE __tx_timer_no_time_slice @ No, skip expiration processing -@ -@ /* Set the time-slice expired flag. */ -@ _tx_timer_expired_time_slice = TX_TRUE; -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag - MOV r0, #1 @ Build expired value - STR r0, [r3, #0] @ Set time-slice expiration flag -@ -@ } -@ + + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) -@ { -@ - LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address - LDR r0, [r1, #0] @ Pickup current timer - LDR r2, [r0, #0] @ Pickup timer list entry - CMP r2, #0 @ Is there anything in the list? - BEQ __tx_timer_no_timer @ No, just increment the timer -@ -@ /* Set expiration flag. */ -@ _tx_timer_expired = TX_TRUE; -@ - LDR r3, =_tx_timer_expired @ Pickup expiration flag address - MOV r2, #1 @ Build expired value - STR r2, [r3, #0] @ Set expired flag - B __tx_timer_done @ Finished timer processing -@ -@ } -@ else -@ { + + /* Test for timer expiration. */ + // if (*_tx_timer_current_ptr) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; -@ - ADD r0, r0, #4 @ Move to next timer -@ -@ /* Check for wrap-around. */ -@ if (_tx_timer_current_ptr == _tx_timer_list_end) -@ - LDR r3, =_tx_timer_list_end @ Pickup addr of 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; -@ - LDR r3, =_tx_timer_list_start @ Pickup addr of timer list start - LDR r0, [r3, #0] @ Set current pointer to list start -@ + + /* No timer expired, increment the timer pointer. */ + // _tx_timer_current_ptr++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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 -@ } -@ + + 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)) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of expired flag - LDR r2, [r3, #0] @ Pickup time-slice expired flag - CMP r2, #0 @ Did a time-slice expire? - BNE __tx_something_expired @ If non-zero, time-slice expired - LDR r1, =_tx_timer_expired @ Pickup addr of other expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Did a timer expire? - BEQ __tx_timer_nothing_expired @ No, nothing expired -@ + + /* See if anything has expired. */ + // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + __tx_something_expired: -@ -@ - STMDB sp!, {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) -@ { -@ - LDR r1, =_tx_timer_expired @ Pickup addr of expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Check for timer expiration - BEQ __tx_timer_dont_activate @ If not set, skip timer activation -@ -@ /* Process timer expiration. */ -@ _tx_timer_expiration_process(); -@ - BL _tx_timer_expiration_process @ Call the timer expiration handling routine -@ -@ } + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of time-slice expired - LDR r2, [r3, #0] @ Pickup the actual flag - CMP r2, #0 @ See if the flag is set - BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing -@ -@ /* Time slice interrupted thread. */ -@ _tx_thread_time_slice(); -@ - BL _tx_thread_time_slice @ Call time-slice processing - LDR r0, =_tx_thread_preempt_disable @ Build address of preempt disable flag - LDR r1, [r0] @ Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice @ Yes, skip the PendSV logic - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r1, [r0] @ Pickup the current thread pointer - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - 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 + + /* Did time slice expire? */ + // if (_tx_timer_expired_time_slice) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -@ - LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for - @ the 8-byte stack alignment -@ -@ } -@ + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB @ Complete all memory access - BX lr @ Return to caller -@ -@} + DSB // Complete all memory access + BX lr // Return to caller +// } diff --git a/ports/cortex_m3/gnu/inc/tx_port.h b/ports/cortex_m3/gnu/inc/tx_port.h index f70397a3..4e2d3823 100644 --- a/ports/cortex_m3/gnu/inc/tx_port.h +++ b/ports/cortex_m3/gnu/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M3/GNU */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,16 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -/* 09-30-2020 William E. Lamie Modified comment(s), */ -/* resulting in version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -64,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -76,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -86,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -113,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,46 +154,83 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#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 logic. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#endif /* 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -186,11 +244,11 @@ typedef unsigned short USHORT; #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -198,11 +256,181 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif + +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) + +#ifdef TX_MISRA_ENABLE + +ULONG _tx_misra_control_get(void); +void _tx_misra_control_set(ULONG value); +ULONG _tx_misra_fpccr_get(void); +void _tx_misra_vfp_touch(void); + +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + + +/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA + in order to ensure no lazy stacking will occur. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } +#else + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + +#endif + +/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. + If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating + this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush + the lazy FPU save, then restore the CONTROL.FPCA state. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } +#else + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } +#endif + +#else /* No VFP in use */ + #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ + /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -226,137 +454,259 @@ typedef unsigned short USHORT; #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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++; -/* This 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 +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - #endif -#ifndef TX_DISABLE_INLINE -/* Define GNU specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; -unsigned int primask_value; + int_posture = __get_interrupt_posture(); - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) -{ - - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); -} - -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) -{ - -unsigned int primask_value; - - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); -} - -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) -{ - - __asm__ volatile (" CPSIE i": : : "memory" ); -} - - __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_ipsr_value() == 0) { - interrupt_save = __get_primask_value(); + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ #define _tx_thread_system_return _tx_thread_system_return_inline -#else +#else /* TX_DISABLE_INLINE is defined */ -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. 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); /* 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-M3/GNU Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/GNU Version 6.1.7 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - - #endif - - - +#endif diff --git a/ports/cortex_m3/gnu/readme_threadx.txt b/ports/cortex_m3/gnu/readme_threadx.txt index ea4f807d..d9063d65 100644 --- a/ports/cortex_m3/gnu/readme_threadx.txt +++ b/ports/cortex_m3/gnu/readme_threadx.txt @@ -1,12 +1,13 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M3 - + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) Using the GNU Tools + 1. Building the ThreadX run-time Library -First make sure you are in the "example_build" directory. Also, make sure that +Navigate to the "example_build" directory. Ensure that you have setup your path and other environment variables necessary for the ARM -gnu (GNU) compiler. At this point you may run the build_threadx.bat batch file. +GNU compiler. At this point you may run the build_threadx.bat batch file. This will build the ThreadX run-time environment in the "example_build" directory. @@ -16,13 +17,13 @@ run-time library file: tx.a. This file must be linked with your application in order to use ThreadX. -2. Demonstration System for Cortex-M3 +2. Demonstration System -The ThreadX demonstration is designed to execute on Cortex-M3 evaluation boards +The ThreadX demonstration is designed to execute on Cortex-M evaluation boards or on a dedicated simulator. Building the demonstration is easy, simply execute the build_threadx_sample.bat -batch file while inside the "example_build" directory. +batch file while inside the "example_build" directory. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.out is a binary @@ -31,8 +32,8 @@ file that can be downloaded and executed on the a simulator, or downloaded to a 3. System Initialization -The entry point in ThreadX for the Cortex-M3 using gnu tools uses the standard GNU -Cortex-M3 reset sequence. From the reset vector the C runtime will be initialized. +The entry point in ThreadX for the Cortex-M using gnu tools uses the standard GNU +Cortex-M reset sequence. From the reset vector the C runtime will be initialized. The ThreadX tx_initialize_low_level.S file is responsible for setting up various system data structures, the vector area, and a periodic timer interrupt @@ -47,29 +48,86 @@ parameter to your application definition function, tx_application_define. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M3 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. +Non-FPU Stack Frame: - Stack Offset Stack Contents + Stack Offset Stack Contents - 0x00 r4 - 0x04 r5 - 0x08 r6 - 0x0C r7 - 0x10 r8 - 0x14 r9 - 0x18 r10 - 0x1C r11 - 0x20 r0 (Hardware stack starts here!!) - 0x24 r1 - 0x28 r2 - 0x2C r3 - 0x30 r12 - 0x34 lr - 0x38 pc - 0x3C xPSR + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 r4 Software stacked GP registers + 0x08 r5 + 0x0C r6 + 0x10 r7 + 0x14 r8 + 0x18 r9 + 0x1C r10 + 0x20 r11 + 0x24 r0 Hardware stacked registers + 0x28 r1 + 0x2C r2 + 0x30 r3 + 0x34 r12 + 0x38 lr + 0x3C pc + 0x40 xPSR + +FPU Stack Frame (only interrupted thread with FPU enabled): + + Stack Offset Stack Contents + + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 s16 Software stacked FPU registers + 0x08 s17 + 0x0C s18 + 0x10 s19 + 0x14 s20 + 0x18 s21 + 0x1C s22 + 0x20 s23 + 0x24 s24 + 0x28 s25 + 0x2C s26 + 0x30 s27 + 0x34 s28 + 0x38 s29 + 0x3C s30 + 0x40 s31 + 0x44 r4 Software stacked registers + 0x48 r5 + 0x4C r6 + 0x50 r7 + 0x54 r8 + 0x58 r9 + 0x5C r10 + 0x60 r11 + 0x64 r0 Hardware stacked registers + 0x68 r1 + 0x6C r2 + 0x70 r3 + 0x74 r12 + 0x78 lr + 0x7C pc + 0x80 xPSR + 0x84 s0 Hardware stacked FPU registers + 0x88 s1 + 0x8C s2 + 0x90 s3 + 0x94 s4 + 0x98 s5 + 0x9C s6 + 0xA0 s7 + 0xA4 s8 + 0xA8 s9 + 0xAC s10 + 0xB0 s11 + 0xB4 s12 + 0xB8 s13 + 0xBC s14 + 0xC0 s15 + 0xC4 fpscr 5. Improving Performance @@ -87,42 +145,32 @@ defined. 6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M3 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: 6.1 Vector Area -The Cortex-M3 vectors start at the label __tx_vectors or similar. The application may modify +The Cortex-M vectors start at the label __tx_vectors or similar. The application may modify the vector area according to its needs. There is code in tx_initialize_low_level() that will configure the vector base register. 6.2 Managed Interrupts -ISRs can be written completely in C (or assembly language) without any calls to -_tx_thread_context_save or _tx_thread_context_restore. These ISRs are allowed access to the -ThreadX API that is available to ISRs. - -ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): - -void your_C_isr(void) -{ - - /* ISR processing goes here, including any needed function calls. */ -} - -ISRs written in assembly language will take the form: +A ThreadX managed interrupt is defined below. By following these conventions, the +application ISR is then allowed access to various ThreadX services from the ISR. +Here is the standard template for managed ISRs in ThreadX: - .global your_assembly_isr + .global __tx_IntHandler .thumb_func -your_assembly_isr: -; VOID your_assembly_isr(VOID) +__tx_IntHandler: +; VOID InterruptHandler (VOID) ; { PUSH {r0, lr} -; + ; /* Do interrupt handler work here */ ; /* BL */ @@ -130,34 +178,31 @@ your_assembly_isr: BX lr ; } -Note: the Cortex-M3 requires exception handlers to be thumb labels, this implies bit 0 set. + +Note: the Cortex-M requires exception handlers to be thumb labels, this implies bit 0 set. To accomplish this, the declaration of the label has to be preceded by the assembler directive .thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to be inserted in the correct location in the interrupt vector table. This table is typically located in either your runtime startup file or in the tx_initialize_low_level.S file. -7. Revision History +7. FPU Support + +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads +can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread +context - no additional setup by the application. + + +8. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 ThreadX update of Cortex-M3/GNU port. The following files were - changed/added for port specific version 6.1: - - *.S Modified comments and whitespace. - -05/19/2020 Initial ThreadX 6.0 version for Cortex-M3 using GNU tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using GNU tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m3/gnu/src/tx_thread_context_restore.S b/ports/cortex_m3/gnu/src/tx_thread_context_restore.S index 8b99ed12..017a8809 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_context_restore.S +++ b/ports/cortex_m3/gnu/src/tx_thread_context_restore.S @@ -1,89 +1,81 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr - .global _tx_thread_system_stack_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_schedule - .global _tx_thread_preempt_disable - .global _tx_execution_isr_exit -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_restore Cortex-M3/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function restores the interrupt context if it is processing a */ -@/* nested interrupt. If not, it returns to the interrupt thread if no */ -@/* preemption is necessary. Otherwise, if preemption is necessary or */ -@/* if no thread was running, the function returns to the scheduler. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* _tx_thread_schedule Thread scheduling routine */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs Interrupt Service Routines */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_restore(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M3/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { .global _tx_thread_context_restore .thumb_func _tx_thread_context_restore: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -@} +// } diff --git a/ports/cortex_m3/gnu/src/tx_thread_context_save.S b/ports/cortex_m3/gnu/src/tx_thread_context_save.S index 08c41b49..f45292d8 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_context_save.S +++ b/ports/cortex_m3/gnu/src/tx_thread_context_save.S @@ -1,84 +1,80 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr - .global _tx_execution_isr_enter -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_save Cortex-M3/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function saves the context of an executing thread in the */ -@/* beginning of interrupt processing. The function also ensures that */ -@/* the system stack is used upon return to the calling ISR. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* None */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 Scott Larson Modified comment(s), and */ -@/* cleaned up whitespace, */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_save(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M3/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_enter] Execution profiling ISR enter */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { .global _tx_thread_context_save .thumb_func _tx_thread_context_save: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr -@} +// } diff --git a/ports/cortex_m3/gnu/src/tx_thread_interrupt_control.S b/ports/cortex_m3/gnu/src/tx_thread_interrupt_control.S index 9fa37ca2..309053a8 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_interrupt_control.S +++ b/ports/cortex_m3/gnu/src/tx_thread_interrupt_control.S @@ -1,84 +1,79 @@ -@/**************************************************************************/ -@/* */ -@/* 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. */ -@/* */ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ - +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_interrupt_control Cortex-M3/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 Scott Larson Modified comment(s), and */ -@/* cleaned up whitespace, */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* UINT _tx_thread_interrupt_control(UINT new_posture) -{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M3/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { .global _tx_thread_interrupt_control .thumb_func _tx_thread_interrupt_control: - -@/* Pickup current interrupt lockout posture. */ - - MRS r1, PRIMASK @ Pickup current interrupt lockout - -@/* Apply the new interrupt posture. */ - - MSR PRIMASK, r0 @ Apply the new interrupt lockout - MOV r0, r1 @ Transfer old to return register - BX lr @ Return to caller - -@/* } */ +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } diff --git a/ports/cortex_m3/gnu/src/tx_thread_interrupt_disable.S b/ports/cortex_m3/gnu/src/tx_thread_interrupt_disable.S new file mode 100644 index 00000000..7da1fe8a --- /dev/null +++ b/ports/cortex_m3/gnu/src/tx_thread_interrupt_disable.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M3/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { + .global _tx_thread_interrupt_disable + .thumb_func +_tx_thread_interrupt_disable: + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else + MRS r0, PRIMASK + CPSID i +#endif + BX lr +// } diff --git a/ports/cortex_m23/ac5/src/tx_thread_stack_error_notify.c b/ports/cortex_m3/gnu/src/tx_thread_interrupt_restore.S similarity index 73% rename from ports/cortex_m23/ac5/src/tx_thread_stack_error_notify.c rename to ports/cortex_m3/gnu/src/tx_thread_interrupt_restore.S index ffd78d08..136b56b7 100644 --- a/ports/cortex_m23/ac5/src/tx_thread_stack_error_notify.c +++ b/ports/cortex_m3/gnu/src/tx_thread_interrupt_restore.S @@ -20,41 +20,31 @@ /**************************************************************************/ /**************************************************************************/ -#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); - + .text 32 + .align 4 + .syntax unified /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_stack_error_notify Cortex-M23 */ -/* 6.1 */ +/* _tx_thread_interrupt_restore Cortex-M3/GNU */ +/* 6.1.7 */ /* 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. */ -/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ /* */ /* INPUT */ /* */ -/* stack_error_handler Pointer to stack error */ -/* handler, TX_NULL to disable */ +/* previous_posture Previous interrupt posture */ /* */ /* OUTPUT */ /* */ -/* status Service return status */ +/* None */ /* */ /* CALLS */ /* */ @@ -68,29 +58,19 @@ extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr) /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ -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); -} +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { + .global _tx_thread_interrupt_restore + .thumb_func +_tx_thread_interrupt_restore: + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else + MSR PRIMASK, r0 +#endif + BX lr +// } diff --git a/ports/cortex_m3/gnu/src/tx_thread_schedule.S b/ports/cortex_m3/gnu/src/tx_thread_schedule.S index b9227c28..9ee1d9f7 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_schedule.S +++ b/ports/cortex_m3/gnu/src/tx_thread_schedule.S @@ -1,265 +1,284 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_current_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_system_stack_ptr - .global _tx_execution_thread_enter - .global _tx_execution_thread_exit +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_thread_current_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit #ifdef TX_LOW_POWER .global tx_low_power_enter .global tx_low_power_exit #endif -@ -@ .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_schedule Cortex-M3/GNU */ -@/* 6.1.5 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* _tx_thread_context_restore Restore thread's context */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* 03-02-2021 Scott Larson Modified comment(s), add */ -@/* low power code, */ -@/* resulting in version 6.1.5 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_schedule(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M3/GNU */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { .global _tx_thread_schedule .thumb_func _tx_thread_schedule: -@ -@ /* This function should only ever be called on Cortex-M3 -@ from the first schedule request. Subsequent scheduling occurs -@ from the PendSV handling routines below. */ -@ -@ /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -@ - MOV 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 */ -@ + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __ARM_PCS_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register +#endif + + /* Enable interrupts */ CPSIE i -@ -@ /* Enter the scheduler for the first time. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ Set PENDSVBIT in ICSR - DSB @ Complete all memory accesses - ISB @ Flush pipeline -@ -@ /* Wait here for the PendSV to take place. */ -@ + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 switch-out switch-in handler... Note that this handler is -@ common for both PendSV and SVCall. */ -@ + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + .global PendSV_Handler .global __tx_PendSVHandler + .syntax unified .thumb_func PendSV_Handler: .thumb_func __tx_PendSVHandler: -@ -@ /* Get current thread value and new thread pointer. */ -@ + + /* Get current thread value and new thread pointer. */ + __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, lr} @ Recover LR - CPSIE i @ Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - MOV 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 r12, PSP @ Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} @ Save its remaining registers - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - STMDB r12!, {LR} @ Save LR on the stack -@ -@ /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -@ - LDR r5, [r4] @ Pickup current time-slice - STR r12, [r1, #8] @ Save the thread stack pointer - 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. */ -@ - STR r3, [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 - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - LDR r5, [r1, #24] @ Pickup thread's current time-slice - ADD 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 r3 + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_save + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers +_skip_vfp_save: #endif -@ -@ /* Restore the thread context and PSP. */ -@ - LDR r12, [r1, #8] @ Pickup thread's stack pointer - LDMIA r12!, {LR} @ Pickup LR - LDMIA r12!, {r4-r11} @ Recover thread's registers - MSR PSP, r12 @ 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. */ -@ + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack + + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 +#endif + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers +_skip_vfp_restore: +#endif + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter @ Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB @ Ensure no outstanding memory transactions - WFI @ Wait for interrupt - ISB @ Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit @ Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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! */ -@ + 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: - MOV r7, #0x08000000 @ Build clear PendSV value - MOV r8, #0xE000E000 @ Build base NVIC address - STR r7, [r8, #0xD04] @ Clear any PendSV -@ -@ /* Re-enable interrupts and restore new thread. */ -@ - CPSIE i @ Enable interrupts - B __tx_ts_restore @ Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __ARM_PCS_VFP + + .global tx_thread_fpu_enable + .thumb_func +tx_thread_fpu_enable: + .global tx_thread_fpu_disable + .thumb_func +tx_thread_fpu_disable: + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller + +#endif diff --git a/ports/cortex_m3/gnu/src/tx_thread_stack_build.S b/ports/cortex_m3/gnu/src/tx_thread_stack_build.S index 37871fc3..e6a1da3f 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_stack_build.S +++ b/ports/cortex_m3/gnu/src/tx_thread_stack_build.S @@ -1,141 +1,133 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_stack_build Cortex-M3/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified Comment(s), setting */ -@/* R10 to top of stack is not */ -@/* needed. Removed references */ -@/* to stack frame, clean up */ -@/* whitespace, resulting */ -@/* in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M3/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { .global _tx_thread_stack_build .thumb_func _tx_thread_stack_build: -@ -@ -@ /* Build a fake interrupt frame. The form of the fake interrupt stack -@ on the Cortex-M3 should look like the following after it is built: -@ -@ Stack Top: -@ LR Interrupted LR (LR at time of PENDSV) -@ r4 Initial value for r4 -@ r5 Initial value for r5 -@ r6 Initial value for r6 -@ r7 Initial value for r7 -@ r8 Initial value for r8 -@ r9 Initial value for r9 -@ r10 Initial value for r10 -@ r11 Initial value for r11 -@ 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 - BIC r2, r2, #0x7 @ Align frame - SUB r2, r2, #68 @ Subtract frame size - LDR r3, =0xFFFFFFFD @ Build initial LR value - STR r3, [r2, #0] @ Save on the stack -@ -@ /* Actually build the stack frame. */ -@ - MOV r3, #0 @ Build initial register value - STR r3, [r2, #4] @ Store initial r4 - STR r3, [r2, #8] @ Store initial r5 - STR r3, [r2, #12] @ Store initial r6 - STR r3, [r2, #16] @ Store initial r7 - STR r3, [r2, #20] @ Store initial r8 - STR r3, [r2, #24] @ Store initial r9 - STR r3, [r2, #28] @ Store initial r10 - STR r3, [r2, #32] @ Store initial r11 -@ -@ /* 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 - MOV r3, #0xFFFFFFFF @ Poison EXC_RETURN value - STR r3, [r2, #56] @ Store initial lr - STR r1, [r2, #60] @ Store initial pc - MOV 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 -@} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 +// } diff --git a/ports/cortex_m3/gnu/src/tx_thread_system_return.S b/ports/cortex_m3/gnu/src/tx_thread_system_return.S index 3b26437a..8a1f4a29 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m3/gnu/src/tx_thread_system_return.S @@ -1,90 +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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_system_return Cortex-M3/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* VOID _tx_thread_system_return(VOID) -@{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M3/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { .thumb_func .global _tx_thread_system_return _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. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ 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 -@/* } */ + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif +_isr_context: + BX lr // Return to caller +// } diff --git a/ports/cortex_m3/gnu/src/tx_timer_interrupt.S b/ports/cortex_m3/gnu/src/tx_timer_interrupt.S index e2c0a33c..2edd6db1 100644 --- a/ports/cortex_m3/gnu/src/tx_timer_interrupt.S +++ b/ports/cortex_m3/gnu/src/tx_timer_interrupt.S @@ -1,259 +1,250 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_timer_time_slice - .global _tx_timer_system_clock - .global _tx_timer_current_ptr - .global _tx_timer_list_start - .global _tx_timer_list_end - .global _tx_timer_expired_time_slice - .global _tx_timer_expired - .global _tx_thread_time_slice - .global _tx_timer_expiration_process -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_timer_time_slice + .global _tx_timer_system_clock + .global _tx_timer_current_ptr + .global _tx_timer_list_start + .global _tx_timer_list_end + .global _tx_timer_expired_time_slice + .global _tx_timer_expired + .global _tx_thread_time_slice + .global _tx_timer_expiration_process + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_timer_interrupt Cortex-M3/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_timer_interrupt(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M3/GNU */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { .global _tx_timer_interrupt .thumb_func _tx_timer_interrupt: -@ -@ /* Upon entry to this routine, it is assumed that context save has already -@ been called, and therefore the compiler scratch registers are available -@ for use. */ -@ -@ /* Increment the system clock. */ -@ _tx_timer_system_clock++; -@ - LDR r1, =_tx_timer_system_clock @ Pickup address of system clock - LDR r0, [r1, #0] @ Pickup system clock - ADD r0, r0, #1 @ Increment system clock - STR r0, [r1, #0] @ Store new system clock -@ -@ /* Test for time-slice expiration. */ -@ if (_tx_timer_time_slice) -@ { -@ - LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice - LDR r2, [r3, #0] @ Pickup time-slice - CMP r2, #0 @ Is it non-active? - BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing -@ -@ /* Decrement the time_slice. */ -@ _tx_timer_time_slice--; -@ - SUB 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) -@ - CMP r2, #0 @ Has it expired? - BNE __tx_timer_no_time_slice @ No, skip expiration processing -@ -@ /* Set the time-slice expired flag. */ -@ _tx_timer_expired_time_slice = TX_TRUE; -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag - MOV r0, #1 @ Build expired value - STR r0, [r3, #0] @ Set time-slice expiration flag -@ -@ } -@ + + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) -@ { -@ - LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address - LDR r0, [r1, #0] @ Pickup current timer - LDR r2, [r0, #0] @ Pickup timer list entry - CMP r2, #0 @ Is there anything in the list? - BEQ __tx_timer_no_timer @ No, just increment the timer -@ -@ /* Set expiration flag. */ -@ _tx_timer_expired = TX_TRUE; -@ - LDR r3, =_tx_timer_expired @ Pickup expiration flag address - MOV r2, #1 @ Build expired value - STR r2, [r3, #0] @ Set expired flag - B __tx_timer_done @ Finished timer processing -@ -@ } -@ else -@ { + + /* Test for timer expiration. */ + // if (*_tx_timer_current_ptr) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; -@ - ADD r0, r0, #4 @ Move to next timer -@ -@ /* Check for wrap-around. */ -@ if (_tx_timer_current_ptr == _tx_timer_list_end) -@ - LDR r3, =_tx_timer_list_end @ Pickup addr of 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; -@ - LDR r3, =_tx_timer_list_start @ Pickup addr of timer list start - LDR r0, [r3, #0] @ Set current pointer to list start -@ + + /* No timer expired, increment the timer pointer. */ + // _tx_timer_current_ptr++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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 -@ } -@ + + 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)) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of expired flag - LDR r2, [r3, #0] @ Pickup time-slice expired flag - CMP r2, #0 @ Did a time-slice expire? - BNE __tx_something_expired @ If non-zero, time-slice expired - LDR r1, =_tx_timer_expired @ Pickup addr of other expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Did a timer expire? - BEQ __tx_timer_nothing_expired @ No, nothing expired -@ + + /* See if anything has expired. */ + // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + __tx_something_expired: -@ -@ - STMDB sp!, {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) -@ { -@ - LDR r1, =_tx_timer_expired @ Pickup addr of expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Check for timer expiration - BEQ __tx_timer_dont_activate @ If not set, skip timer activation -@ -@ /* Process timer expiration. */ -@ _tx_timer_expiration_process(); -@ - BL _tx_timer_expiration_process @ Call the timer expiration handling routine -@ -@ } + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of time-slice expired - LDR r2, [r3, #0] @ Pickup the actual flag - CMP r2, #0 @ See if the flag is set - BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing -@ -@ /* Time slice interrupted thread. */ -@ _tx_thread_time_slice(); -@ - BL _tx_thread_time_slice @ Call time-slice processing - LDR r0, =_tx_thread_preempt_disable @ Build address of preempt disable flag - LDR r1, [r0] @ Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice @ Yes, skip the PendSV logic - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r1, [r0] @ Pickup the current thread pointer - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - 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 + + /* Did time slice expire? */ + // if (_tx_timer_expired_time_slice) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -@ - LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for - @ the 8-byte stack alignment -@ -@ } -@ + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB @ Complete all memory access - BX lr @ Return to caller -@ -@} + DSB // Complete all memory access + BX lr // Return to caller +// } diff --git a/ports/cortex_m3/iar/inc/tx_port.h b/ports/cortex_m3/iar/inc/tx_port.h index 78c3575a..6950d635 100644 --- a/ports/cortex_m3/iar/inc/tx_port.h +++ b/ports/cortex_m3/iar/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M3/IAR */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -73,23 +73,43 @@ #include #include -#include -#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #include #endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ #define VOID void typedef char CHAR; typedef unsigned char UCHAR; -typedef signed int INT; +typedef int INT; typedef unsigned int UINT; -typedef signed long LONG; +typedef long LONG; typedef unsigned long ULONG; -typedef signed short SHORT; +typedef unsigned long long ULONG64; +typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -114,29 +134,29 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024UL) +#define TX_TRACE_TIME_SOURCE *((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 *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -147,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -165,7 +199,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 @@ -179,23 +213,26 @@ 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 -#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT -#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ #else -#define TX_THREAD_EXTENSION_2 -#endif -#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -#define TX_THREAD_EXTENSION_3 -#else -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; +#define TX_THREAD_EXTENSION_2 #endif + +#define TX_THREAD_EXTENSION_3 + + + /* Define the port extensions of the remaining ThreadX objects. */ #define TX_BLOCK_POOL_EXTENSION @@ -207,40 +244,193 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif /* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, tx_thread_shell_entry, and tx_thread_terminate. */ + #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #if (__VER__ < 8000000) -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); #else void *_tx_iar_create_per_thread_tls_area(void); void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); void __iar_Initlocks(void); -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); -#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); #endif #else -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif + +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) + +#ifdef TX_MISRA_ENABLE + +ULONG _tx_misra_control_get(void); +void _tx_misra_control_set(ULONG value); +ULONG _tx_misra_fpccr_get(void); +void _tx_misra_vfp_touch(void); + +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + + +/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA + in order to ensure no lazy stacking will occur. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } +#else + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + +#endif + +/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. + If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating + this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush + the lazy FPU save, then restore the CONTROL.FPCA state. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } +#else + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } +#endif + +#else /* No VFP in use */ + #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ + /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -264,16 +454,38 @@ void __iar_Initlocks(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) -#else + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -282,35 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif - -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -#ifdef TX_DISABLE_INLINE + +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -318,49 +684,22 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save; -#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();}; -#define TX_RESTORE {__set_interrupt_state(interrupt_save);}; - -#define _tx_thread_system_return _tx_thread_system_return_inline - -static void _tx_thread_system_return_inline(void) -{ -__istate_t interrupt_save; - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_IPSR() == 0) - { - interrupt_save = __get_interrupt_state(); - __enable_interrupt(); - __set_interrupt_state(interrupt_save); - } -} - -#endif +#endif /* TX_DISABLE_INLINE */ -/* Define the interrupt lockout macros for each ThreadX object. */ +/* Define FPU extension for the Cortex-M. 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. */ -#define TX_BLOCK_POOL_DISABLE TX_DISABLE -#define TX_BYTE_POOL_DISABLE TX_DISABLE -#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE -#define TX_MUTEX_DISABLE TX_DISABLE -#define TX_QUEUE_DISABLE TX_DISABLE -#define TX_SEMAPHORE_DISABLE TX_DISABLE +void tx_thread_fpu_enable(void); +void tx_thread_fpu_disable(void); /* 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-M3/IAR Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/IAR Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -371,8 +710,3 @@ extern CHAR _tx_version_id[]; #endif - - - - - diff --git a/ports/cortex_m3/iar/readme_threadx.txt b/ports/cortex_m3/iar/readme_threadx.txt index 24b8cd80..28b54e03 100644 --- a/ports/cortex_m3/iar/readme_threadx.txt +++ b/ports/cortex_m3/iar/readme_threadx.txt @@ -1,6 +1,7 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M3 + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using IAR EWARM Tools - Using the IAR Tools 1. Building the ThreadX run-time Library @@ -14,21 +15,22 @@ the application. 2. Demonstration System -The ThreadX demonstration is designed to execute under the IAR -Windows-based Cortex-M3 simulator. +The ThreadX demonstration is designed to execute under the IAR debugger under +simulation. -Building the demonstration is easy; simply make the sample_threadx.ewp project -the "active project" in the IAR Embedded Workbench and select the -"Make" button. +Building the demonstration is easy; simply open the threadx.www workspace file, +make the sample_threadx.ewp project the "active project" in the IAR Embedded +Workbench, and select the "Make" button. You should observe the compilation of sample_threadx.c (which is the demonstration -application) and linking with tx.a. The resulting file sample_threadx.out is a -binary file that can be downloaded and executed on IAR's Cortex-M3 simulator. +application) and linking with tx.a. The resulting file sample_threadx.out is a +binary ELF file that can be downloaded and executed on the IAR Windows-based +Cortex-M simulator. 3. System Initialization -The entry point in ThreadX for the Cortex-M3 using IAR tools is at label +The entry point in ThreadX for the Cortex-M using IAR tools is at label __iar_program_start. This is defined within the IAR compiler's startup code. In addition, this is where all static and global preset C variable initialization processing takes place. @@ -50,30 +52,86 @@ other RAM sections in memory. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M3 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. +Non-FPU Stack Frame: - Stack Offset Stack Contents + Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) - 0x04 r4 - 0x08 r5 - 0x0C r6 - 0x10 r7 - 0x14 r8 - 0x18 r9 - 0x1C r10 (sl) - 0x20 r11 - 0x24 r0 (Hardware stack starts here!!) - 0x28 r1 - 0x2C r2 - 0x30 r3 - 0x34 r12 - 0x38 lr - 0x3C pc - 0x40 xPSR + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 r4 Software stacked GP registers + 0x08 r5 + 0x0C r6 + 0x10 r7 + 0x14 r8 + 0x18 r9 + 0x1C r10 + 0x20 r11 + 0x24 r0 Hardware stacked registers + 0x28 r1 + 0x2C r2 + 0x30 r3 + 0x34 r12 + 0x38 lr + 0x3C pc + 0x40 xPSR + +FPU Stack Frame (only interrupted thread with FPU enabled): + + Stack Offset Stack Contents + + 0x00 lr Interrupted lr (lr at time of PENDSV) + 0x04 s16 Software stacked FPU registers + 0x08 s17 + 0x0C s18 + 0x10 s19 + 0x14 s20 + 0x18 s21 + 0x1C s22 + 0x20 s23 + 0x24 s24 + 0x28 s25 + 0x2C s26 + 0x30 s27 + 0x34 s28 + 0x38 s29 + 0x3C s30 + 0x40 s31 + 0x44 r4 Software stacked registers + 0x48 r5 + 0x4C r6 + 0x50 r7 + 0x54 r8 + 0x58 r9 + 0x5C r10 + 0x60 r11 + 0x64 r0 Hardware stacked registers + 0x68 r1 + 0x6C r2 + 0x70 r3 + 0x74 r12 + 0x78 lr + 0x7C pc + 0x80 xPSR + 0x84 s0 Hardware stacked FPU registers + 0x88 s1 + 0x8C s2 + 0x90 s3 + 0x94 s4 + 0x98 s5 + 0x9C s6 + 0xA0 s7 + 0xA4 s8 + 0xA8 s9 + 0xAC s10 + 0xB0 s11 + 0xB4 s12 + 0xB8 s13 + 0xBC s14 + 0xC0 s15 + 0xC4 fpscr 5. Improving Performance @@ -82,7 +140,7 @@ The distribution version of ThreadX is built without any compiler optimizations. This makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. Of course, this costs some performance. To make it run faster, you can change the ThreadX library -project to enable various compiler optimizations. +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING @@ -91,18 +149,11 @@ defined. 6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M3 -targets. There are a certain set of requirements that are defined in the -following sub-sections: - - -6.1 Vector Area - -The Cortex-M3 vectors start at the label __vector_table and is defined in cstartup_M.s. +The Cortex-M vectors start at the label __vector_table and is defined in cstartup_M.s. The application may modify the vector area according to its needs. -6.2 Managed Interrupts +6.1 Managed Interrupts ISRs for Cortex-M using the IAR tools can be written completely in C (or assembly language) without any calls to _tx_thread_context_save or _tx_thread_context_restore. @@ -121,15 +172,14 @@ ISRs written in assembly language will take the form: PUBLIC your_assembly_isr your_assembly_isr: - PUSH {lr} + PUSH {r0, lr} ; ISR processing goes here, including any needed function calls. - POP {lr} + POP {r0, lr} BX lr - 7. IAR Thread-safe Library Support Thread-safe support for the IAR tools is easily enabled by building the ThreadX library @@ -142,22 +192,23 @@ The project options "General Options -> Library Configuration" should also have "Enable thread support in library" box selected. -8. Revision History +8. VFP Support + +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads +can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread +context - no additional setup by the application. + + +9. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX version 6.1 for Cortex-M3 using IAR's ARM tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using IAR's ARM tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m3/iar/src/tx_misra.s b/ports/cortex_m3/iar/src/tx_misra.s index 2531f6ee..2add69b3 100644 --- a/ports/cortex_m3/iar/src/tx_misra.s +++ b/ports/cortex_m3/iar/src/tx_misra.s @@ -96,6 +96,12 @@ PUBLIC _tx_misra_void_to_uchar_pointer_convert PUBLIC _tx_misra_void_to_ulong_pointer_convert PUBLIC _tx_misra_ipsr_get + PUBLIC _tx_misra_control_get + PUBLIC _tx_misra_control_set +#ifdef __ARMVFP__ + PUBLIC _tx_misra_fpccr_get + PUBLIC _tx_misra_vfp_touch +#endif PUBLIC _tx_version_id @@ -980,7 +986,7 @@ _tx_misra_char_to_uchar_pointer_convert: BX LR ;; return -***********************************************************************************************/ +/***********************************************************************************************/ /***********************************************************************************************/ /** */ /** ULONG _tx_misra_ipsr_get(void); */ @@ -995,6 +1001,71 @@ _tx_misra_ipsr_get: BX LR ;; return +/***********************************************************************************************/ +/***********************************************************************************************/ +/** */ +/** ULONG _tx_misra_control_get(void); */ +/** */ +/***********************************************************************************************/ +/***********************************************************************************************/ + + SECTION `.text`:CODE:NOROOT(1) + THUMB +_tx_misra_control_get: + MRS R0, CONTROL + BX LR ;; return + + +/***********************************************************************************************/ +/***********************************************************************************************/ +/** */ +/** void _tx_misra_control_set(ULONG value); */ +/** */ +/***********************************************************************************************/ +/***********************************************************************************************/ + + SECTION `.text`:CODE:NOROOT(1) + THUMB +_tx_misra_control_set: + MSR CONTROL, R0 + BX LR ;; return + + +#ifdef __ARMVFP__ + +/***********************************************************************************************/ +/***********************************************************************************************/ +/** */ +/** ULONG _tx_misra_fpccr_get(void); */ +/** */ +/***********************************************************************************************/ +/***********************************************************************************************/ + + SECTION `.text`:CODE:NOROOT(2) + THUMB +_tx_misra_fpccr_get: + LDR r0, =0xE000EF34 ; Build FPCCR address + LDR r0, [r0] ; Load FPCCR value + BX LR ;; return + + +/***********************************************************************************************/ +/***********************************************************************************************/ +/** */ +/** void _tx_misra_vfp_touch(void); */ +/** */ +/***********************************************************************************************/ +/***********************************************************************************************/ + + SECTION `.text`:CODE:NOROOT(1) + THUMB +_tx_misra_vfp_touch: + vmov.f32 s0, s0 + BX LR ;; return + +#endif + + SECTION `.iar_vfe_header`:DATA:NOALLOC:NOROOT(2) SECTION_TYPE SHT_PROGBITS, 0 DATA diff --git a/ports/cortex_m3/iar/src/tx_thread_context_restore.s b/ports/cortex_m3/iar/src/tx_thread_context_restore.s index 9842f8ce..45341c70 100644 --- a/ports/cortex_m3/iar/src/tx_thread_context_restore.s +++ b/ports/cortex_m3/iar/src/tx_thread_context_restore.s @@ -1,89 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_execution_isr_exit -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function restores the interrupt context if it is processing a */ -;/* nested interrupt. If not, it returns to the interrupt thread if no */ -;/* preemption is necessary. Otherwise, if preemption is necessary or */ -;/* if no thread was running, the function returns to the scheduler. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* [_tx_execution_isr_exit] Execution profiling ISR exit */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs Interrupt Service Routines */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_restore(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M3/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { PUBLIC _tx_thread_context_restore _tx_thread_context_restore: -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR exit function to indicate an ISR is complete. */ -; - PUSH {r0,lr} ; Save ISR lr - BL _tx_execution_isr_exit ; Call the ISR exit function - POP {r0,lr} ; Restore ISR lr +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address #endif -; - POP {lr} + BX lr -; -;} +// } END diff --git a/ports/cortex_m3/iar/src/tx_thread_context_save.s b/ports/cortex_m3/iar/src/tx_thread_context_save.s index 23462fdc..8bb771cb 100644 --- a/ports/cortex_m3/iar/src/tx_thread_context_save.s +++ b/ports/cortex_m3/iar/src/tx_thread_context_save.s @@ -1,87 +1,80 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_execution_isr_enter -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_save Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function saves the context of an executing thread in the */ -;/* beginning of interrupt processing. The function also ensures that */ -;/* the system stack is used upon return to the calling ISR. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* [_tx_execution_isr_enter] Execution profiling ISR enter */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M3/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_enter] Execution profiling ISR enter */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { PUBLIC _tx_thread_context_save _tx_thread_context_save: -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR enter function to indicate an ISR is starting. */ -; - PUSH {r0, lr} ; Save return address - BL _tx_execution_isr_enter ; Call the ISR enter function - POP {r0, lr} ; Recover return address + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address #endif -; -; /* Context is already saved - just return! */ -; + + /* Context is already saved - just return. */ + BX lr -;} +// } END diff --git a/ports/cortex_m3/iar/src/tx_thread_interrupt_control.s b/ports/cortex_m3/iar/src/tx_thread_interrupt_control.s index 2c8bf932..8886a66b 100644 --- a/ports/cortex_m3/iar/src/tx_thread_interrupt_control.s +++ b/ports/cortex_m3/iar/src/tx_thread_interrupt_control.s @@ -1,77 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_control Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_control(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M3/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { PUBLIC _tx_thread_interrupt_control _tx_thread_interrupt_control: -; -; /* Pickup current interrupt lockout posture. */ -; - MRS r1, PRIMASK - MSR PRIMASK, r0 - MOV r0, r1 - BX lr -; -;} +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } END diff --git a/ports/cortex_m3/iar/src/tx_thread_interrupt_disable.s b/ports/cortex_m3/iar/src/tx_thread_interrupt_disable.s index af919f6f..7b1235a5 100644 --- a/ports/cortex_m3/iar/src/tx_thread_interrupt_disable.s +++ b/ports/cortex_m3/iar/src/tx_thread_interrupt_disable.s @@ -1,76 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_disable(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M3/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { PUBLIC _tx_thread_interrupt_disable _tx_thread_interrupt_disable: -; -; /* Return current interrupt lockout posture. */ -; + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_USE_BASEPRI + MSR BASEPRI, r1 +#else MRS r0, PRIMASK CPSID i +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m3/iar/src/tx_thread_interrupt_restore.s b/ports/cortex_m3/iar/src/tx_thread_interrupt_restore.s index a10b571f..9f4525f0 100644 --- a/ports/cortex_m3/iar/src/tx_thread_interrupt_restore.s +++ b/ports/cortex_m3/iar/src/tx_thread_interrupt_restore.s @@ -1,75 +1,75 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_interrupt_restore(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M3/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { PUBLIC _tx_thread_interrupt_restore _tx_thread_interrupt_restore: -; -; /* Restore previous interrupt lockout posture. */ -; + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else MSR PRIMASK, r0 +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m3/iar/src/tx_thread_schedule.s b/ports/cortex_m3/iar/src/tx_thread_schedule.s index 4d109e86..941f5398 100644 --- a/ports/cortex_m3/iar/src/tx_thread_schedule.s +++ b/ports/cortex_m3/iar/src/tx_thread_schedule.s @@ -1,261 +1,279 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_timer_time_slice - EXTERN _tx_thread_system_stack_ptr + EXTERN _tx_thread_preempt_disable EXTERN _tx_execution_thread_enter EXTERN _tx_execution_thread_exit - EXTERN _tx_thread_preempt_disable #ifdef TX_LOW_POWER EXTERN tx_low_power_enter EXTERN tx_low_power_exit #endif -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M3/IAR */ -;/* 6.1.5 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* _tx_thread_context_restore Restore thread's context */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* 03-02-2021 Scott Larson Modified comment(s), add */ -;/* low power code, */ -;/* resulting in version 6.1.5 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_schedule(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M3/IAR */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { PUBLIC _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 */ -; + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __ARMVFP__ + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register +#endif + + /* Enable interrupts */ CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR - DSB ; Complete all memory accesses - ISB ; Flush pipeline -; -; /* Wait here for the PendSV to take place. */ -; + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 PendSV handler. */ -; + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + PUBLIC PendSV_Handler PUBLIC __tx_PendSVHandler PendSV_Handler: __tx_PendSVHandler: -; -; /* Get current thread value and new thread pointer. */ -; + + /* Get current thread value and new thread pointer. */ + __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, lr} ; Recover LR - CPSIE i ; Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack -; -; /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -; - LDR r5, [r4] ; Pickup current time-slice - STR r12, [r1, #8] ; Save the thread stack pointer - 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. */ -; - STR r3, [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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 r3 + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __ARMVFP__ + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_save + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers +_skip_vfp_save: #endif -; -; /* Restore the thread context and PSP. */ -; - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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. */ -; + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack + + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 +#endif + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __ARMVFP__ + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers +_skip_vfp_restore: +#endif + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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! */ -; + 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: - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread -;} + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __ARMVFP__ + + PUBLIC tx_thread_fpu_enable +tx_thread_fpu_enable: + PUBLIC tx_thread_fpu_disable +tx_thread_fpu_disable: + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller + +#endif END diff --git a/ports/cortex_m3/iar/src/tx_thread_stack_build.s b/ports/cortex_m3/iar/src/tx_thread_stack_build.s index e5f23bc5..5005363e 100644 --- a/ports/cortex_m3/iar/src/tx_thread_stack_build.s +++ b/ports/cortex_m3/iar/src/tx_thread_stack_build.s @@ -1,134 +1,132 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_stack_build Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M3/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { PUBLIC _tx_thread_stack_build _tx_thread_stack_build: -; -; -; /* Build a fake interrupt frame. The form of the fake interrupt stack -; on the Cortex-M should look like the following after it is built: -; -; Stack Top: -; LR Interrupted LR (LR at time of PENDSV) -; r4 Initial value for r4 -; r5 Initial value for r5 -; r6 Initial value for r6 -; r7 Initial value for r7 -; r8 Initial value for r8 -; r9 Initial value for r9 -; r10 Initial value for r10 -; r11 Initial value for r11 -; 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 - BIC r2, r2, #0x7 ; Align frame for 8-byte alignment - SUB r2, r2, #68 ; Subtract frame size - LDR r3, =0xFFFFFFFD ; Build initial LR value - STR r3, [r2, #0] ; Save on the stack -; -; /* Actually build the stack frame. */ -; - MOV r3, #0 ; Build initial register value - STR r3, [r2, #4] ; Store initial r4 - STR r3, [r2, #8] ; Store initial r5 - STR r3, [r2, #12] ; Store initial r6 - STR r3, [r2, #16] ; Store initial r7 - STR r3, [r2, #20] ; Store initial r8 - STR r3, [r2, #24] ; Store initial r9 - STR r3, [r2, #28] ; Store initial r10 - STR r3, [r2, #32] ; Store initial r11 -; -; /* 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 - MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value - STR r3, [r2, #56] ; Store initial lr - STR r1, [r2, #60] ; Store initial pc - MOV 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 -;} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 diff --git a/ports/cortex_m3/iar/src/tx_thread_system_return.s b/ports/cortex_m3/iar/src/tx_thread_system_return.s index 38fb892b..0c2ae9bf 100644 --- a/ports/cortex_m3/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m3/iar/src/tx_thread_system_return.s @@ -1,87 +1,92 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_system_return Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_system_return(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M3/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { PUBLIC _tx_thread_system_return -_tx_thread_system_return??rA: _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. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 + + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif _isr_context: - BX lr ; Return to caller -;} + BX lr // Return to caller +// } END diff --git a/ports/cortex_m3/iar/src/tx_timer_interrupt.s b/ports/cortex_m3/iar/src/tx_timer_interrupt.s index 58303af0..13427464 100644 --- a/ports/cortex_m3/iar/src/tx_timer_interrupt.s +++ b/ports/cortex_m3/iar/src/tx_timer_interrupt.s @@ -1,26 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_timer_time_slice EXTERN _tx_timer_system_clock EXTERN _tx_timer_current_ptr @@ -33,224 +32,221 @@ EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_thread_preempt_disable -; -; + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M3/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* expiration functions are called. */ -;/* */ -;/* 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_timer_interrupt(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M3/IAR */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { PUBLIC _tx_timer_interrupt _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++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock - LDR r0, [r1, #0] ; Pickup system clock - ADD r0, r0, #1 ; Increment system clock - STR r0, [r1, #0] ; Store new system clock -; -; /* Test for time-slice expiration. */ -; if (_tx_timer_time_slice) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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--; -; - SUB 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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++; -; - ADD r0, r0, #4 ; Move to next timer -; -; /* Check for wrap-around. */ -; if (_tx_timer_current_ptr == _tx_timer_list_end) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired: -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + +__tx_something_expired: + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for - ; the 8-byte stack alignment -; -; } -; + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB ; Complete all memory access - BX lr ; Return to caller -; -;} + DSB // Complete all memory access + BX lr // Return to caller +// } END diff --git a/ports/cortex_m3/keil/inc/tx_port.h b/ports/cortex_m3/keil/inc/tx_port.h index 6aea4610..8b076fa0 100644 --- a/ports/cortex_m3/keil/inc/tx_port.h +++ b/ports/cortex_m3/keil/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M3/Keil */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,7 +156,7 @@ typedef unsigned short USHORT; #ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -144,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -162,7 +199,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 @@ -176,13 +213,24 @@ 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -196,11 +244,11 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -208,18 +256,181 @@ ULONG _tx_misra_time_stamp_get(VOID); tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif + +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) + +#ifdef TX_MISRA_ENABLE + +ULONG _tx_misra_control_get(void); +void _tx_misra_control_set(ULONG value); +ULONG _tx_misra_fpccr_get(void); +void _tx_misra_vfp_touch(void); + +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + + +/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA + in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } +#else + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } #endif +/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. + If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating + this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush + the lazy FPU save, then restore the CONTROL.FPCA state. */ + +#ifndef TX_MISRA_ENABLE + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } +#else + +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } +#endif + +#else /* No VFP in use */ + +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ + /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -243,16 +454,38 @@ register unsigned int _ipsr __asm("ipsr"); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -261,35 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -#ifdef TX_DISABLE_INLINE +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -297,42 +684,22 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); - -#define _tx_thread_system_return _tx_thread_system_return_inline +#endif /* TX_DISABLE_INLINE */ -static void _tx_thread_system_return_inline(void) -{ -unsigned int was_masked; - - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (_ipsr == 0) - { - was_masked = __disable_irq(); - __enable_irq(); - if (was_masked != 0) - __disable_irq(); - } -} -#endif +/* Define FPU extension for the Cortex-M. 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); /* 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-M3/Keil Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/Keil Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -343,7 +710,3 @@ extern CHAR _tx_version_id[]; #endif - - - - diff --git a/ports/cortex_m33/ac5/example_build/ARMCM33_DSP_FP_TZ_config.txt b/ports/cortex_m33/ac5/example_build/ARMCM33_DSP_FP_TZ_config.txt deleted file mode 100644 index 04e32d1f..00000000 --- a/ports/cortex_m33/ac5/example_build/ARMCM33_DSP_FP_TZ_config.txt +++ /dev/null @@ -1,24 +0,0 @@ -# Parameters: -# instance.parameter=value #(type, mode) default = 'def value' : description : [min..max] -#---------------------------------------------------------------------------------------------- -cpu0.FPU=1 # (bool , init-time) default = '1' : Set whether the model has VFP support -cpu0.DSP=1 # (bool , init-time) default = '1' : Set whether the model has the DSP extension -cpu0.semihosting-enable=0 # (bool , init-time) default = '1' : Enable semihosting SVC traps. Applications that do not use semihosting must set this parameter to false. -cpu0.MPU_S=0x8 # (int , init-time) default = '0x8' : Number of regions in the Secure MPU. If Security Extentions are absent, this is ignored : [0x0..0x10] -cpu0.MPU_NS=0x8 # (int , init-time) default = '0x8' : Number of regions in the Non-Secure MPU. If Security Extentions are absent, this is the total number of MPU regions : [0x0..0x10] -cpu0.ITM=0 # (bool , init-time) default = '1' : Level of instrumentation trace supported. false : No ITM trace included, true: ITM trace included -cpu0.IRQLVL=0x3 # (int , init-time) default = '0x3' : Number of bits of interrupt priority : [0x3..0x8] -cpu0.BIGENDINIT=0 # (bool , init-time) default = '0' : Initialize processor to big endian mode -cpu0.INITSVTOR=0x00000000 # (int , init-time) default = '0x10000000' : Secure vector-table offset at reset : [0x0..0xFFFFFF80] -cpu0.INITNSVTOR=0x0 # (int , init-time) default = '0x0' : Non-Secure vector-table offset at reset : [0x0..0xFFFFFF80] -cpu0.SAU=0x8 # (int , init-time) default = '0x4' : Number of SAU regions (0 => no SAU) : [0x0..0x8] -cpu0.SAU_CTRL.ENABLE=0 # (bool , init-time) default = '0' : Enable SAU at reset -cpu0.SAU_CTRL.ALLNS=0 # (bool , init-time) default = '0' : At reset, the SAU treats entire memory space as NS when the SAU is disabled if this is set -idau.NUM_IDAU_REGION=0x0 # (int , init-time) default = '0xA' : -cpu0.LOCK_SAU=0 # (bool , init-time) default = '0' : Lock down of SAU registers write -cpu0.LOCK_S_MPU=0 # (bool , init-time) default = '0' : Lock down of Secure MPU registers write -cpu0.LOCK_NS_MPU=0 # (bool , init-time) default = '0' : Lock down of Non-Secure MPU registers write -cpu0.CPIF=1 # (bool , init-time) default = '1' : Specifies whether the external coprocessor interface is included -cpu0.SECEXT=1 # (bool , init-time) default = '1' : Whether the ARMv8-M Security Extensions are included -fvp_mps2.DISABLE_GATING=1 # (bool , init-time) default = '0' : Disable Memory gating logic -#---------------------------------------------------------------------------------------------- diff --git a/ports/cortex_m33/ac5/example_build/AzureRTOS.uvmpw b/ports/cortex_m33/ac5/example_build/AzureRTOS.uvmpw deleted file mode 100644 index c50658f7..00000000 --- a/ports/cortex_m33/ac5/example_build/AzureRTOS.uvmpw +++ /dev/null @@ -1,23 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - WorkSpace - - - .\demo_secure_zone\demo_secure_zone.uvprojx - 1 - - - - .\demo_threadx_non-secure_zone\demo_threadx_non-secure_zone.uvprojx - - - - .\ThreadX_Library.uvprojx - - -
diff --git a/ports/cortex_m33/ac5/example_build/Debug.ini b/ports/cortex_m33/ac5/example_build/Debug.ini deleted file mode 100644 index 2a9dfba0..00000000 --- a/ports/cortex_m33/ac5/example_build/Debug.ini +++ /dev/null @@ -1,4 +0,0 @@ -LOAD "..\\demo_threadx_non-secure_zone\\Objects\\demo_threadx_non-secure_zone.axf" incremental -LOAD "..\\demo_secure_zone\\Objects\\demo_secure_zone.axf" incremental -RESET -g, \\demo_secure_zone\main_s\main \ No newline at end of file diff --git a/ports/cortex_m33/ac5/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h b/ports/cortex_m33/ac5/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h deleted file mode 100644 index 1eb74752..00000000 --- a/ports/cortex_m33/ac5/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'ThreadX_Library' - * Target: 'ThreadX_Library_Project' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM33_DSP_FP_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m33/ac5/example_build/RTOS.uvmpw.uvgui b/ports/cortex_m33/ac5/example_build/RTOS.uvmpw.uvgui deleted file mode 100644 index 5c23c31f..00000000 --- a/ports/cortex_m33/ac5/example_build/RTOS.uvmpw.uvgui +++ /dev/null @@ -1,1777 +0,0 @@ - - - - -6.1 - -
### uVision Project, (C) Keil Software
- - - - - 44 - 2 - 3 - - -1 - -1 - - - -1 - -1 - - - 0 - 0 - 1024 - 728 - - - - 0 - - 297 - 0100000004000000010000000100000001000000010000000000000002000000000000000100000001000000000000002800000028000000010000000100000000000000010000005F433A5C4B65696C5C41524D5C5041434B5C41524D5C434D5349535C352E322E305C434D5349535C52544F53325C5254585C4578616D706C65735C54727573745A6F6E6556384D5C52544F535C434D33335F735C41627374726163742E747874000000000C41627374726163742E74787400000000C5D4F200FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000380100006500000080070000FD030000 - - - - 0 - Build - - -1 - -1 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - F40000004F00000090050000F0000000 - - - 16 - F4000000650000009005000006010000 - - - - 1005 - 1005 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006600000031010000CE030000 - - - 16 - 2100000037000000110100001A010000 - - - - 109 - 109 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006600000031010000CE030000 - - - 16 - 21000000370000003D010000BD020000 - - - - 1465 - 1465 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1466 - 1466 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1467 - 1467 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1468 - 1468 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1506 - 1506 - 0 - 0 - 0 - 0 - 32767 - 0 - 16384 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 1913 - 1913 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - F7000000660000008D050000D7000000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1935 - 1935 - 0 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000110100001A010000 - - - - 1936 - 1936 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000110100001A010000 - - - - 1937 - 1937 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000110100001A010000 - - - - 1939 - 1939 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1940 - 1940 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1941 - 1941 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 1942 - 1942 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 195 - 195 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006600000031010000CE030000 - - - 16 - 21000000370000003D010000BD020000 - - - - 196 - 196 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006600000031010000CE030000 - - - 16 - 21000000370000003D010000BD020000 - - - - 197 - 197 - 0 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 03000000390300007D070000CE030000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 198 - 198 - 0 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 000000005F0200009005000014030000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 199 - 199 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000390300007D070000CE030000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 203 - 203 - 0 - 0 - 0 - 0 - 32767 - 0 - 8192 - 0 - - 16 - F7000000660000008D050000D7000000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 204 - 204 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - F7000000660000008D050000D7000000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 221 - 221 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 00000000000000000000000000000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 2506 - 2506 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 2507 - 2507 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 343 - 343 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - F7000000660000008D050000D7000000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 346 - 346 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - F7000000660000008D050000D7000000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 35824 - 35824 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - F7000000660000008D050000D7000000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 35885 - 35885 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35886 - 35886 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35887 - 35887 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35888 - 35888 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35889 - 35889 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35890 - 35890 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35891 - 35891 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35892 - 35892 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35893 - 35893 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35894 - 35894 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35895 - 35895 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35896 - 35896 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35897 - 35897 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35898 - 35898 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35899 - 35899 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35900 - 35900 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35901 - 35901 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35902 - 35902 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35903 - 35903 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35904 - 35904 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 35905 - 35905 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 38003 - 38003 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006600000031010000CE030000 - - - 16 - 21000000370000003D010000BD020000 - - - - 38007 - 38007 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000390300007D070000CE030000 - - - 16 - 2100000037000000E9020000D8000000 - - - - 436 - 436 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000390300007D070000CE030000 - - - 16 - 21000000370000003D010000BD020000 - - - - 437 - 437 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000110100001A010000 - - - - 440 - 440 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000760200008D050000FB020000 - - - 16 - 2100000037000000110100001A010000 - - - - 463 - 463 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006E0300007D070000CE030000 - - - 16 - 21000000370000003D01000079020000 - - - - 466 - 466 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006E0300007D070000CE030000 - - - 16 - 21000000370000003D01000079020000 - - - - 470 - 470 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000010000000300000003020000 - - - 16 - 2100000037000000E9020000C7000000 - - - - 50000 - 50000 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50001 - 50001 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50002 - 50002 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50003 - 50003 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50004 - 50004 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50005 - 50005 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50006 - 50006 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50007 - 50007 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50008 - 50008 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50009 - 50009 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50010 - 50010 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50011 - 50011 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50012 - 50012 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50013 - 50013 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50014 - 50014 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50015 - 50015 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50016 - 50016 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50017 - 50017 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50018 - 50018 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 50019 - 50019 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - A3040000660000008D05000056020000 - - - 16 - 2100000037000000110100001A010000 - - - - 59392 - 59392 - 1 - 0 - 0 - 0 - 940 - 0 - 8192 - 0 - - 16 - 0000000000000000B70300001C000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59393 - 0 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 00000000E703000080070000FA030000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59399 - 59399 - 1 - 0 - 0 - 0 - 303 - 0 - 8192 - 1 - - 16 - 000000001C000000E701000038000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59400 - 59400 - 0 - 0 - 0 - 0 - 612 - 0 - 8192 - 2 - - 16 - 00000000380000006F02000054000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 824 - 824 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000010000000300000003020000 - - - 16 - 21000000370000001101000002010000 - - - - 3692 - 000000000F000000000000000020000000000000FFFFFFFFFFFFFFFFF4000000F000000090050000F4000000000000000100000004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000000000000F4000000650000009005000006010000F40000004F00000090050000F00000000000000040280046060000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF9C0400004F000000A00400006F020000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000A0040000650000009005000085020000A00400004F000000900500006F02000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF340100004F00000038010000E703000001000000020000100400000001000000A7FEFFFF1C060000FFFFFFFF05000000ED0300006D000000C3000000C40000007394000001800010000001000000000000006500000034010000FD030000000000004F00000034010000E70300000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF000000005B020000900500005F02000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB090000018000800000000000000000000075020000900500002A030000000000005F020000900500001403000000000000404100460E0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC80200005F020000CC0200001403000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000000000000FFFFFFFFFFFFFFFF000000001E03000080070000220300000000000001000000040000000100000067FDFFFFF4000000FFFFFFFF04000000C5000000C7000000B40100007794000001800080000000000000000000003803000080070000FD030000000000002203000080070000E70300000000000040820046040000000C4275696C64204F757470757400000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000080000000000000FFFFFFFFFFFFFFFF0000000017020000900500001B0200000000000001000000040000000100000000000000000000000000000000000000000000000100000000000000FFFFFFFF0200000038030000D6010000018000800000000000000000000000000000010000003202000000000000EAFFFFFF010000001C02000000000000404100460200000009554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC80200001B020000CC020000BF02000000000000020000000400000000000000000000000000000000000000000000000000000001000000FFFFFFFF3803000001000000FFFFFFFF38030000000000000080000000000000FFFFFFFFFFFFFFFF00000000530300008007000057030000000000000100000004000000010000000000000000000000FFFFFFFF02000000D2010000CF01000001800080000000000000000000006D03000080070000FD030000000000005703000080070000E70300000000000040820046020000000E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF1346696E6420416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFD201000001000000FFFFFFFFD2010000000000000000000000000000 - - - 59392 - File - - 2438 - 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000004000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000004000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050000000000944657374726F796564960000000000000014000944657374726F79656406507265656D7006746872656164136F735274785468726561645265616479507574106F73527478546872656164426C6F636B15457672527478546872656164556E626C6F636B656413457672527478546872656164426C6F636B6564116F735274785468726561645377697463681545767252747854687265616444657374726F796564146F7352747854687265616457616974456E746572146F7352747854687265616444656C61795469636B0D7468726561642D3E7374617465126F73527478546872656164426C6F636B6564126F7352747854687265616457616974696E67204576745274784B65726E656C496E666F5265747269657665645F44657461696C194576745274784B65726E656C496E666F52657472696576656408546872656164437206236966646566136F735F69646C655F7468726561645F617474720E6F73546872656164417474725F740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020000001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 - - - 1423 - 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 1423 - 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 - - - - 59399 - Build - - 1000 - 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000004001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000004002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA0000000000000000000000000000000000000000000000000100000001000000960000000300205000000000144656502053696D756C6174696F6E204D6F64656C96000000000000000100144656502053696D756C6174696F6E204D6F64656C000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000000240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C642F010000 - - - 583 - 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 583 - 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000 - - - - 59400 - Debug - - 2373 - 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720000000000000000010000000000000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7200000000000000000100000000000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 - - - 898 - 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 898 - 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 - - - - 0 - 1920 - 1080 - - - - - - 1 - 0 - - 100 - 0 - - <1>.\Abstract.txt - 0 - 1 - 1 - 0 - - 0 - - - - -
diff --git a/ports/cortex_m33/ac5/example_build/ThreadX_Library.uvoptx b/ports/cortex_m33/ac5/example_build/ThreadX_Library.uvoptx deleted file mode 100644 index b481cba0..00000000 --- a/ports/cortex_m33/ac5/example_build/ThreadX_Library.uvoptx +++ /dev/null @@ -1,2569 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - ThreadX_Library_Project - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 0 - 0 - 1 - - 7 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 1 - - - - - - - - - - - BIN\ULP2CM3.DLL - - - - 0 - UL2V8M - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - - - 0 - ULP2CM3 - -O2510 -S0 -C0 -FO15 -FD20000000 -FC4000 -FN1 -FF0MK_P256 -FS00 -FL040000) - - - - - 0 - - - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - - - Source Group - 0 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_allocate.c - tx_block_allocate.c - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_cleanup.c - tx_block_pool_cleanup.c - 0 - 0 - - - 1 - 3 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_create.c - tx_block_pool_create.c - 0 - 0 - - - 1 - 4 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_delete.c - tx_block_pool_delete.c - 0 - 0 - - - 1 - 5 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_info_get.c - tx_block_pool_info_get.c - 0 - 0 - - - 1 - 6 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_initialize.c - tx_block_pool_initialize.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_performance_info_get.c - tx_block_pool_performance_info_get.c - 0 - 0 - - - 1 - 8 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c - tx_block_pool_performance_system_info_get.c - 0 - 0 - - - 1 - 9 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_pool_prioritize.c - tx_block_pool_prioritize.c - 0 - 0 - - - 1 - 10 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_block_release.c - tx_block_release.c - 0 - 0 - - - 1 - 11 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_allocate.c - tx_byte_allocate.c - 0 - 0 - - - 1 - 12 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_cleanup.c - tx_byte_pool_cleanup.c - 0 - 0 - - - 1 - 13 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_create.c - tx_byte_pool_create.c - 0 - 0 - - - 1 - 14 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_delete.c - tx_byte_pool_delete.c - 0 - 0 - - - 1 - 15 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_info_get.c - tx_byte_pool_info_get.c - 0 - 0 - - - 1 - 16 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_initialize.c - tx_byte_pool_initialize.c - 0 - 0 - - - 1 - 17 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_performance_info_get.c - tx_byte_pool_performance_info_get.c - 0 - 0 - - - 1 - 18 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c - tx_byte_pool_performance_system_info_get.c - 0 - 0 - - - 1 - 19 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_prioritize.c - tx_byte_pool_prioritize.c - 0 - 0 - - - 1 - 20 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_pool_search.c - tx_byte_pool_search.c - 0 - 0 - - - 1 - 21 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_byte_release.c - tx_byte_release.c - 0 - 0 - - - 1 - 22 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_cleanup.c - tx_event_flags_cleanup.c - 0 - 0 - - - 1 - 23 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_create.c - tx_event_flags_create.c - 0 - 0 - - - 1 - 24 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_delete.c - tx_event_flags_delete.c - 0 - 0 - - - 1 - 25 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_get.c - tx_event_flags_get.c - 0 - 0 - - - 1 - 26 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_info_get.c - tx_event_flags_info_get.c - 0 - 0 - - - 1 - 27 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_initialize.c - tx_event_flags_initialize.c - 0 - 0 - - - 1 - 28 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_performance_info_get.c - tx_event_flags_performance_info_get.c - 0 - 0 - - - 1 - 29 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c - tx_event_flags_performance_system_info_get.c - 0 - 0 - - - 1 - 30 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_set.c - tx_event_flags_set.c - 0 - 0 - - - 1 - 31 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_event_flags_set_notify.c - tx_event_flags_set_notify.c - 0 - 0 - - - 1 - 32 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_initialize_high_level.c - tx_initialize_high_level.c - 0 - 0 - - - 1 - 33 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_initialize_kernel_enter.c - tx_initialize_kernel_enter.c - 0 - 0 - - - 1 - 34 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_initialize_kernel_setup.c - tx_initialize_kernel_setup.c - 0 - 0 - - - 1 - 35 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_cleanup.c - tx_mutex_cleanup.c - 0 - 0 - - - 1 - 36 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_create.c - tx_mutex_create.c - 0 - 0 - - - 1 - 37 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_delete.c - tx_mutex_delete.c - 0 - 0 - - - 1 - 38 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_get.c - tx_mutex_get.c - 0 - 0 - - - 1 - 39 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_info_get.c - tx_mutex_info_get.c - 0 - 0 - - - 1 - 40 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_initialize.c - tx_mutex_initialize.c - 0 - 0 - - - 1 - 41 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_performance_info_get.c - tx_mutex_performance_info_get.c - 0 - 0 - - - 1 - 42 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_performance_system_info_get.c - tx_mutex_performance_system_info_get.c - 0 - 0 - - - 1 - 43 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_prioritize.c - tx_mutex_prioritize.c - 0 - 0 - - - 1 - 44 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_priority_change.c - tx_mutex_priority_change.c - 0 - 0 - - - 1 - 45 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_mutex_put.c - tx_mutex_put.c - 0 - 0 - - - 1 - 46 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_cleanup.c - tx_queue_cleanup.c - 0 - 0 - - - 1 - 47 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_create.c - tx_queue_create.c - 0 - 0 - - - 1 - 48 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_delete.c - tx_queue_delete.c - 0 - 0 - - - 1 - 49 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_flush.c - tx_queue_flush.c - 0 - 0 - - - 1 - 50 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_front_send.c - tx_queue_front_send.c - 0 - 0 - - - 1 - 51 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_info_get.c - tx_queue_info_get.c - 0 - 0 - - - 1 - 52 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_initialize.c - tx_queue_initialize.c - 0 - 0 - - - 1 - 53 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_performance_info_get.c - tx_queue_performance_info_get.c - 0 - 0 - - - 1 - 54 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_performance_system_info_get.c - tx_queue_performance_system_info_get.c - 0 - 0 - - - 1 - 55 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_prioritize.c - tx_queue_prioritize.c - 0 - 0 - - - 1 - 56 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_receive.c - tx_queue_receive.c - 0 - 0 - - - 1 - 57 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_send.c - tx_queue_send.c - 0 - 0 - - - 1 - 58 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_queue_send_notify.c - tx_queue_send_notify.c - 0 - 0 - - - 1 - 59 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_ceiling_put.c - tx_semaphore_ceiling_put.c - 0 - 0 - - - 1 - 60 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_cleanup.c - tx_semaphore_cleanup.c - 0 - 0 - - - 1 - 61 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_create.c - tx_semaphore_create.c - 0 - 0 - - - 1 - 62 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_delete.c - tx_semaphore_delete.c - 0 - 0 - - - 1 - 63 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_get.c - tx_semaphore_get.c - 0 - 0 - - - 1 - 64 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_info_get.c - tx_semaphore_info_get.c - 0 - 0 - - - 1 - 65 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_initialize.c - tx_semaphore_initialize.c - 0 - 0 - - - 1 - 66 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_performance_info_get.c - tx_semaphore_performance_info_get.c - 0 - 0 - - - 1 - 67 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c - tx_semaphore_performance_system_info_get.c - 0 - 0 - - - 1 - 68 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_prioritize.c - tx_semaphore_prioritize.c - 0 - 0 - - - 1 - 69 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_put.c - tx_semaphore_put.c - 0 - 0 - - - 1 - 70 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_semaphore_put_notify.c - tx_semaphore_put_notify.c - 0 - 0 - - - 1 - 71 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_create.c - tx_thread_create.c - 0 - 0 - - - 1 - 72 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_delete.c - tx_thread_delete.c - 0 - 0 - - - 1 - 73 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_entry_exit_notify.c - tx_thread_entry_exit_notify.c - 0 - 0 - - - 1 - 74 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_identify.c - tx_thread_identify.c - 0 - 0 - - - 1 - 75 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_info_get.c - tx_thread_info_get.c - 0 - 0 - - - 1 - 76 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_initialize.c - tx_thread_initialize.c - 0 - 0 - - - 1 - 77 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_performance_info_get.c - tx_thread_performance_info_get.c - 0 - 0 - - - 1 - 78 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_performance_system_info_get.c - tx_thread_performance_system_info_get.c - 0 - 0 - - - 1 - 79 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_preemption_change.c - tx_thread_preemption_change.c - 0 - 0 - - - 1 - 80 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_priority_change.c - tx_thread_priority_change.c - 0 - 0 - - - 1 - 81 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_relinquish.c - tx_thread_relinquish.c - 0 - 0 - - - 1 - 82 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_reset.c - tx_thread_reset.c - 0 - 0 - - - 1 - 83 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_resume.c - tx_thread_resume.c - 0 - 0 - - - 1 - 84 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_shell_entry.c - tx_thread_shell_entry.c - 0 - 0 - - - 1 - 85 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_sleep.c - tx_thread_sleep.c - 0 - 0 - - - 1 - 86 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_stack_analyze.c - tx_thread_stack_analyze.c - 0 - 0 - - - 1 - 87 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_suspend.c - tx_thread_suspend.c - 0 - 0 - - - 1 - 88 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_system_preempt_check.c - tx_thread_system_preempt_check.c - 0 - 0 - - - 1 - 89 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_system_resume.c - tx_thread_system_resume.c - 0 - 0 - - - 1 - 90 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_system_suspend.c - tx_thread_system_suspend.c - 0 - 0 - - - 1 - 91 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_terminate.c - tx_thread_terminate.c - 0 - 0 - - - 1 - 92 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_time_slice.c - tx_thread_time_slice.c - 0 - 0 - - - 1 - 93 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_time_slice_change.c - tx_thread_time_slice_change.c - 0 - 0 - - - 1 - 94 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_timeout.c - tx_thread_timeout.c - 0 - 0 - - - 1 - 95 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_thread_wait_abort.c - tx_thread_wait_abort.c - 0 - 0 - - - 1 - 96 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_time_get.c - tx_time_get.c - 0 - 0 - - - 1 - 97 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_time_set.c - tx_time_set.c - 0 - 0 - - - 1 - 98 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_activate.c - tx_timer_activate.c - 0 - 0 - - - 1 - 99 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_change.c - tx_timer_change.c - 0 - 0 - - - 1 - 100 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_create.c - tx_timer_create.c - 0 - 0 - - - 1 - 101 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_deactivate.c - tx_timer_deactivate.c - 0 - 0 - - - 1 - 102 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_delete.c - tx_timer_delete.c - 0 - 0 - - - 1 - 103 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_expiration_process.c - tx_timer_expiration_process.c - 0 - 0 - - - 1 - 104 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_info_get.c - tx_timer_info_get.c - 0 - 0 - - - 1 - 105 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_initialize.c - tx_timer_initialize.c - 0 - 0 - - - 1 - 106 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_performance_info_get.c - tx_timer_performance_info_get.c - 0 - 0 - - - 1 - 107 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_performance_system_info_get.c - tx_timer_performance_system_info_get.c - 0 - 0 - - - 1 - 108 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_system_activate.c - tx_timer_system_activate.c - 0 - 0 - - - 1 - 109 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_system_deactivate.c - tx_timer_system_deactivate.c - 0 - 0 - - - 1 - 110 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_timer_thread_entry.c - tx_timer_thread_entry.c - 0 - 0 - - - 1 - 111 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_disable.c - tx_trace_disable.c - 0 - 0 - - - 1 - 112 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_enable.c - tx_trace_enable.c - 0 - 0 - - - 1 - 113 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_initialize.c - tx_trace_initialize.c - 0 - 0 - - - 1 - 114 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_interrupt_control.c - tx_trace_interrupt_control.c - 0 - 0 - - - 1 - 115 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_isr_enter_insert.c - tx_trace_isr_enter_insert.c - 0 - 0 - - - 1 - 116 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_isr_exit_insert.c - tx_trace_isr_exit_insert.c - 0 - 0 - - - 1 - 117 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_object_register.c - tx_trace_object_register.c - 0 - 0 - - - 1 - 118 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_object_unregister.c - tx_trace_object_unregister.c - 0 - 0 - - - 1 - 119 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_user_event_insert.c - tx_trace_user_event_insert.c - 0 - 0 - - - 1 - 120 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_allocate.c - txe_block_allocate.c - 0 - 0 - - - 1 - 121 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_create.c - txe_block_pool_create.c - 0 - 0 - - - 1 - 122 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_delete.c - txe_block_pool_delete.c - 0 - 0 - - - 1 - 123 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_info_get.c - txe_block_pool_info_get.c - 0 - 0 - - - 1 - 124 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_pool_prioritize.c - txe_block_pool_prioritize.c - 0 - 0 - - - 1 - 125 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_block_release.c - txe_block_release.c - 0 - 0 - - - 1 - 126 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_allocate.c - txe_byte_allocate.c - 0 - 0 - - - 1 - 127 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_create.c - txe_byte_pool_create.c - 0 - 0 - - - 1 - 128 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_delete.c - txe_byte_pool_delete.c - 0 - 0 - - - 1 - 129 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_info_get.c - txe_byte_pool_info_get.c - 0 - 0 - - - 1 - 130 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_pool_prioritize.c - txe_byte_pool_prioritize.c - 0 - 0 - - - 1 - 131 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_byte_release.c - txe_byte_release.c - 0 - 0 - - - 1 - 132 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_create.c - txe_event_flags_create.c - 0 - 0 - - - 1 - 133 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_delete.c - txe_event_flags_delete.c - 0 - 0 - - - 1 - 134 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_get.c - txe_event_flags_get.c - 0 - 0 - - - 1 - 135 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_info_get.c - txe_event_flags_info_get.c - 0 - 0 - - - 1 - 136 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_set.c - txe_event_flags_set.c - 0 - 0 - - - 1 - 137 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_event_flags_set_notify.c - txe_event_flags_set_notify.c - 0 - 0 - - - 1 - 138 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_create.c - txe_mutex_create.c - 0 - 0 - - - 1 - 139 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_delete.c - txe_mutex_delete.c - 0 - 0 - - - 1 - 140 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_get.c - txe_mutex_get.c - 0 - 0 - - - 1 - 141 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_info_get.c - txe_mutex_info_get.c - 0 - 0 - - - 1 - 142 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_prioritize.c - txe_mutex_prioritize.c - 0 - 0 - - - 1 - 143 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_mutex_put.c - txe_mutex_put.c - 0 - 0 - - - 1 - 144 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_create.c - txe_queue_create.c - 0 - 0 - - - 1 - 145 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_delete.c - txe_queue_delete.c - 0 - 0 - - - 1 - 146 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_flush.c - txe_queue_flush.c - 0 - 0 - - - 1 - 147 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_front_send.c - txe_queue_front_send.c - 0 - 0 - - - 1 - 148 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_info_get.c - txe_queue_info_get.c - 0 - 0 - - - 1 - 149 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_prioritize.c - txe_queue_prioritize.c - 0 - 0 - - - 1 - 150 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_receive.c - txe_queue_receive.c - 0 - 0 - - - 1 - 151 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_send.c - txe_queue_send.c - 0 - 0 - - - 1 - 152 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_queue_send_notify.c - txe_queue_send_notify.c - 0 - 0 - - - 1 - 153 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_ceiling_put.c - txe_semaphore_ceiling_put.c - 0 - 0 - - - 1 - 154 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_create.c - txe_semaphore_create.c - 0 - 0 - - - 1 - 155 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_delete.c - txe_semaphore_delete.c - 0 - 0 - - - 1 - 156 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_get.c - txe_semaphore_get.c - 0 - 0 - - - 1 - 157 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_info_get.c - txe_semaphore_info_get.c - 0 - 0 - - - 1 - 158 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_prioritize.c - txe_semaphore_prioritize.c - 0 - 0 - - - 1 - 159 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_put.c - txe_semaphore_put.c - 0 - 0 - - - 1 - 160 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_semaphore_put_notify.c - txe_semaphore_put_notify.c - 0 - 0 - - - 1 - 161 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_create.c - txe_thread_create.c - 0 - 0 - - - 1 - 162 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_delete.c - txe_thread_delete.c - 0 - 0 - - - 1 - 163 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_entry_exit_notify.c - txe_thread_entry_exit_notify.c - 0 - 0 - - - 1 - 164 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_info_get.c - txe_thread_info_get.c - 0 - 0 - - - 1 - 165 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_preemption_change.c - txe_thread_preemption_change.c - 0 - 0 - - - 1 - 166 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_priority_change.c - txe_thread_priority_change.c - 0 - 0 - - - 1 - 167 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_relinquish.c - txe_thread_relinquish.c - 0 - 0 - - - 1 - 168 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_reset.c - txe_thread_reset.c - 0 - 0 - - - 1 - 169 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_resume.c - txe_thread_resume.c - 0 - 0 - - - 1 - 170 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_suspend.c - txe_thread_suspend.c - 0 - 0 - - - 1 - 171 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_terminate.c - txe_thread_terminate.c - 0 - 0 - - - 1 - 172 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_time_slice_change.c - txe_thread_time_slice_change.c - 0 - 0 - - - 1 - 173 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_thread_wait_abort.c - txe_thread_wait_abort.c - 0 - 0 - - - 1 - 174 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_activate.c - txe_timer_activate.c - 0 - 0 - - - 1 - 175 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_change.c - txe_timer_change.c - 0 - 0 - - - 1 - 176 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_create.c - txe_timer_create.c - 0 - 0 - - - 1 - 177 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_deactivate.c - txe_timer_deactivate.c - 0 - 0 - - - 1 - 178 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_delete.c - txe_timer_delete.c - 0 - 0 - - - 1 - 179 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\txe_timer_info_get.c - txe_timer_info_get.c - 0 - 0 - - - 1 - 180 - 2 - 0 - 0 - 0 - ..\src\tx_timer_interrupt.s - tx_timer_interrupt.s - 0 - 0 - - - 1 - 181 - 2 - 0 - 0 - 0 - ..\src\tx_thread_context_restore.s - tx_thread_context_restore.s - 0 - 0 - - - 1 - 182 - 2 - 0 - 0 - 0 - ..\src\tx_thread_context_save.s - tx_thread_context_save.s - 0 - 0 - - - 1 - 183 - 2 - 0 - 0 - 0 - ..\src\tx_thread_interrupt_control.s - tx_thread_interrupt_control.s - 0 - 0 - - - 1 - 184 - 2 - 0 - 0 - 0 - ..\src\tx_thread_schedule.s - tx_thread_schedule.s - 0 - 0 - - - 1 - 185 - 2 - 0 - 0 - 0 - ..\src\tx_thread_stack_build.s - tx_thread_stack_build.s - 0 - 0 - - - 1 - 186 - 2 - 0 - 0 - 0 - ..\src\tx_thread_system_return.s - tx_thread_system_return.s - 0 - 0 - - - 1 - 187 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_buffer_full_notify.c - tx_trace_buffer_full_notify.c - 0 - 0 - - - 1 - 188 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_event_filter.c - tx_trace_event_filter.c - 0 - 0 - - - 1 - 189 - 1 - 0 - 0 - 0 - ..\..\..\..\common\src\tx_trace_event_unfilter.c - tx_trace_event_unfilter.c - 0 - 0 - - - 1 - 190 - 2 - 0 - 0 - 0 - ..\src\tx_thread_interrupt_disable.s - tx_thread_interrupt_disable.s - 0 - 0 - - - 1 - 191 - 2 - 0 - 0 - 0 - ..\src\tx_thread_interrupt_restore.s - tx_thread_interrupt_restore.s - 0 - 0 - - - 1 - 192 - 1 - 0 - 0 - 0 - ..\src\txe_thread_secure_stack_allocate.c - txe_thread_secure_stack_allocate.c - 0 - 0 - - - 1 - 193 - 1 - 0 - 0 - 0 - ..\src\txe_thread_secure_stack_free.c - txe_thread_secure_stack_free.c - 0 - 0 - - - 1 - 194 - 2 - 0 - 0 - 0 - ..\src\tx_thread_secure_stack_allocate.s - tx_thread_secure_stack_allocate.s - 0 - 0 - - - 1 - 195 - 2 - 0 - 0 - 0 - ..\src\tx_thread_secure_stack_free.s - tx_thread_secure_stack_free.s - 0 - 0 - - - 1 - 196 - 2 - 0 - 0 - 0 - .\tx_initialize_low_level.S - tx_initialize_low_level.S - 0 - 0 - - - 1 - 197 - 1 - 0 - 0 - 0 - ..\src\tx_thread_stack_error_handler.c - tx_thread_stack_error_handler.c - 0 - 0 - - - 1 - 198 - 1 - 0 - 0 - 0 - ..\src\tx_thread_stack_error_notify.c - tx_thread_stack_error_notify.c - 0 - 0 - - - - - ::CMSIS - 0 - 0 - 0 - 1 - - -
diff --git a/ports/cortex_m33/ac5/example_build/ThreadX_Library.uvprojx b/ports/cortex_m33/ac5/example_build/ThreadX_Library.uvprojx deleted file mode 100644 index 432fd4b2..00000000 --- a/ports/cortex_m33/ac5/example_build/ThreadX_Library.uvprojx +++ /dev/null @@ -1,1423 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - ThreadX_Library_Project - 0x4 - ARM-ADS - 6140000::V6.14::ARMCLANG - 1 - - - ARMCM33_DSP_FP_TZ - ARM - ARM.CMSIS.5.5.1 - http://www.keil.com/pack/ - IRAM(0x20000000,0x00020000) IRAM2(0x20200000,0x00020000) IROM(0x00000000,0x00200000) IROM2(0x00200000,0x00200000) CPUTYPE("Cortex-M33") FPU3(SFPU) DSP TZ CLOCK(12000000) ESEL ELITTLE - - - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - 0 - $$Device:ARMCM33_DSP_FP_TZ$Device\ARM\ARMCM33\Include\ARMCM33_DSP_FP_TZ.h - - - - - - - - - - - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\ - ThreadX_Library - 0 - 1 - 0 - 1 - 1 - .\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 0 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - - - - - SARMV8M.DLL - -MPU - TCM.DLL - -pCM33 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4100 - - 1 - BIN\ULP2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M33" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 2 - 0 - 0 - 1 - 1 - 8 - 0 - 1 - 0 - 1 - 4 - 4 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 1 - 0x0 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x200000 - - - 1 - 0x200000 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 0 - 0x20200000 - 0x20000 - - - - - - 0 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 3 - 1 - 1 - 1 - 0 - 0 - 0 - - - - - ..\..\..\..\common\inc, ..\inc - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 4 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - - - - - - - - - - - - Source Group - - - tx_block_allocate.c - 1 - ..\..\..\..\common\src\tx_block_allocate.c - - - tx_block_pool_cleanup.c - 1 - ..\..\..\..\common\src\tx_block_pool_cleanup.c - - - tx_block_pool_create.c - 1 - ..\..\..\..\common\src\tx_block_pool_create.c - - - tx_block_pool_delete.c - 1 - ..\..\..\..\common\src\tx_block_pool_delete.c - - - tx_block_pool_info_get.c - 1 - ..\..\..\..\common\src\tx_block_pool_info_get.c - - - tx_block_pool_initialize.c - 1 - ..\..\..\..\common\src\tx_block_pool_initialize.c - - - tx_block_pool_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_block_pool_performance_info_get.c - - - tx_block_pool_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c - - - tx_block_pool_prioritize.c - 1 - ..\..\..\..\common\src\tx_block_pool_prioritize.c - - - tx_block_release.c - 1 - ..\..\..\..\common\src\tx_block_release.c - - - tx_byte_allocate.c - 1 - ..\..\..\..\common\src\tx_byte_allocate.c - - - tx_byte_pool_cleanup.c - 1 - ..\..\..\..\common\src\tx_byte_pool_cleanup.c - - - tx_byte_pool_create.c - 1 - ..\..\..\..\common\src\tx_byte_pool_create.c - - - tx_byte_pool_delete.c - 1 - ..\..\..\..\common\src\tx_byte_pool_delete.c - - - tx_byte_pool_info_get.c - 1 - ..\..\..\..\common\src\tx_byte_pool_info_get.c - - - tx_byte_pool_initialize.c - 1 - ..\..\..\..\common\src\tx_byte_pool_initialize.c - - - tx_byte_pool_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_byte_pool_performance_info_get.c - - - tx_byte_pool_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c - - - tx_byte_pool_prioritize.c - 1 - ..\..\..\..\common\src\tx_byte_pool_prioritize.c - - - tx_byte_pool_search.c - 1 - ..\..\..\..\common\src\tx_byte_pool_search.c - - - tx_byte_release.c - 1 - ..\..\..\..\common\src\tx_byte_release.c - - - tx_event_flags_cleanup.c - 1 - ..\..\..\..\common\src\tx_event_flags_cleanup.c - - - tx_event_flags_create.c - 1 - ..\..\..\..\common\src\tx_event_flags_create.c - - - tx_event_flags_delete.c - 1 - ..\..\..\..\common\src\tx_event_flags_delete.c - - - tx_event_flags_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_get.c - - - tx_event_flags_info_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_info_get.c - - - tx_event_flags_initialize.c - 1 - ..\..\..\..\common\src\tx_event_flags_initialize.c - - - tx_event_flags_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_performance_info_get.c - - - tx_event_flags_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c - - - tx_event_flags_set.c - 1 - ..\..\..\..\common\src\tx_event_flags_set.c - - - tx_event_flags_set_notify.c - 1 - ..\..\..\..\common\src\tx_event_flags_set_notify.c - - - tx_initialize_high_level.c - 1 - ..\..\..\..\common\src\tx_initialize_high_level.c - - - tx_initialize_kernel_enter.c - 1 - ..\..\..\..\common\src\tx_initialize_kernel_enter.c - - - tx_initialize_kernel_setup.c - 1 - ..\..\..\..\common\src\tx_initialize_kernel_setup.c - - - tx_mutex_cleanup.c - 1 - ..\..\..\..\common\src\tx_mutex_cleanup.c - - - tx_mutex_create.c - 1 - ..\..\..\..\common\src\tx_mutex_create.c - - - tx_mutex_delete.c - 1 - ..\..\..\..\common\src\tx_mutex_delete.c - - - tx_mutex_get.c - 1 - ..\..\..\..\common\src\tx_mutex_get.c - - - tx_mutex_info_get.c - 1 - ..\..\..\..\common\src\tx_mutex_info_get.c - - - tx_mutex_initialize.c - 1 - ..\..\..\..\common\src\tx_mutex_initialize.c - - - tx_mutex_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_mutex_performance_info_get.c - - - tx_mutex_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_mutex_performance_system_info_get.c - - - tx_mutex_prioritize.c - 1 - ..\..\..\..\common\src\tx_mutex_prioritize.c - - - tx_mutex_priority_change.c - 1 - ..\..\..\..\common\src\tx_mutex_priority_change.c - - - tx_mutex_put.c - 1 - ..\..\..\..\common\src\tx_mutex_put.c - - - tx_queue_cleanup.c - 1 - ..\..\..\..\common\src\tx_queue_cleanup.c - - - tx_queue_create.c - 1 - ..\..\..\..\common\src\tx_queue_create.c - - - tx_queue_delete.c - 1 - ..\..\..\..\common\src\tx_queue_delete.c - - - tx_queue_flush.c - 1 - ..\..\..\..\common\src\tx_queue_flush.c - - - tx_queue_front_send.c - 1 - ..\..\..\..\common\src\tx_queue_front_send.c - - - tx_queue_info_get.c - 1 - ..\..\..\..\common\src\tx_queue_info_get.c - - - tx_queue_initialize.c - 1 - ..\..\..\..\common\src\tx_queue_initialize.c - - - tx_queue_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_queue_performance_info_get.c - - - tx_queue_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_queue_performance_system_info_get.c - - - tx_queue_prioritize.c - 1 - ..\..\..\..\common\src\tx_queue_prioritize.c - - - tx_queue_receive.c - 1 - ..\..\..\..\common\src\tx_queue_receive.c - - - tx_queue_send.c - 1 - ..\..\..\..\common\src\tx_queue_send.c - - - tx_queue_send_notify.c - 1 - ..\..\..\..\common\src\tx_queue_send_notify.c - - - tx_semaphore_ceiling_put.c - 1 - ..\..\..\..\common\src\tx_semaphore_ceiling_put.c - - - tx_semaphore_cleanup.c - 1 - ..\..\..\..\common\src\tx_semaphore_cleanup.c - - - tx_semaphore_create.c - 1 - ..\..\..\..\common\src\tx_semaphore_create.c - - - tx_semaphore_delete.c - 1 - ..\..\..\..\common\src\tx_semaphore_delete.c - - - tx_semaphore_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_get.c - - - tx_semaphore_info_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_info_get.c - - - tx_semaphore_initialize.c - 1 - ..\..\..\..\common\src\tx_semaphore_initialize.c - - - tx_semaphore_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_performance_info_get.c - - - tx_semaphore_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c - - - tx_semaphore_prioritize.c - 1 - ..\..\..\..\common\src\tx_semaphore_prioritize.c - - - tx_semaphore_put.c - 1 - ..\..\..\..\common\src\tx_semaphore_put.c - - - tx_semaphore_put_notify.c - 1 - ..\..\..\..\common\src\tx_semaphore_put_notify.c - - - tx_thread_create.c - 1 - ..\..\..\..\common\src\tx_thread_create.c - - - tx_thread_delete.c - 1 - ..\..\..\..\common\src\tx_thread_delete.c - - - tx_thread_entry_exit_notify.c - 1 - ..\..\..\..\common\src\tx_thread_entry_exit_notify.c - - - tx_thread_identify.c - 1 - ..\..\..\..\common\src\tx_thread_identify.c - - - tx_thread_info_get.c - 1 - ..\..\..\..\common\src\tx_thread_info_get.c - - - tx_thread_initialize.c - 1 - ..\..\..\..\common\src\tx_thread_initialize.c - - - tx_thread_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_thread_performance_info_get.c - - - tx_thread_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_thread_performance_system_info_get.c - - - tx_thread_preemption_change.c - 1 - ..\..\..\..\common\src\tx_thread_preemption_change.c - - - tx_thread_priority_change.c - 1 - ..\..\..\..\common\src\tx_thread_priority_change.c - - - tx_thread_relinquish.c - 1 - ..\..\..\..\common\src\tx_thread_relinquish.c - - - tx_thread_reset.c - 1 - ..\..\..\..\common\src\tx_thread_reset.c - - - tx_thread_resume.c - 1 - ..\..\..\..\common\src\tx_thread_resume.c - - - tx_thread_shell_entry.c - 1 - ..\..\..\..\common\src\tx_thread_shell_entry.c - - - tx_thread_sleep.c - 1 - ..\..\..\..\common\src\tx_thread_sleep.c - - - tx_thread_stack_analyze.c - 1 - ..\..\..\..\common\src\tx_thread_stack_analyze.c - - - tx_thread_suspend.c - 1 - ..\..\..\..\common\src\tx_thread_suspend.c - - - tx_thread_system_preempt_check.c - 1 - ..\..\..\..\common\src\tx_thread_system_preempt_check.c - - - tx_thread_system_resume.c - 1 - ..\..\..\..\common\src\tx_thread_system_resume.c - - - tx_thread_system_suspend.c - 1 - ..\..\..\..\common\src\tx_thread_system_suspend.c - - - tx_thread_terminate.c - 1 - ..\..\..\..\common\src\tx_thread_terminate.c - - - tx_thread_time_slice.c - 1 - ..\..\..\..\common\src\tx_thread_time_slice.c - - - tx_thread_time_slice_change.c - 1 - ..\..\..\..\common\src\tx_thread_time_slice_change.c - - - tx_thread_timeout.c - 1 - ..\..\..\..\common\src\tx_thread_timeout.c - - - tx_thread_wait_abort.c - 1 - ..\..\..\..\common\src\tx_thread_wait_abort.c - - - tx_time_get.c - 1 - ..\..\..\..\common\src\tx_time_get.c - - - tx_time_set.c - 1 - ..\..\..\..\common\src\tx_time_set.c - - - tx_timer_activate.c - 1 - ..\..\..\..\common\src\tx_timer_activate.c - - - tx_timer_change.c - 1 - ..\..\..\..\common\src\tx_timer_change.c - - - tx_timer_create.c - 1 - ..\..\..\..\common\src\tx_timer_create.c - - - tx_timer_deactivate.c - 1 - ..\..\..\..\common\src\tx_timer_deactivate.c - - - tx_timer_delete.c - 1 - ..\..\..\..\common\src\tx_timer_delete.c - - - tx_timer_expiration_process.c - 1 - ..\..\..\..\common\src\tx_timer_expiration_process.c - - - tx_timer_info_get.c - 1 - ..\..\..\..\common\src\tx_timer_info_get.c - - - tx_timer_initialize.c - 1 - ..\..\..\..\common\src\tx_timer_initialize.c - - - tx_timer_performance_info_get.c - 1 - ..\..\..\..\common\src\tx_timer_performance_info_get.c - - - tx_timer_performance_system_info_get.c - 1 - ..\..\..\..\common\src\tx_timer_performance_system_info_get.c - - - tx_timer_system_activate.c - 1 - ..\..\..\..\common\src\tx_timer_system_activate.c - - - tx_timer_system_deactivate.c - 1 - ..\..\..\..\common\src\tx_timer_system_deactivate.c - - - tx_timer_thread_entry.c - 1 - ..\..\..\..\common\src\tx_timer_thread_entry.c - - - tx_trace_disable.c - 1 - ..\..\..\..\common\src\tx_trace_disable.c - - - tx_trace_enable.c - 1 - ..\..\..\..\common\src\tx_trace_enable.c - - - tx_trace_initialize.c - 1 - ..\..\..\..\common\src\tx_trace_initialize.c - - - tx_trace_interrupt_control.c - 1 - ..\..\..\..\common\src\tx_trace_interrupt_control.c - - - tx_trace_isr_enter_insert.c - 1 - ..\..\..\..\common\src\tx_trace_isr_enter_insert.c - - - tx_trace_isr_exit_insert.c - 1 - ..\..\..\..\common\src\tx_trace_isr_exit_insert.c - - - tx_trace_object_register.c - 1 - ..\..\..\..\common\src\tx_trace_object_register.c - - - tx_trace_object_unregister.c - 1 - ..\..\..\..\common\src\tx_trace_object_unregister.c - - - tx_trace_user_event_insert.c - 1 - ..\..\..\..\common\src\tx_trace_user_event_insert.c - - - txe_block_allocate.c - 1 - ..\..\..\..\common\src\txe_block_allocate.c - - - txe_block_pool_create.c - 1 - ..\..\..\..\common\src\txe_block_pool_create.c - - - txe_block_pool_delete.c - 1 - ..\..\..\..\common\src\txe_block_pool_delete.c - - - txe_block_pool_info_get.c - 1 - ..\..\..\..\common\src\txe_block_pool_info_get.c - - - txe_block_pool_prioritize.c - 1 - ..\..\..\..\common\src\txe_block_pool_prioritize.c - - - txe_block_release.c - 1 - ..\..\..\..\common\src\txe_block_release.c - - - txe_byte_allocate.c - 1 - ..\..\..\..\common\src\txe_byte_allocate.c - - - txe_byte_pool_create.c - 1 - ..\..\..\..\common\src\txe_byte_pool_create.c - - - txe_byte_pool_delete.c - 1 - ..\..\..\..\common\src\txe_byte_pool_delete.c - - - txe_byte_pool_info_get.c - 1 - ..\..\..\..\common\src\txe_byte_pool_info_get.c - - - txe_byte_pool_prioritize.c - 1 - ..\..\..\..\common\src\txe_byte_pool_prioritize.c - - - txe_byte_release.c - 1 - ..\..\..\..\common\src\txe_byte_release.c - - - txe_event_flags_create.c - 1 - ..\..\..\..\common\src\txe_event_flags_create.c - - - txe_event_flags_delete.c - 1 - ..\..\..\..\common\src\txe_event_flags_delete.c - - - txe_event_flags_get.c - 1 - ..\..\..\..\common\src\txe_event_flags_get.c - - - txe_event_flags_info_get.c - 1 - ..\..\..\..\common\src\txe_event_flags_info_get.c - - - txe_event_flags_set.c - 1 - ..\..\..\..\common\src\txe_event_flags_set.c - - - txe_event_flags_set_notify.c - 1 - ..\..\..\..\common\src\txe_event_flags_set_notify.c - - - txe_mutex_create.c - 1 - ..\..\..\..\common\src\txe_mutex_create.c - - - txe_mutex_delete.c - 1 - ..\..\..\..\common\src\txe_mutex_delete.c - - - txe_mutex_get.c - 1 - ..\..\..\..\common\src\txe_mutex_get.c - - - txe_mutex_info_get.c - 1 - ..\..\..\..\common\src\txe_mutex_info_get.c - - - txe_mutex_prioritize.c - 1 - ..\..\..\..\common\src\txe_mutex_prioritize.c - - - txe_mutex_put.c - 1 - ..\..\..\..\common\src\txe_mutex_put.c - - - txe_queue_create.c - 1 - ..\..\..\..\common\src\txe_queue_create.c - - - txe_queue_delete.c - 1 - ..\..\..\..\common\src\txe_queue_delete.c - - - txe_queue_flush.c - 1 - ..\..\..\..\common\src\txe_queue_flush.c - - - txe_queue_front_send.c - 1 - ..\..\..\..\common\src\txe_queue_front_send.c - - - txe_queue_info_get.c - 1 - ..\..\..\..\common\src\txe_queue_info_get.c - - - txe_queue_prioritize.c - 1 - ..\..\..\..\common\src\txe_queue_prioritize.c - - - txe_queue_receive.c - 1 - ..\..\..\..\common\src\txe_queue_receive.c - - - txe_queue_send.c - 1 - ..\..\..\..\common\src\txe_queue_send.c - - - txe_queue_send_notify.c - 1 - ..\..\..\..\common\src\txe_queue_send_notify.c - - - txe_semaphore_ceiling_put.c - 1 - ..\..\..\..\common\src\txe_semaphore_ceiling_put.c - - - txe_semaphore_create.c - 1 - ..\..\..\..\common\src\txe_semaphore_create.c - - - txe_semaphore_delete.c - 1 - ..\..\..\..\common\src\txe_semaphore_delete.c - - - txe_semaphore_get.c - 1 - ..\..\..\..\common\src\txe_semaphore_get.c - - - txe_semaphore_info_get.c - 1 - ..\..\..\..\common\src\txe_semaphore_info_get.c - - - txe_semaphore_prioritize.c - 1 - ..\..\..\..\common\src\txe_semaphore_prioritize.c - - - txe_semaphore_put.c - 1 - ..\..\..\..\common\src\txe_semaphore_put.c - - - txe_semaphore_put_notify.c - 1 - ..\..\..\..\common\src\txe_semaphore_put_notify.c - - - txe_thread_create.c - 1 - ..\..\..\..\common\src\txe_thread_create.c - - - txe_thread_delete.c - 1 - ..\..\..\..\common\src\txe_thread_delete.c - - - txe_thread_entry_exit_notify.c - 1 - ..\..\..\..\common\src\txe_thread_entry_exit_notify.c - - - txe_thread_info_get.c - 1 - ..\..\..\..\common\src\txe_thread_info_get.c - - - txe_thread_preemption_change.c - 1 - ..\..\..\..\common\src\txe_thread_preemption_change.c - - - txe_thread_priority_change.c - 1 - ..\..\..\..\common\src\txe_thread_priority_change.c - - - txe_thread_relinquish.c - 1 - ..\..\..\..\common\src\txe_thread_relinquish.c - - - txe_thread_reset.c - 1 - ..\..\..\..\common\src\txe_thread_reset.c - - - txe_thread_resume.c - 1 - ..\..\..\..\common\src\txe_thread_resume.c - - - txe_thread_suspend.c - 1 - ..\..\..\..\common\src\txe_thread_suspend.c - - - txe_thread_terminate.c - 1 - ..\..\..\..\common\src\txe_thread_terminate.c - - - txe_thread_time_slice_change.c - 1 - ..\..\..\..\common\src\txe_thread_time_slice_change.c - - - txe_thread_wait_abort.c - 1 - ..\..\..\..\common\src\txe_thread_wait_abort.c - - - txe_timer_activate.c - 1 - ..\..\..\..\common\src\txe_timer_activate.c - - - txe_timer_change.c - 1 - ..\..\..\..\common\src\txe_timer_change.c - - - txe_timer_create.c - 1 - ..\..\..\..\common\src\txe_timer_create.c - - - txe_timer_deactivate.c - 1 - ..\..\..\..\common\src\txe_timer_deactivate.c - - - txe_timer_delete.c - 1 - ..\..\..\..\common\src\txe_timer_delete.c - - - txe_timer_info_get.c - 1 - ..\..\..\..\common\src\txe_timer_info_get.c - - - tx_timer_interrupt.s - 2 - ..\src\tx_timer_interrupt.s - - - tx_thread_context_restore.s - 2 - ..\src\tx_thread_context_restore.s - - - tx_thread_context_save.s - 2 - ..\src\tx_thread_context_save.s - - - tx_thread_interrupt_control.s - 2 - ..\src\tx_thread_interrupt_control.s - - - tx_thread_schedule.s - 2 - ..\src\tx_thread_schedule.s - - - tx_thread_stack_build.s - 2 - ..\src\tx_thread_stack_build.s - - - tx_thread_system_return.s - 2 - ..\src\tx_thread_system_return.s - - - tx_trace_buffer_full_notify.c - 1 - ..\..\..\..\common\src\tx_trace_buffer_full_notify.c - - - tx_trace_event_filter.c - 1 - ..\..\..\..\common\src\tx_trace_event_filter.c - - - tx_trace_event_unfilter.c - 1 - ..\..\..\..\common\src\tx_trace_event_unfilter.c - - - tx_thread_interrupt_disable.s - 2 - ..\src\tx_thread_interrupt_disable.s - - - tx_thread_interrupt_restore.s - 2 - ..\src\tx_thread_interrupt_restore.s - - - txe_thread_secure_stack_allocate.c - 1 - ..\src\txe_thread_secure_stack_allocate.c - - - txe_thread_secure_stack_free.c - 1 - ..\src\txe_thread_secure_stack_free.c - - - tx_thread_secure_stack_allocate.s - 2 - ..\src\tx_thread_secure_stack_allocate.s - - - tx_thread_secure_stack_free.s - 2 - ..\src\tx_thread_secure_stack_free.s - - - tx_initialize_low_level.S - 2 - .\tx_initialize_low_level.S - - - tx_thread_stack_error_handler.c - 1 - ..\src\tx_thread_stack_error_handler.c - - - tx_thread_stack_error_notify.c - 1 - ..\src\tx_thread_stack_error_notify.c - - - - - ::CMSIS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <Project Info> - - - - - - 0 - 1 - - - - -
diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/Abstract.txt b/ports/cortex_m33/ac5/example_build/demo_secure_zone/Abstract.txt deleted file mode 100644 index 0d1d8c52..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/Abstract.txt +++ /dev/null @@ -1,19 +0,0 @@ -This ARM Cortex-M33 secure/non-secure example project that -shows the setup of the CMSIS-RTOS2 RTX for TrustZone for -ARMv8-M applications. - -The application uses CMSIS and can be executed on a Fixed -Virtual Platform (FVP) simulation model. The application -demonstrates three RTOS threads. - - -Secure application: - - Setup code and start non-secure application. - -Non-secure application: - - Calls a secure function from non-secure state. - - Calls a secure function that call back to a non-secure function. - -Output: -Variables used in this application can be viewed in the Debugger -Watch window. \ No newline at end of file diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct b/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct deleted file mode 100644 index f1424c35..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct +++ /dev/null @@ -1,78 +0,0 @@ -#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m33 -xc -; command above MUST be in first line (no comment above!) - -/* -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------- -*/ - -/*--------------------- Flash Configuration ---------------------------------- -; Flash Configuration -; Flash Base Address <0x0-0xFFFFFFFF:8> -; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __ROM_BASE 0x00000000 -#define __ROM_SIZE 0x00200000 - -/*--------------------- Embedded RAM Configuration --------------------------- -; RAM Configuration -; RAM Base Address <0x0-0xFFFFFFFF:8> -; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __RAM_BASE 0x20000000 -#define __RAM_SIZE 0x00020000 - -/*--------------------- Stack / Heap Configuration --------------------------- -; Stack / Heap Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __STACK_SIZE 0x00000400 -#define __HEAP_SIZE 0x00000C00 - - -/*---------------------------------------------------------------------------- - User Stack & Heap boundery definition - *----------------------------------------------------------------------------*/ -#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ -#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ - - -/*---------------------------------------------------------------------------- - Scatter File Definitions definition - *----------------------------------------------------------------------------*/ -#define __RO_BASE __ROM_BASE -#define __RO_SIZE __ROM_SIZE - -#define __RW_BASE (__RAM_BASE ) -#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) - - - -LR_ROM __RO_BASE __RO_SIZE { ; load region size_region - ER_ROM __RO_BASE __RO_SIZE { ; load address = execution address - *.o (RESET, +First) - *(InRoot$$Sections) -; *(Veneer$$CMSE) ; uncomment for secure applications - .ANY (+RO) - .ANY (+XO) - } - - RW_RAM __RW_BASE __RW_SIZE { ; RW data - .ANY (+RW +ZI) - } - -#if __HEAP_SIZE > 0 - ARM_LIB_HEAP __HEAP_BASE EMPTY __HEAP_SIZE { ; Reserve empty region for heap - } -#endif - - ARM_LIB_STACK __STACK_TOP EMPTY -__STACK_SIZE { ; Reserve empty region for stack - } - SEAL +0 - { - *.o(.seal+FIRST) - } -} diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/partition_ARMCM33.h b/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/partition_ARMCM33.h deleted file mode 100644 index a7cb0d73..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/partition_ARMCM33.h +++ /dev/null @@ -1,1260 +0,0 @@ -/**************************************************************************//** - * @file partition_ARMCM33.h - * @brief CMSIS-CORE Initial Setup for Secure / Non-Secure Zones for ARMCM33 - * @version V1.1.1 - * @date 12. March 2019 - ******************************************************************************/ -/* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PARTITION_ARMCM33_H -#define PARTITION_ARMCM33_H - -/* -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -*/ - -/* -// Initialize Security Attribution Unit (SAU) CTRL register -*/ -#define SAU_INIT_CTRL 1 - -/* -// Enable SAU -// Value for SAU->CTRL register bit ENABLE -*/ -#define SAU_INIT_CTRL_ENABLE 1 - -/* -// When SAU is disabled -// <0=> All Memory is Secure -// <1=> All Memory is Non-Secure -// Value for SAU->CTRL register bit ALLNS -// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. -*/ -#define SAU_INIT_CTRL_ALLNS 0 - -/* -// -*/ - -/* -// Initialize Security Attribution Unit (SAU) Address Regions -// SAU configuration specifies regions to be one of: -// - Secure and Non-Secure Callable -// - Non-Secure -// Note: All memory regions not configured by SAU are Secure -*/ -#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ - -/* -// Initialize SAU Region 0 -// Setup SAU Region 0 memory attributes -*/ -#define SAU_INIT_REGION0 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START0 0x00000000 /* start address of SAU region 0 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END0 0x001FFFFF /* end address of SAU region 0 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC0 1 -/* -// -*/ - -/* -// Initialize SAU Region 1 -// Setup SAU Region 1 memory attributes -*/ -#define SAU_INIT_REGION1 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START1 0x00200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END1 0x003FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC1 0 -/* -// -*/ - -/* -// Initialize SAU Region 2 -// Setup SAU Region 2 memory attributes -*/ -#define SAU_INIT_REGION2 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START2 0x20200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END2 0x203FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC2 0 -/* -// -*/ - -/* -// Initialize SAU Region 3 -// Setup SAU Region 3 memory attributes -*/ -#define SAU_INIT_REGION3 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START3 0x40000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END3 0x40040000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC3 0 -/* -// -*/ - -/* -// Initialize SAU Region 4 -// Setup SAU Region 4 memory attributes -*/ -#define SAU_INIT_REGION4 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START4 0x00000000 /* start address of SAU region 4 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END4 0x00000000 /* end address of SAU region 4 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC4 0 -/* -// -*/ - -/* -// Initialize SAU Region 5 -// Setup SAU Region 5 memory attributes -*/ -#define SAU_INIT_REGION5 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START5 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END5 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC5 0 -/* -// -*/ - -/* -// Initialize SAU Region 6 -// Setup SAU Region 6 memory attributes -*/ -#define SAU_INIT_REGION6 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START6 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END6 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC6 0 -/* -// -*/ - -/* -// Initialize SAU Region 7 -// Setup SAU Region 7 memory attributes -*/ -#define SAU_INIT_REGION7 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START7 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END7 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC7 0 -/* -// -*/ - -/* -// -*/ - -/* -// Setup behaviour of Sleep and Exception Handling -*/ -#define SCB_CSR_AIRCR_INIT 1 - -/* -// Deep Sleep can be enabled by -// <0=>Secure and Non-Secure state -// <1=>Secure state only -// Value for SCB->CSR register bit DEEPSLEEPS -*/ -#define SCB_CSR_DEEPSLEEPS_VAL 1 - -/* -// System reset request accessible from -// <0=> Secure and Non-Secure state -// <1=> Secure state only -// Value for SCB->AIRCR register bit SYSRESETREQS -*/ -#define SCB_AIRCR_SYSRESETREQS_VAL 1 - -/* -// Priority of Non-Secure exceptions is -// <0=> Not altered -// <1=> Lowered to 0x80-0xFF -// Value for SCB->AIRCR register bit PRIS -*/ -#define SCB_AIRCR_PRIS_VAL 1 - -/* -// BusFault, HardFault, and NMI target -// <0=> Secure state -// <1=> Non-Secure state -// Value for SCB->AIRCR register bit BFHFNMINS -*/ -#define SCB_AIRCR_BFHFNMINS_VAL 0 - -/* -// -*/ - -/* -// Setup behaviour of Floating Point Unit -*/ -#define TZ_FPU_NS_USAGE 1 - -/* -// Floating Point Unit usage -// <0=> Secure state only -// <3=> Secure and Non-Secure state -// Value for SCB->NSACR register bits CP10, CP11 -*/ -#define SCB_NSACR_CP10_11_VAL 3 - -/* -// Treat floating-point registers as Secure -// <0=> Disabled -// <1=> Enabled -// Value for FPU->FPCCR register bit TS -*/ -#define FPU_FPCCR_TS_VAL 0 - -/* -// Clear on return (CLRONRET) accessibility -// <0=> Secure and Non-Secure state -// <1=> Secure state only -// Value for FPU->FPCCR register bit CLRONRETS -*/ -#define FPU_FPCCR_CLRONRETS_VAL 0 - -/* -// Clear floating-point caller saved registers on exception return -// <0=> Disabled -// <1=> Enabled -// Value for FPU->FPCCR register bit CLRONRET -*/ -#define FPU_FPCCR_CLRONRET_VAL 1 - -/* -// -*/ - -/* -// Setup Interrupt Target -*/ - -/* -// Initialize ITNS 0 (Interrupts 0..31) -*/ -#define NVIC_INIT_ITNS0 1 - -/* -// Interrupts 0..31 -// Interrupt 0 <0=> Secure state <1=> Non-Secure state -// Interrupt 1 <0=> Secure state <1=> Non-Secure state -// Interrupt 2 <0=> Secure state <1=> Non-Secure state -// Interrupt 3 <0=> Secure state <1=> Non-Secure state -// Interrupt 4 <0=> Secure state <1=> Non-Secure state -// Interrupt 5 <0=> Secure state <1=> Non-Secure state -// Interrupt 6 <0=> Secure state <1=> Non-Secure state -// Interrupt 7 <0=> Secure state <1=> Non-Secure state -// Interrupt 8 <0=> Secure state <1=> Non-Secure state -// Interrupt 9 <0=> Secure state <1=> Non-Secure state -// Interrupt 10 <0=> Secure state <1=> Non-Secure state -// Interrupt 11 <0=> Secure state <1=> Non-Secure state -// Interrupt 12 <0=> Secure state <1=> Non-Secure state -// Interrupt 13 <0=> Secure state <1=> Non-Secure state -// Interrupt 14 <0=> Secure state <1=> Non-Secure state -// Interrupt 15 <0=> Secure state <1=> Non-Secure state -// Interrupt 16 <0=> Secure state <1=> Non-Secure state -// Interrupt 17 <0=> Secure state <1=> Non-Secure state -// Interrupt 18 <0=> Secure state <1=> Non-Secure state -// Interrupt 19 <0=> Secure state <1=> Non-Secure state -// Interrupt 20 <0=> Secure state <1=> Non-Secure state -// Interrupt 21 <0=> Secure state <1=> Non-Secure state -// Interrupt 22 <0=> Secure state <1=> Non-Secure state -// Interrupt 23 <0=> Secure state <1=> Non-Secure state -// Interrupt 24 <0=> Secure state <1=> Non-Secure state -// Interrupt 25 <0=> Secure state <1=> Non-Secure state -// Interrupt 26 <0=> Secure state <1=> Non-Secure state -// Interrupt 27 <0=> Secure state <1=> Non-Secure state -// Interrupt 28 <0=> Secure state <1=> Non-Secure state -// Interrupt 29 <0=> Secure state <1=> Non-Secure state -// Interrupt 30 <0=> Secure state <1=> Non-Secure state -// Interrupt 31 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS0_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 1 (Interrupts 32..63) -*/ -#define NVIC_INIT_ITNS1 1 - -/* -// Interrupts 32..63 -// Interrupt 32 <0=> Secure state <1=> Non-Secure state -// Interrupt 33 <0=> Secure state <1=> Non-Secure state -// Interrupt 34 <0=> Secure state <1=> Non-Secure state -// Interrupt 35 <0=> Secure state <1=> Non-Secure state -// Interrupt 36 <0=> Secure state <1=> Non-Secure state -// Interrupt 37 <0=> Secure state <1=> Non-Secure state -// Interrupt 38 <0=> Secure state <1=> Non-Secure state -// Interrupt 39 <0=> Secure state <1=> Non-Secure state -// Interrupt 40 <0=> Secure state <1=> Non-Secure state -// Interrupt 41 <0=> Secure state <1=> Non-Secure state -// Interrupt 42 <0=> Secure state <1=> Non-Secure state -// Interrupt 43 <0=> Secure state <1=> Non-Secure state -// Interrupt 44 <0=> Secure state <1=> Non-Secure state -// Interrupt 45 <0=> Secure state <1=> Non-Secure state -// Interrupt 46 <0=> Secure state <1=> Non-Secure state -// Interrupt 47 <0=> Secure state <1=> Non-Secure state -// Interrupt 48 <0=> Secure state <1=> Non-Secure state -// Interrupt 49 <0=> Secure state <1=> Non-Secure state -// Interrupt 50 <0=> Secure state <1=> Non-Secure state -// Interrupt 51 <0=> Secure state <1=> Non-Secure state -// Interrupt 52 <0=> Secure state <1=> Non-Secure state -// Interrupt 53 <0=> Secure state <1=> Non-Secure state -// Interrupt 54 <0=> Secure state <1=> Non-Secure state -// Interrupt 55 <0=> Secure state <1=> Non-Secure state -// Interrupt 56 <0=> Secure state <1=> Non-Secure state -// Interrupt 57 <0=> Secure state <1=> Non-Secure state -// Interrupt 58 <0=> Secure state <1=> Non-Secure state -// Interrupt 59 <0=> Secure state <1=> Non-Secure state -// Interrupt 60 <0=> Secure state <1=> Non-Secure state -// Interrupt 61 <0=> Secure state <1=> Non-Secure state -// Interrupt 62 <0=> Secure state <1=> Non-Secure state -// Interrupt 63 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS1_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 2 (Interrupts 64..95) -*/ -#define NVIC_INIT_ITNS2 0 - -/* -// Interrupts 64..95 -// Interrupt 64 <0=> Secure state <1=> Non-Secure state -// Interrupt 65 <0=> Secure state <1=> Non-Secure state -// Interrupt 66 <0=> Secure state <1=> Non-Secure state -// Interrupt 67 <0=> Secure state <1=> Non-Secure state -// Interrupt 68 <0=> Secure state <1=> Non-Secure state -// Interrupt 69 <0=> Secure state <1=> Non-Secure state -// Interrupt 70 <0=> Secure state <1=> Non-Secure state -// Interrupt 71 <0=> Secure state <1=> Non-Secure state -// Interrupt 72 <0=> Secure state <1=> Non-Secure state -// Interrupt 73 <0=> Secure state <1=> Non-Secure state -// Interrupt 74 <0=> Secure state <1=> Non-Secure state -// Interrupt 75 <0=> Secure state <1=> Non-Secure state -// Interrupt 76 <0=> Secure state <1=> Non-Secure state -// Interrupt 77 <0=> Secure state <1=> Non-Secure state -// Interrupt 78 <0=> Secure state <1=> Non-Secure state -// Interrupt 79 <0=> Secure state <1=> Non-Secure state -// Interrupt 80 <0=> Secure state <1=> Non-Secure state -// Interrupt 81 <0=> Secure state <1=> Non-Secure state -// Interrupt 82 <0=> Secure state <1=> Non-Secure state -// Interrupt 83 <0=> Secure state <1=> Non-Secure state -// Interrupt 84 <0=> Secure state <1=> Non-Secure state -// Interrupt 85 <0=> Secure state <1=> Non-Secure state -// Interrupt 86 <0=> Secure state <1=> Non-Secure state -// Interrupt 87 <0=> Secure state <1=> Non-Secure state -// Interrupt 88 <0=> Secure state <1=> Non-Secure state -// Interrupt 89 <0=> Secure state <1=> Non-Secure state -// Interrupt 90 <0=> Secure state <1=> Non-Secure state -// Interrupt 91 <0=> Secure state <1=> Non-Secure state -// Interrupt 92 <0=> Secure state <1=> Non-Secure state -// Interrupt 93 <0=> Secure state <1=> Non-Secure state -// Interrupt 94 <0=> Secure state <1=> Non-Secure state -// Interrupt 95 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS2_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 3 (Interrupts 96..127) -*/ -#define NVIC_INIT_ITNS3 0 - -/* -// Interrupts 96..127 -// Interrupt 96 <0=> Secure state <1=> Non-Secure state -// Interrupt 97 <0=> Secure state <1=> Non-Secure state -// Interrupt 98 <0=> Secure state <1=> Non-Secure state -// Interrupt 99 <0=> Secure state <1=> Non-Secure state -// Interrupt 100 <0=> Secure state <1=> Non-Secure state -// Interrupt 101 <0=> Secure state <1=> Non-Secure state -// Interrupt 102 <0=> Secure state <1=> Non-Secure state -// Interrupt 103 <0=> Secure state <1=> Non-Secure state -// Interrupt 104 <0=> Secure state <1=> Non-Secure state -// Interrupt 105 <0=> Secure state <1=> Non-Secure state -// Interrupt 106 <0=> Secure state <1=> Non-Secure state -// Interrupt 107 <0=> Secure state <1=> Non-Secure state -// Interrupt 108 <0=> Secure state <1=> Non-Secure state -// Interrupt 109 <0=> Secure state <1=> Non-Secure state -// Interrupt 110 <0=> Secure state <1=> Non-Secure state -// Interrupt 111 <0=> Secure state <1=> Non-Secure state -// Interrupt 112 <0=> Secure state <1=> Non-Secure state -// Interrupt 113 <0=> Secure state <1=> Non-Secure state -// Interrupt 114 <0=> Secure state <1=> Non-Secure state -// Interrupt 115 <0=> Secure state <1=> Non-Secure state -// Interrupt 116 <0=> Secure state <1=> Non-Secure state -// Interrupt 117 <0=> Secure state <1=> Non-Secure state -// Interrupt 118 <0=> Secure state <1=> Non-Secure state -// Interrupt 119 <0=> Secure state <1=> Non-Secure state -// Interrupt 120 <0=> Secure state <1=> Non-Secure state -// Interrupt 121 <0=> Secure state <1=> Non-Secure state -// Interrupt 122 <0=> Secure state <1=> Non-Secure state -// Interrupt 123 <0=> Secure state <1=> Non-Secure state -// Interrupt 124 <0=> Secure state <1=> Non-Secure state -// Interrupt 125 <0=> Secure state <1=> Non-Secure state -// Interrupt 126 <0=> Secure state <1=> Non-Secure state -// Interrupt 127 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS3_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 4 (Interrupts 128..159) -*/ -#define NVIC_INIT_ITNS4 0 - -/* -// Interrupts 128..159 -// Interrupt 128 <0=> Secure state <1=> Non-Secure state -// Interrupt 129 <0=> Secure state <1=> Non-Secure state -// Interrupt 130 <0=> Secure state <1=> Non-Secure state -// Interrupt 131 <0=> Secure state <1=> Non-Secure state -// Interrupt 132 <0=> Secure state <1=> Non-Secure state -// Interrupt 133 <0=> Secure state <1=> Non-Secure state -// Interrupt 134 <0=> Secure state <1=> Non-Secure state -// Interrupt 135 <0=> Secure state <1=> Non-Secure state -// Interrupt 136 <0=> Secure state <1=> Non-Secure state -// Interrupt 137 <0=> Secure state <1=> Non-Secure state -// Interrupt 138 <0=> Secure state <1=> Non-Secure state -// Interrupt 139 <0=> Secure state <1=> Non-Secure state -// Interrupt 140 <0=> Secure state <1=> Non-Secure state -// Interrupt 141 <0=> Secure state <1=> Non-Secure state -// Interrupt 142 <0=> Secure state <1=> Non-Secure state -// Interrupt 143 <0=> Secure state <1=> Non-Secure state -// Interrupt 144 <0=> Secure state <1=> Non-Secure state -// Interrupt 145 <0=> Secure state <1=> Non-Secure state -// Interrupt 146 <0=> Secure state <1=> Non-Secure state -// Interrupt 147 <0=> Secure state <1=> Non-Secure state -// Interrupt 148 <0=> Secure state <1=> Non-Secure state -// Interrupt 149 <0=> Secure state <1=> Non-Secure state -// Interrupt 150 <0=> Secure state <1=> Non-Secure state -// Interrupt 151 <0=> Secure state <1=> Non-Secure state -// Interrupt 152 <0=> Secure state <1=> Non-Secure state -// Interrupt 153 <0=> Secure state <1=> Non-Secure state -// Interrupt 154 <0=> Secure state <1=> Non-Secure state -// Interrupt 155 <0=> Secure state <1=> Non-Secure state -// Interrupt 156 <0=> Secure state <1=> Non-Secure state -// Interrupt 157 <0=> Secure state <1=> Non-Secure state -// Interrupt 158 <0=> Secure state <1=> Non-Secure state -// Interrupt 159 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS4_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 5 (Interrupts 160..191) -*/ -#define NVIC_INIT_ITNS5 0 - -/* -// Interrupts 160..191 -// Interrupt 160 <0=> Secure state <1=> Non-Secure state -// Interrupt 161 <0=> Secure state <1=> Non-Secure state -// Interrupt 162 <0=> Secure state <1=> Non-Secure state -// Interrupt 163 <0=> Secure state <1=> Non-Secure state -// Interrupt 164 <0=> Secure state <1=> Non-Secure state -// Interrupt 165 <0=> Secure state <1=> Non-Secure state -// Interrupt 166 <0=> Secure state <1=> Non-Secure state -// Interrupt 167 <0=> Secure state <1=> Non-Secure state -// Interrupt 168 <0=> Secure state <1=> Non-Secure state -// Interrupt 169 <0=> Secure state <1=> Non-Secure state -// Interrupt 170 <0=> Secure state <1=> Non-Secure state -// Interrupt 171 <0=> Secure state <1=> Non-Secure state -// Interrupt 172 <0=> Secure state <1=> Non-Secure state -// Interrupt 173 <0=> Secure state <1=> Non-Secure state -// Interrupt 174 <0=> Secure state <1=> Non-Secure state -// Interrupt 175 <0=> Secure state <1=> Non-Secure state -// Interrupt 176 <0=> Secure state <1=> Non-Secure state -// Interrupt 177 <0=> Secure state <1=> Non-Secure state -// Interrupt 178 <0=> Secure state <1=> Non-Secure state -// Interrupt 179 <0=> Secure state <1=> Non-Secure state -// Interrupt 180 <0=> Secure state <1=> Non-Secure state -// Interrupt 181 <0=> Secure state <1=> Non-Secure state -// Interrupt 182 <0=> Secure state <1=> Non-Secure state -// Interrupt 183 <0=> Secure state <1=> Non-Secure state -// Interrupt 184 <0=> Secure state <1=> Non-Secure state -// Interrupt 185 <0=> Secure state <1=> Non-Secure state -// Interrupt 186 <0=> Secure state <1=> Non-Secure state -// Interrupt 187 <0=> Secure state <1=> Non-Secure state -// Interrupt 188 <0=> Secure state <1=> Non-Secure state -// Interrupt 189 <0=> Secure state <1=> Non-Secure state -// Interrupt 190 <0=> Secure state <1=> Non-Secure state -// Interrupt 191 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS5_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 6 (Interrupts 192..223) -*/ -#define NVIC_INIT_ITNS6 0 - -/* -// Interrupts 192..223 -// Interrupt 192 <0=> Secure state <1=> Non-Secure state -// Interrupt 193 <0=> Secure state <1=> Non-Secure state -// Interrupt 194 <0=> Secure state <1=> Non-Secure state -// Interrupt 195 <0=> Secure state <1=> Non-Secure state -// Interrupt 196 <0=> Secure state <1=> Non-Secure state -// Interrupt 197 <0=> Secure state <1=> Non-Secure state -// Interrupt 198 <0=> Secure state <1=> Non-Secure state -// Interrupt 199 <0=> Secure state <1=> Non-Secure state -// Interrupt 200 <0=> Secure state <1=> Non-Secure state -// Interrupt 201 <0=> Secure state <1=> Non-Secure state -// Interrupt 202 <0=> Secure state <1=> Non-Secure state -// Interrupt 203 <0=> Secure state <1=> Non-Secure state -// Interrupt 204 <0=> Secure state <1=> Non-Secure state -// Interrupt 205 <0=> Secure state <1=> Non-Secure state -// Interrupt 206 <0=> Secure state <1=> Non-Secure state -// Interrupt 207 <0=> Secure state <1=> Non-Secure state -// Interrupt 208 <0=> Secure state <1=> Non-Secure state -// Interrupt 209 <0=> Secure state <1=> Non-Secure state -// Interrupt 210 <0=> Secure state <1=> Non-Secure state -// Interrupt 211 <0=> Secure state <1=> Non-Secure state -// Interrupt 212 <0=> Secure state <1=> Non-Secure state -// Interrupt 213 <0=> Secure state <1=> Non-Secure state -// Interrupt 214 <0=> Secure state <1=> Non-Secure state -// Interrupt 215 <0=> Secure state <1=> Non-Secure state -// Interrupt 216 <0=> Secure state <1=> Non-Secure state -// Interrupt 217 <0=> Secure state <1=> Non-Secure state -// Interrupt 218 <0=> Secure state <1=> Non-Secure state -// Interrupt 219 <0=> Secure state <1=> Non-Secure state -// Interrupt 220 <0=> Secure state <1=> Non-Secure state -// Interrupt 221 <0=> Secure state <1=> Non-Secure state -// Interrupt 222 <0=> Secure state <1=> Non-Secure state -// Interrupt 223 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS6_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 7 (Interrupts 224..255) -*/ -#define NVIC_INIT_ITNS7 0 - -/* -// Interrupts 224..255 -// Interrupt 224 <0=> Secure state <1=> Non-Secure state -// Interrupt 225 <0=> Secure state <1=> Non-Secure state -// Interrupt 226 <0=> Secure state <1=> Non-Secure state -// Interrupt 227 <0=> Secure state <1=> Non-Secure state -// Interrupt 228 <0=> Secure state <1=> Non-Secure state -// Interrupt 229 <0=> Secure state <1=> Non-Secure state -// Interrupt 230 <0=> Secure state <1=> Non-Secure state -// Interrupt 231 <0=> Secure state <1=> Non-Secure state -// Interrupt 232 <0=> Secure state <1=> Non-Secure state -// Interrupt 233 <0=> Secure state <1=> Non-Secure state -// Interrupt 234 <0=> Secure state <1=> Non-Secure state -// Interrupt 235 <0=> Secure state <1=> Non-Secure state -// Interrupt 236 <0=> Secure state <1=> Non-Secure state -// Interrupt 237 <0=> Secure state <1=> Non-Secure state -// Interrupt 238 <0=> Secure state <1=> Non-Secure state -// Interrupt 239 <0=> Secure state <1=> Non-Secure state -// Interrupt 240 <0=> Secure state <1=> Non-Secure state -// Interrupt 241 <0=> Secure state <1=> Non-Secure state -// Interrupt 242 <0=> Secure state <1=> Non-Secure state -// Interrupt 243 <0=> Secure state <1=> Non-Secure state -// Interrupt 244 <0=> Secure state <1=> Non-Secure state -// Interrupt 245 <0=> Secure state <1=> Non-Secure state -// Interrupt 246 <0=> Secure state <1=> Non-Secure state -// Interrupt 247 <0=> Secure state <1=> Non-Secure state -// Interrupt 248 <0=> Secure state <1=> Non-Secure state -// Interrupt 249 <0=> Secure state <1=> Non-Secure state -// Interrupt 250 <0=> Secure state <1=> Non-Secure state -// Interrupt 251 <0=> Secure state <1=> Non-Secure state -// Interrupt 252 <0=> Secure state <1=> Non-Secure state -// Interrupt 253 <0=> Secure state <1=> Non-Secure state -// Interrupt 254 <0=> Secure state <1=> Non-Secure state -// Interrupt 255 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS7_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 8 (Interrupts 256..287) -*/ -#define NVIC_INIT_ITNS8 0 - -/* -// Interrupts 256..287 -// Interrupt 256 <0=> Secure state <1=> Non-Secure state -// Interrupt 257 <0=> Secure state <1=> Non-Secure state -// Interrupt 258 <0=> Secure state <1=> Non-Secure state -// Interrupt 259 <0=> Secure state <1=> Non-Secure state -// Interrupt 260 <0=> Secure state <1=> Non-Secure state -// Interrupt 261 <0=> Secure state <1=> Non-Secure state -// Interrupt 262 <0=> Secure state <1=> Non-Secure state -// Interrupt 263 <0=> Secure state <1=> Non-Secure state -// Interrupt 264 <0=> Secure state <1=> Non-Secure state -// Interrupt 265 <0=> Secure state <1=> Non-Secure state -// Interrupt 266 <0=> Secure state <1=> Non-Secure state -// Interrupt 267 <0=> Secure state <1=> Non-Secure state -// Interrupt 268 <0=> Secure state <1=> Non-Secure state -// Interrupt 269 <0=> Secure state <1=> Non-Secure state -// Interrupt 270 <0=> Secure state <1=> Non-Secure state -// Interrupt 271 <0=> Secure state <1=> Non-Secure state -// Interrupt 272 <0=> Secure state <1=> Non-Secure state -// Interrupt 273 <0=> Secure state <1=> Non-Secure state -// Interrupt 274 <0=> Secure state <1=> Non-Secure state -// Interrupt 275 <0=> Secure state <1=> Non-Secure state -// Interrupt 276 <0=> Secure state <1=> Non-Secure state -// Interrupt 277 <0=> Secure state <1=> Non-Secure state -// Interrupt 278 <0=> Secure state <1=> Non-Secure state -// Interrupt 279 <0=> Secure state <1=> Non-Secure state -// Interrupt 280 <0=> Secure state <1=> Non-Secure state -// Interrupt 281 <0=> Secure state <1=> Non-Secure state -// Interrupt 282 <0=> Secure state <1=> Non-Secure state -// Interrupt 283 <0=> Secure state <1=> Non-Secure state -// Interrupt 284 <0=> Secure state <1=> Non-Secure state -// Interrupt 285 <0=> Secure state <1=> Non-Secure state -// Interrupt 286 <0=> Secure state <1=> Non-Secure state -// Interrupt 287 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS8_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 9 (Interrupts 288..319) -*/ -#define NVIC_INIT_ITNS9 0 - -/* -// Interrupts 288..319 -// Interrupt 288 <0=> Secure state <1=> Non-Secure state -// Interrupt 289 <0=> Secure state <1=> Non-Secure state -// Interrupt 290 <0=> Secure state <1=> Non-Secure state -// Interrupt 291 <0=> Secure state <1=> Non-Secure state -// Interrupt 292 <0=> Secure state <1=> Non-Secure state -// Interrupt 293 <0=> Secure state <1=> Non-Secure state -// Interrupt 294 <0=> Secure state <1=> Non-Secure state -// Interrupt 295 <0=> Secure state <1=> Non-Secure state -// Interrupt 296 <0=> Secure state <1=> Non-Secure state -// Interrupt 297 <0=> Secure state <1=> Non-Secure state -// Interrupt 298 <0=> Secure state <1=> Non-Secure state -// Interrupt 299 <0=> Secure state <1=> Non-Secure state -// Interrupt 300 <0=> Secure state <1=> Non-Secure state -// Interrupt 301 <0=> Secure state <1=> Non-Secure state -// Interrupt 302 <0=> Secure state <1=> Non-Secure state -// Interrupt 303 <0=> Secure state <1=> Non-Secure state -// Interrupt 304 <0=> Secure state <1=> Non-Secure state -// Interrupt 305 <0=> Secure state <1=> Non-Secure state -// Interrupt 306 <0=> Secure state <1=> Non-Secure state -// Interrupt 307 <0=> Secure state <1=> Non-Secure state -// Interrupt 308 <0=> Secure state <1=> Non-Secure state -// Interrupt 309 <0=> Secure state <1=> Non-Secure state -// Interrupt 310 <0=> Secure state <1=> Non-Secure state -// Interrupt 311 <0=> Secure state <1=> Non-Secure state -// Interrupt 312 <0=> Secure state <1=> Non-Secure state -// Interrupt 313 <0=> Secure state <1=> Non-Secure state -// Interrupt 314 <0=> Secure state <1=> Non-Secure state -// Interrupt 315 <0=> Secure state <1=> Non-Secure state -// Interrupt 316 <0=> Secure state <1=> Non-Secure state -// Interrupt 317 <0=> Secure state <1=> Non-Secure state -// Interrupt 318 <0=> Secure state <1=> Non-Secure state -// Interrupt 319 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS9_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 10 (Interrupts 320..351) -*/ -#define NVIC_INIT_ITNS10 0 - -/* -// Interrupts 320..351 -// Interrupt 320 <0=> Secure state <1=> Non-Secure state -// Interrupt 321 <0=> Secure state <1=> Non-Secure state -// Interrupt 322 <0=> Secure state <1=> Non-Secure state -// Interrupt 323 <0=> Secure state <1=> Non-Secure state -// Interrupt 324 <0=> Secure state <1=> Non-Secure state -// Interrupt 325 <0=> Secure state <1=> Non-Secure state -// Interrupt 326 <0=> Secure state <1=> Non-Secure state -// Interrupt 327 <0=> Secure state <1=> Non-Secure state -// Interrupt 328 <0=> Secure state <1=> Non-Secure state -// Interrupt 329 <0=> Secure state <1=> Non-Secure state -// Interrupt 330 <0=> Secure state <1=> Non-Secure state -// Interrupt 331 <0=> Secure state <1=> Non-Secure state -// Interrupt 332 <0=> Secure state <1=> Non-Secure state -// Interrupt 333 <0=> Secure state <1=> Non-Secure state -// Interrupt 334 <0=> Secure state <1=> Non-Secure state -// Interrupt 335 <0=> Secure state <1=> Non-Secure state -// Interrupt 336 <0=> Secure state <1=> Non-Secure state -// Interrupt 337 <0=> Secure state <1=> Non-Secure state -// Interrupt 338 <0=> Secure state <1=> Non-Secure state -// Interrupt 339 <0=> Secure state <1=> Non-Secure state -// Interrupt 340 <0=> Secure state <1=> Non-Secure state -// Interrupt 341 <0=> Secure state <1=> Non-Secure state -// Interrupt 342 <0=> Secure state <1=> Non-Secure state -// Interrupt 343 <0=> Secure state <1=> Non-Secure state -// Interrupt 344 <0=> Secure state <1=> Non-Secure state -// Interrupt 345 <0=> Secure state <1=> Non-Secure state -// Interrupt 346 <0=> Secure state <1=> Non-Secure state -// Interrupt 347 <0=> Secure state <1=> Non-Secure state -// Interrupt 348 <0=> Secure state <1=> Non-Secure state -// Interrupt 349 <0=> Secure state <1=> Non-Secure state -// Interrupt 350 <0=> Secure state <1=> Non-Secure state -// Interrupt 351 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS10_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 11 (Interrupts 352..383) -*/ -#define NVIC_INIT_ITNS11 0 - -/* -// Interrupts 352..383 -// Interrupt 352 <0=> Secure state <1=> Non-Secure state -// Interrupt 353 <0=> Secure state <1=> Non-Secure state -// Interrupt 354 <0=> Secure state <1=> Non-Secure state -// Interrupt 355 <0=> Secure state <1=> Non-Secure state -// Interrupt 356 <0=> Secure state <1=> Non-Secure state -// Interrupt 357 <0=> Secure state <1=> Non-Secure state -// Interrupt 358 <0=> Secure state <1=> Non-Secure state -// Interrupt 359 <0=> Secure state <1=> Non-Secure state -// Interrupt 360 <0=> Secure state <1=> Non-Secure state -// Interrupt 361 <0=> Secure state <1=> Non-Secure state -// Interrupt 362 <0=> Secure state <1=> Non-Secure state -// Interrupt 363 <0=> Secure state <1=> Non-Secure state -// Interrupt 364 <0=> Secure state <1=> Non-Secure state -// Interrupt 365 <0=> Secure state <1=> Non-Secure state -// Interrupt 366 <0=> Secure state <1=> Non-Secure state -// Interrupt 367 <0=> Secure state <1=> Non-Secure state -// Interrupt 368 <0=> Secure state <1=> Non-Secure state -// Interrupt 369 <0=> Secure state <1=> Non-Secure state -// Interrupt 370 <0=> Secure state <1=> Non-Secure state -// Interrupt 371 <0=> Secure state <1=> Non-Secure state -// Interrupt 372 <0=> Secure state <1=> Non-Secure state -// Interrupt 373 <0=> Secure state <1=> Non-Secure state -// Interrupt 374 <0=> Secure state <1=> Non-Secure state -// Interrupt 375 <0=> Secure state <1=> Non-Secure state -// Interrupt 376 <0=> Secure state <1=> Non-Secure state -// Interrupt 377 <0=> Secure state <1=> Non-Secure state -// Interrupt 378 <0=> Secure state <1=> Non-Secure state -// Interrupt 379 <0=> Secure state <1=> Non-Secure state -// Interrupt 380 <0=> Secure state <1=> Non-Secure state -// Interrupt 381 <0=> Secure state <1=> Non-Secure state -// Interrupt 382 <0=> Secure state <1=> Non-Secure state -// Interrupt 383 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS11_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 12 (Interrupts 384..415) -*/ -#define NVIC_INIT_ITNS12 0 - -/* -// Interrupts 384..415 -// Interrupt 384 <0=> Secure state <1=> Non-Secure state -// Interrupt 385 <0=> Secure state <1=> Non-Secure state -// Interrupt 386 <0=> Secure state <1=> Non-Secure state -// Interrupt 387 <0=> Secure state <1=> Non-Secure state -// Interrupt 388 <0=> Secure state <1=> Non-Secure state -// Interrupt 389 <0=> Secure state <1=> Non-Secure state -// Interrupt 390 <0=> Secure state <1=> Non-Secure state -// Interrupt 391 <0=> Secure state <1=> Non-Secure state -// Interrupt 392 <0=> Secure state <1=> Non-Secure state -// Interrupt 393 <0=> Secure state <1=> Non-Secure state -// Interrupt 394 <0=> Secure state <1=> Non-Secure state -// Interrupt 395 <0=> Secure state <1=> Non-Secure state -// Interrupt 396 <0=> Secure state <1=> Non-Secure state -// Interrupt 397 <0=> Secure state <1=> Non-Secure state -// Interrupt 398 <0=> Secure state <1=> Non-Secure state -// Interrupt 399 <0=> Secure state <1=> Non-Secure state -// Interrupt 400 <0=> Secure state <1=> Non-Secure state -// Interrupt 401 <0=> Secure state <1=> Non-Secure state -// Interrupt 402 <0=> Secure state <1=> Non-Secure state -// Interrupt 403 <0=> Secure state <1=> Non-Secure state -// Interrupt 404 <0=> Secure state <1=> Non-Secure state -// Interrupt 405 <0=> Secure state <1=> Non-Secure state -// Interrupt 406 <0=> Secure state <1=> Non-Secure state -// Interrupt 407 <0=> Secure state <1=> Non-Secure state -// Interrupt 408 <0=> Secure state <1=> Non-Secure state -// Interrupt 409 <0=> Secure state <1=> Non-Secure state -// Interrupt 410 <0=> Secure state <1=> Non-Secure state -// Interrupt 411 <0=> Secure state <1=> Non-Secure state -// Interrupt 412 <0=> Secure state <1=> Non-Secure state -// Interrupt 413 <0=> Secure state <1=> Non-Secure state -// Interrupt 414 <0=> Secure state <1=> Non-Secure state -// Interrupt 415 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS12_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 13 (Interrupts 416..447) -*/ -#define NVIC_INIT_ITNS13 0 - -/* -// Interrupts 416..447 -// Interrupt 416 <0=> Secure state <1=> Non-Secure state -// Interrupt 417 <0=> Secure state <1=> Non-Secure state -// Interrupt 418 <0=> Secure state <1=> Non-Secure state -// Interrupt 419 <0=> Secure state <1=> Non-Secure state -// Interrupt 420 <0=> Secure state <1=> Non-Secure state -// Interrupt 421 <0=> Secure state <1=> Non-Secure state -// Interrupt 422 <0=> Secure state <1=> Non-Secure state -// Interrupt 423 <0=> Secure state <1=> Non-Secure state -// Interrupt 424 <0=> Secure state <1=> Non-Secure state -// Interrupt 425 <0=> Secure state <1=> Non-Secure state -// Interrupt 426 <0=> Secure state <1=> Non-Secure state -// Interrupt 427 <0=> Secure state <1=> Non-Secure state -// Interrupt 428 <0=> Secure state <1=> Non-Secure state -// Interrupt 429 <0=> Secure state <1=> Non-Secure state -// Interrupt 430 <0=> Secure state <1=> Non-Secure state -// Interrupt 431 <0=> Secure state <1=> Non-Secure state -// Interrupt 432 <0=> Secure state <1=> Non-Secure state -// Interrupt 433 <0=> Secure state <1=> Non-Secure state -// Interrupt 434 <0=> Secure state <1=> Non-Secure state -// Interrupt 435 <0=> Secure state <1=> Non-Secure state -// Interrupt 436 <0=> Secure state <1=> Non-Secure state -// Interrupt 437 <0=> Secure state <1=> Non-Secure state -// Interrupt 438 <0=> Secure state <1=> Non-Secure state -// Interrupt 439 <0=> Secure state <1=> Non-Secure state -// Interrupt 440 <0=> Secure state <1=> Non-Secure state -// Interrupt 441 <0=> Secure state <1=> Non-Secure state -// Interrupt 442 <0=> Secure state <1=> Non-Secure state -// Interrupt 443 <0=> Secure state <1=> Non-Secure state -// Interrupt 444 <0=> Secure state <1=> Non-Secure state -// Interrupt 445 <0=> Secure state <1=> Non-Secure state -// Interrupt 446 <0=> Secure state <1=> Non-Secure state -// Interrupt 447 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS13_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 14 (Interrupts 448..479) -*/ -#define NVIC_INIT_ITNS14 0 - -/* -// Interrupts 448..479 -// Interrupt 448 <0=> Secure state <1=> Non-Secure state -// Interrupt 449 <0=> Secure state <1=> Non-Secure state -// Interrupt 450 <0=> Secure state <1=> Non-Secure state -// Interrupt 451 <0=> Secure state <1=> Non-Secure state -// Interrupt 452 <0=> Secure state <1=> Non-Secure state -// Interrupt 453 <0=> Secure state <1=> Non-Secure state -// Interrupt 454 <0=> Secure state <1=> Non-Secure state -// Interrupt 455 <0=> Secure state <1=> Non-Secure state -// Interrupt 456 <0=> Secure state <1=> Non-Secure state -// Interrupt 457 <0=> Secure state <1=> Non-Secure state -// Interrupt 458 <0=> Secure state <1=> Non-Secure state -// Interrupt 459 <0=> Secure state <1=> Non-Secure state -// Interrupt 460 <0=> Secure state <1=> Non-Secure state -// Interrupt 461 <0=> Secure state <1=> Non-Secure state -// Interrupt 462 <0=> Secure state <1=> Non-Secure state -// Interrupt 463 <0=> Secure state <1=> Non-Secure state -// Interrupt 464 <0=> Secure state <1=> Non-Secure state -// Interrupt 465 <0=> Secure state <1=> Non-Secure state -// Interrupt 466 <0=> Secure state <1=> Non-Secure state -// Interrupt 467 <0=> Secure state <1=> Non-Secure state -// Interrupt 468 <0=> Secure state <1=> Non-Secure state -// Interrupt 469 <0=> Secure state <1=> Non-Secure state -// Interrupt 470 <0=> Secure state <1=> Non-Secure state -// Interrupt 471 <0=> Secure state <1=> Non-Secure state -// Interrupt 472 <0=> Secure state <1=> Non-Secure state -// Interrupt 473 <0=> Secure state <1=> Non-Secure state -// Interrupt 474 <0=> Secure state <1=> Non-Secure state -// Interrupt 475 <0=> Secure state <1=> Non-Secure state -// Interrupt 476 <0=> Secure state <1=> Non-Secure state -// Interrupt 477 <0=> Secure state <1=> Non-Secure state -// Interrupt 478 <0=> Secure state <1=> Non-Secure state -// Interrupt 479 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS14_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 15 (Interrupts 480..511) -*/ -#define NVIC_INIT_ITNS15 0 - -/* -// Interrupts 480..511 -// Interrupt 480 <0=> Secure state <1=> Non-Secure state -// Interrupt 481 <0=> Secure state <1=> Non-Secure state -// Interrupt 482 <0=> Secure state <1=> Non-Secure state -// Interrupt 483 <0=> Secure state <1=> Non-Secure state -// Interrupt 484 <0=> Secure state <1=> Non-Secure state -// Interrupt 485 <0=> Secure state <1=> Non-Secure state -// Interrupt 486 <0=> Secure state <1=> Non-Secure state -// Interrupt 487 <0=> Secure state <1=> Non-Secure state -// Interrupt 488 <0=> Secure state <1=> Non-Secure state -// Interrupt 489 <0=> Secure state <1=> Non-Secure state -// Interrupt 490 <0=> Secure state <1=> Non-Secure state -// Interrupt 491 <0=> Secure state <1=> Non-Secure state -// Interrupt 492 <0=> Secure state <1=> Non-Secure state -// Interrupt 493 <0=> Secure state <1=> Non-Secure state -// Interrupt 494 <0=> Secure state <1=> Non-Secure state -// Interrupt 495 <0=> Secure state <1=> Non-Secure state -// Interrupt 496 <0=> Secure state <1=> Non-Secure state -// Interrupt 497 <0=> Secure state <1=> Non-Secure state -// Interrupt 498 <0=> Secure state <1=> Non-Secure state -// Interrupt 499 <0=> Secure state <1=> Non-Secure state -// Interrupt 500 <0=> Secure state <1=> Non-Secure state -// Interrupt 501 <0=> Secure state <1=> Non-Secure state -// Interrupt 502 <0=> Secure state <1=> Non-Secure state -// Interrupt 503 <0=> Secure state <1=> Non-Secure state -// Interrupt 504 <0=> Secure state <1=> Non-Secure state -// Interrupt 505 <0=> Secure state <1=> Non-Secure state -// Interrupt 506 <0=> Secure state <1=> Non-Secure state -// Interrupt 507 <0=> Secure state <1=> Non-Secure state -// Interrupt 508 <0=> Secure state <1=> Non-Secure state -// Interrupt 509 <0=> Secure state <1=> Non-Secure state -// Interrupt 510 <0=> Secure state <1=> Non-Secure state -// Interrupt 511 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS15_VAL 0x00000000 - -/* -// -*/ - -/* -// -*/ - - - -/* - max 128 SAU regions. - SAU regions are defined in partition.h - */ - -#define SAU_INIT_REGION(n) \ - SAU->RNR = (n & SAU_RNR_REGION_Msk); \ - SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ - SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ - ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U - -/** - \brief Setup a SAU Region - \details Writes the region information contained in SAU_Region to the - registers SAU_RNR, SAU_RBAR, and SAU_RLAR - */ -__STATIC_INLINE void TZ_SAU_Setup (void) -{ - -#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) - - #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) - SAU_INIT_REGION(0); - #endif - - #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) - SAU_INIT_REGION(1); - #endif - - #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) - SAU_INIT_REGION(2); - #endif - - #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) - SAU_INIT_REGION(3); - #endif - - #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) - SAU_INIT_REGION(4); - #endif - - #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) - SAU_INIT_REGION(5); - #endif - - #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) - SAU_INIT_REGION(6); - #endif - - #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) - SAU_INIT_REGION(7); - #endif - - /* repeat this for all possible SAU regions */ - -#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ - - - #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) - SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | - ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; - #endif - - #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) - SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | - ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); - - SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | - SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk )) | - ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | - ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | - ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | - ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); - #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ - - #if defined (__FPU_USED) && (__FPU_USED == 1U) && \ - defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U) - - SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | - ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); - - FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | - ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | - ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | - ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); - #endif - - #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) - NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; - #endif - - #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) - NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; - #endif - - #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) - NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; - #endif - - #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) - NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; - #endif - - #if defined (NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U) - NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL; - #endif - - #if defined (NVIC_INIT_ITNS5) && (NVIC_INIT_ITNS5 == 1U) - NVIC->ITNS[5] = NVIC_INIT_ITNS5_VAL; - #endif - - #if defined (NVIC_INIT_ITNS6) && (NVIC_INIT_ITNS6 == 1U) - NVIC->ITNS[6] = NVIC_INIT_ITNS6_VAL; - #endif - - #if defined (NVIC_INIT_ITNS7) && (NVIC_INIT_ITNS7 == 1U) - NVIC->ITNS[7] = NVIC_INIT_ITNS7_VAL; - #endif - - #if defined (NVIC_INIT_ITNS8) && (NVIC_INIT_ITNS8 == 1U) - NVIC->ITNS[8] = NVIC_INIT_ITNS8_VAL; - #endif - - #if defined (NVIC_INIT_ITNS9) && (NVIC_INIT_ITNS9 == 1U) - NVIC->ITNS[9] = NVIC_INIT_ITNS9_VAL; - #endif - - #if defined (NVIC_INIT_ITNS10) && (NVIC_INIT_ITNS10 == 1U) - NVIC->ITNS[10] = NVIC_INIT_ITNS10_VAL; - #endif - - #if defined (NVIC_INIT_ITNS11) && (NVIC_INIT_ITNS11 == 1U) - NVIC->ITNS[11] = NVIC_INIT_ITNS11_VAL; - #endif - - #if defined (NVIC_INIT_ITNS12) && (NVIC_INIT_ITNS12 == 1U) - NVIC->ITNS[12] = NVIC_INIT_ITNS12_VAL; - #endif - - #if defined (NVIC_INIT_ITNS13) && (NVIC_INIT_ITNS13 == 1U) - NVIC->ITNS[13] = NVIC_INIT_ITNS13_VAL; - #endif - - #if defined (NVIC_INIT_ITNS14) && (NVIC_INIT_ITNS14 == 1U) - NVIC->ITNS[14] = NVIC_INIT_ITNS14_VAL; - #endif - - #if defined (NVIC_INIT_ITNS15) && (NVIC_INIT_ITNS15 == 1U) - NVIC->ITNS[15] = NVIC_INIT_ITNS15_VAL; - #endif - - /* repeat this for all possible ITNS elements */ - -} - -#endif /* PARTITION_ARMCM33_H */ diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c b/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c deleted file mode 100644 index 4fcc5dbc..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c +++ /dev/null @@ -1,139 +0,0 @@ -/****************************************************************************** - * @file startup_ARMCM33.c - * @brief CMSIS Core Device Startup File for Cortex-M33 Device - * @version V2.0.0 - * @date 20. May 2019 - ******************************************************************************/ -/* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM33) - #include "ARMCM33.h" -#elif defined (ARMCM33_TZ) - #include "ARMCM33_TZ.h" -#elif defined (ARMCM33_DSP_FP) - #include "ARMCM33_DSP_FP.h" -#elif defined (ARMCM33_DSP_FP_TZ) - #include "ARMCM33_DSP_FP_TZ.h" -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler Function Prototype - *----------------------------------------------------------------------------*/ -typedef void( *pFunc )( void ); - -/*---------------------------------------------------------------------------- - External References - *----------------------------------------------------------------------------*/ -extern uint32_t __INITIAL_SP; -extern uint32_t __STACK_LIMIT; - -extern void __PROGRAM_START(void) __NO_RETURN; - -/*---------------------------------------------------------------------------- - Internal References - *----------------------------------------------------------------------------*/ -void Default_Handler(void) __NO_RETURN; -void Reset_Handler (void) __NO_RETURN; - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler - *----------------------------------------------------------------------------*/ -/* Exceptions */ -void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SecureFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - -void Interrupt0_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt1_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt2_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt3_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt4_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt5_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt6_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt7_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt8_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt9_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - - -/*---------------------------------------------------------------------------- - Exception / Interrupt Vector table - *----------------------------------------------------------------------------*/ -extern const pFunc __VECTOR_TABLE[496]; - const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { - (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ - Reset_Handler, /* Reset Handler */ - NMI_Handler, /* -14 NMI Handler */ - HardFault_Handler, /* -13 Hard Fault Handler */ - MemManage_Handler, /* -12 MPU Fault Handler */ - BusFault_Handler, /* -11 Bus Fault Handler */ - UsageFault_Handler, /* -10 Usage Fault Handler */ - SecureFault_Handler, /* -9 Secure Fault Handler */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - SVC_Handler, /* -5 SVCall Handler */ - DebugMon_Handler, /* -4 Debug Monitor Handler */ - 0, /* Reserved */ - PendSV_Handler, /* -2 PendSV Handler */ - SysTick_Handler, /* -1 SysTick Handler */ - - /* Interrupts */ - Interrupt0_Handler, /* 0 Interrupt 0 */ - Interrupt1_Handler, /* 1 Interrupt 1 */ - Interrupt2_Handler, /* 2 Interrupt 2 */ - Interrupt3_Handler, /* 3 Interrupt 3 */ - Interrupt4_Handler, /* 4 Interrupt 4 */ - Interrupt5_Handler, /* 5 Interrupt 5 */ - Interrupt6_Handler, /* 6 Interrupt 6 */ - Interrupt7_Handler, /* 7 Interrupt 7 */ - Interrupt8_Handler, /* 8 Interrupt 8 */ - Interrupt9_Handler /* 9 Interrupt 9 */ - /* Interrupts 10 .. 480 are left out */ -}; - -/* The linker will place this value at the bottom of the stack to seal the secure main stack. */ -const int stack_seal __attribute__((section (".seal"))) = 0xFEF5EDA5; - -/*---------------------------------------------------------------------------- - Reset Handler called on controller reset - *----------------------------------------------------------------------------*/ -void Reset_Handler(void) -{ - __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); - - SystemInit(); /* CMSIS System Initialization */ - __PROGRAM_START(); /* Enter PreMain (C library entry point) */ -} - -/*---------------------------------------------------------------------------- - Default Handler for Exceptions / Interrupts - *----------------------------------------------------------------------------*/ -void Default_Handler(void) -{ - while(1); -} diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c b/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c deleted file mode 100644 index 36cb0c63..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************//** - * @file system_ARMCM33.c - * @brief CMSIS Device System Source File for - * ARMCM33 Device - * @version V5.3.1 - * @date 09. July 2018 - ******************************************************************************/ -/* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM33) - #include "ARMCM33.h" -#elif defined (ARMCM33_TZ) - #include "ARMCM33_TZ.h" - - #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - #include "partition_ARMCM33.h" - #endif -#elif defined (ARMCM33_DSP_FP) - #include "ARMCM33_DSP_FP.h" -#elif defined (ARMCM33_DSP_FP_TZ) - #include "ARMCM33_DSP_FP_TZ.h" - - #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - #include "partition_ARMCM33.h" - #endif -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Define clocks - *----------------------------------------------------------------------------*/ -#define XTAL (50000000UL) /* Oscillator frequency */ - -#define SYSTEM_CLOCK (XTAL / 2U) - - -/*---------------------------------------------------------------------------- - Externals - *----------------------------------------------------------------------------*/ -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - extern uint32_t __Vectors; -#endif - -/*---------------------------------------------------------------------------- - System Core Clock Variable - *----------------------------------------------------------------------------*/ -uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Core Clock Frequency */ - - -/*---------------------------------------------------------------------------- - System Core Clock update function - *----------------------------------------------------------------------------*/ -void SystemCoreClockUpdate (void) -{ - SystemCoreClock = SYSTEM_CLOCK; -} - -/*---------------------------------------------------------------------------- - System initialization function - *----------------------------------------------------------------------------*/ -void SystemInit (void) -{ - -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - SCB->VTOR = (uint32_t) &__Vectors; -#endif - -#if defined (__FPU_USED) && (__FPU_USED == 1U) - SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ - (3U << 11U*2U) ); /* enable CP11 Full Access */ -#endif - -#ifdef UNALIGNED_SUPPORT_DISABLE - SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; -#endif - -#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - TZ_SAU_Setup(); -#endif - - SystemCoreClock = SYSTEM_CLOCK; - - *(uint32_t *)0xE000ED24 = 0x000F0000; /* S: enable secure, usage, bus, mem faults */ - *(uint32_t *)0xE002ED24 = 0x000F0000; /* NS: enable secure, usage, bus, mem faults */ -} - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -void HardFault_Handler(void) -{ - while(1); - -} - -void UsageFault_Handler(void) -{ - while(1); -} -#endif diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h b/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h deleted file mode 100644 index 65bfdcd7..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'demo_secure_zone' - * Target: 'FVP Simulation Model' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM33_DSP_FP_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/demo_secure_zone.uvoptx b/ports/cortex_m33/ac5/example_build/demo_secure_zone/demo_secure_zone.uvoptx deleted file mode 100644 index ec235687..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/demo_secure_zone.uvoptx +++ /dev/null @@ -1,318 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - FVP Simulation Model - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\Listings\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 0 - 0 - 1 - - 7 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 15 - - - - - - - - - - ..\Debug.ini - BIN\DbgFMv8M.DLL - - - - 0 - DLGTARM - (6010=245,200,722,796,0)(6018=306,263,495,612,0)(6019=488,279,677,615,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=724,129,982,860,0)(6015=-1,-1,-1,-1,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) - - - 0 - DbgFMv8M - -I -S -L"cpu0" -O4102 -C0 -MC".\FVP\MPS2_Cortex-M\FVP_MPS2_Cortex-M33_MDK.exe" -MF"..\ARMCM33_DSP_FP_TZ_config.txt" -PF -MA - - - 0 - UL2V8M - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - - - - - - 0 - 1 - thread_0_counter - - - 1 - 1 - thread_1_counter - - - 2 - 1 - thread_2_counter - - - 3 - 1 - thread_3_counter - - - 4 - 1 - thread_4_counter - - - 5 - 1 - thread_5_counter - - - 6 - 1 - thread_6_counter - - - 7 - 1 - thread_7_counter - - - - - 1 - 2 - 0x2001ffd8 - 0 - - - - - 2 - 2 - 0xE000ED28 - 0 - - - - 0 - - - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - - - Secure Code - 1 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - .\main_s.c - main_s.c - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - ..\..\src\tx_thread_secure_stack.c - tx_thread_secure_stack.c - 0 - 0 - - - - - Interface - 1 - 0 - 0 - 0 - - 2 - 3 - 1 - 0 - 0 - 0 - .\interface.c - interface.c - 0 - 0 - - - - - ::CMSIS - 0 - 0 - 0 - 1 - - - - ::Device - 1 - 0 - 0 - 1 - - -
diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/demo_secure_zone.uvprojx b/ports/cortex_m33/ac5/example_build/demo_secure_zone/demo_secure_zone.uvprojx deleted file mode 100644 index c2fac3e4..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/demo_secure_zone.uvprojx +++ /dev/null @@ -1,497 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - FVP Simulation Model - 0x4 - ARM-ADS - 6140000::V6.14::ARMCLANG - 1 - - - ARMCM33_DSP_FP_TZ - ARM - ARM.CMSIS.5.7.0 - http://www.keil.com/pack/ - IRAM(0x20000000,0x00020000) IRAM2(0x20200000,0x00020000) IROM(0x00000000,0x00200000) IROM2(0x00200000,0x00200000) CPUTYPE("Cortex-M33") FPU3(SFPU) DSP TZ CLOCK(12000000) ESEL ELITTLE - - - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - 0 - $$Device:ARMCM33_DSP_FP_TZ$Device\ARM\ARMCM33\Include\ARMCM33_DSP_FP_TZ.h - - - - - - - - - - $$Device:ARMCM33_DSP_FP_TZ$Device\ARM\SVD\ARMCM33.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\Objects\ - demo_secure_zone - 1 - 0 - 0 - 1 - 1 - .\Listings\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - - - - - SARMV8M.DLL - -MPU - TCM.DLL - -pCM33 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 0 - -1 - - 1 - BIN\UL2V8M.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M33" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 2 - 0 - 0 - 1 - 1 - 8 - 1 - 1 - 0 - 1 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 1 - 0x0 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x200000 - - - 1 - 0x200000 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 0 - 0x20200000 - 0x20000 - - - - - - 1 - 7 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 0 - 0 - 0 - 0 - 3 - 3 - 1 - 1 - 0 - 0 - 0 - - - - - ..\..\..\..\..\common\inc, ..\..\inc - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 4 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - .\RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_AC6.sct - - - - - - - - - - - Secure Code - - - main_s.c - 1 - .\main_s.c - - - tx_thread_secure_stack.c - 1 - ..\..\src\tx_thread_secure_stack.c - - - - - Interface - - - interface.c - 1 - .\interface.c - - - - - ::CMSIS - - - ::Device - - - - - - - - - - - - - - - - - - - - - - - - RTE\CMSIS\RTX_Config.c - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_ac6.sct - - - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\partition_ARMCM33.h - - - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.c - - - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\system_ARMCM33.c - - - - - - - - - - - - - <Project Info> - - - - - - 0 - 1 - - - - -
diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/interface.c b/ports/cortex_m33/ac5/example_build/demo_secure_zone/interface.c deleted file mode 100644 index 4e6e8eee..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/interface.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * interface.c Secure/non-secure callable application code - * - * Version 1.0 - * Initial Release - *---------------------------------------------------------------------------*/ - - -#include // CMSE definitions -#include "interface.h" // Header file with secure interface API - -/* typedef for non-secure callback functions */ -typedef funcptr funcptr_NS __attribute__((cmse_nonsecure_call)); - -/* Non-secure callable (entry) function */ -int func1(int x) __attribute__((cmse_nonsecure_entry)) { - return x+3; -} - -/* Non-secure callable (entry) function, calling a non-secure callback function */ -int func2(funcptr callback, int x) __attribute__((cmse_nonsecure_entry)) { - funcptr_NS callback_NS; // non-secure callback function pointer - int y; - - /* return function pointer with cleared LSB */ - callback_NS = (funcptr_NS)cmse_nsfptr_create(callback); - - y = callback_NS (x+1); - - return (y+2); -} diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/interface.h b/ports/cortex_m33/ac5/example_build/demo_secure_zone/interface.h deleted file mode 100644 index 8215d5a3..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/interface.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * interface.h API definition for the non-secure state - * - * Version 1.0 - * Initial Release - *---------------------------------------------------------------------------*/ - -/* Function pointer declaration */ -typedef int (*funcptr)(int); - -/* Non-secure callable functions */ -extern int func1(int x); -extern int func2(funcptr callback, int x); diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/main_ns.c b/ports/cortex_m33/ac5/example_build/demo_secure_zone/main_ns.c deleted file mode 100644 index 5d16e1bb..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/main_ns.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * main_ns.c Non-secure main function - RTOS demo - * - * Version 1.0 - * Initial Release - *---------------------------------------------------------------------------*/ - -#include "interface.h" // Interface API -//#include "cmsis_os2.h" // ARM::CMSIS:RTOS2:Keil RTX5 - -//static osStatus_t Status; - -//static osThreadId_t ThreadA_Id; -//static osThreadId_t ThreadB_Id; -//static osThreadId_t ThreadC_Id; - -void ThreadA (void *argument); -void ThreadB (void *argument); -void ThreadC (void *argument); - - -extern volatile int counterA; -extern volatile int counterB; -extern volatile int counterC; - -volatile int counterA; -volatile int counterB; -volatile int counterC; - -/* -static int callbackA (int val) { - return (val); -} - -__attribute__((noreturn)) -void ThreadA (void *argument) { - (void)argument; - - for (;;) { - counterA = func1 (counterA); - counterA = func2 (callbackA, counterA); - osDelay(2U); - } -} - -static int callbackB (int val) { - uint32_t flags; - - flags = osThreadFlagsWait (1U, osFlagsWaitAny, osWaitForever); - if (flags == 1U) { - return (val+1); - } else { - return (0); - } -} - - -__attribute__((noreturn)) -void ThreadB (void *argument) { - (void)argument; - - for (;;) { - counterB = func1 (counterB); - counterB = func2 (callbackB, counterB); - } -} - -__attribute__((noreturn)) -void ThreadC (void *argument) { - (void)argument; - - for (;;) { - counterC = counterC + 1; - if ((counterC % 0x10) == 0) { - osThreadFlagsSet (ThreadB_Id, 1); - } - osDelay(1U); - } -} - -static const osThreadAttr_t ThreadAttr = { - .tz_module = 1U, // indicate calls to secure mode -}; -*/ -#if 1 -int main (void) { - - for (;;); -} -#endif diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/main_s.c b/ports/cortex_m33/ac5/example_build/demo_secure_zone/main_s.c deleted file mode 100644 index 2c667821..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/main_s.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2013-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * $Date: 15. October 2016 - * $Revision: 1.1.0 - * - * Project: TrustZone for ARMv8-M - * Title: Code template for secure main function - * - *---------------------------------------------------------------------------*/ - -/* Use CMSE intrinsics */ -#include - #include -#include "RTE_Components.h" -#include CMSIS_device_header - -/* TZ_START_NS: Start address of non-secure application */ -#ifndef TZ_START_NS -#define TZ_START_NS (0x200000U) -#endif - -/* typedef for non-secure callback functions */ -typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call)); - -/* Secure main() */ -int main(void) { - funcptr_void NonSecure_ResetHandler; - - /* Add user setup code for secure part here*/ - - /* Set non-secure main stack (MSP_NS) */ - __TZ_set_MSP_NS(*((uint32_t *)(TZ_START_NS))); - - /* Get non-secure reset handler */ - NonSecure_ResetHandler = (funcptr_void)(*((uint32_t *)((TZ_START_NS) + 4U))); - - /* Start non-secure state software application */ - NonSecure_ResetHandler(); - - /* Non-secure software does not return, this code is not executed */ - while (1) { - __NOP(); - } -} diff --git a/ports/cortex_m33/ac5/example_build/demo_secure_zone/tz_context.c b/ports/cortex_m33/ac5/example_build/demo_secure_zone/tz_context.c deleted file mode 100644 index f3152890..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_secure_zone/tz_context.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2015-2016 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------------- - * - * $Date: 15. October 2016 - * $Revision: 1.1.0 - * - * Project: TrustZone for ARMv8-M - * Title: Context Management for ARMv8-M TrustZone - Sample implementation - * - *---------------------------------------------------------------------------*/ - -#include "RTE_Components.h" -#include CMSIS_device_header -#include "tz_context.h" - -/// Number of process slots (threads may call secure library code) -#ifndef TZ_PROCESS_STACK_SLOTS -#define TZ_PROCESS_STACK_SLOTS 8U -#endif - -/// Stack size of the secure library code -#ifndef TZ_PROCESS_STACK_SIZE -#define TZ_PROCESS_STACK_SIZE 256U -#endif - -typedef struct { - uint32_t sp_top; // stack space top - uint32_t sp_limit; // stack space limit - uint32_t sp; // current stack pointer -} stack_info_t; - -static stack_info_t ProcessStackInfo [TZ_PROCESS_STACK_SLOTS]; -static uint64_t ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U]; -static uint32_t ProcessStackFreeSlot = 0xFFFFFFFFU; - - -/// Initialize secure context memory system -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_InitContextSystem_S (void) { - uint32_t n; - - if (__get_IPSR() == 0U) { - return 0U; // Thread Mode - } - - for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) { - ProcessStackInfo[n].sp = 0U; - ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n]; - ProcessStackInfo[n].sp_top = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE; - *((uint32_t *)ProcessStackMemory[n]) = n + 1U; - } - *((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU; - - ProcessStackFreeSlot = 0U; - - // Default process stack pointer and stack limit - __set_PSPLIM((uint32_t)ProcessStackMemory); - __set_PSP ((uint32_t)ProcessStackMemory); - - // Privileged Thread Mode using PSP - __set_CONTROL(0x02U); - - return 1U; // Success -} - - -/// Allocate context memory for calling secure software modules in TrustZone -/// \param[in] module identifies software modules called from non-secure mode -/// \return value != 0 id TrustZone memory slot identifier -/// \return value 0 no memory available or internal error -__attribute__((cmse_nonsecure_entry)) -TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) { - uint32_t slot; - - (void)module; // Ignore (fixed Stack size) - - if (__get_IPSR() == 0U) { - return 0U; // Thread Mode - } - - if (ProcessStackFreeSlot == 0xFFFFFFFFU) { - return 0U; // No slot available - } - - slot = ProcessStackFreeSlot; - ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]); - - ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top; - - return (slot + 1U); -} - - -/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S -/// \param[in] id TrustZone memory slot identifier -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) { - uint32_t slot; - - if (__get_IPSR() == 0U) { - return 0U; // Thread Mode - } - - if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { - return 0U; // Invalid ID - } - - slot = id - 1U; - - if (ProcessStackInfo[slot].sp == 0U) { - return 0U; // Inactive slot - } - ProcessStackInfo[slot].sp = 0U; - - *((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot; - ProcessStackFreeSlot = slot; - - return 1U; // Success -} - - -/// Load secure context (called on RTOS thread context switch) -/// \param[in] id TrustZone memory slot identifier -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) { - uint32_t slot; - - if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { - return 0U; // Thread Mode or using Main Stack for threads - } - - if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { - return 0U; // Invalid ID - } - - slot = id - 1U; - - if (ProcessStackInfo[slot].sp == 0U) { - return 0U; // Inactive slot - } - - // Setup process stack pointer and stack limit - __set_PSPLIM(ProcessStackInfo[slot].sp_limit); - __set_PSP (ProcessStackInfo[slot].sp); - - return 1U; // Success -} - - -/// Store secure context (called on RTOS thread context switch) -/// \param[in] id TrustZone memory slot identifier -/// \return execution status (1: success, 0: error) -__attribute__((cmse_nonsecure_entry)) -uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) { - uint32_t slot; - uint32_t sp; - - if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { - return 0U; // Thread Mode or using Main Stack for threads - } - - if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { - return 0U; // Invalid ID - } - - slot = id - 1U; - - if (ProcessStackInfo[slot].sp == 0U) { - return 0U; // Inactive slot - } - - sp = __get_PSP(); - if ((sp < ProcessStackInfo[slot].sp_limit) || - (sp > ProcessStackInfo[slot].sp_top)) { - return 0U; // SP out of range - } - ProcessStackInfo[slot].sp = sp; - - // Default process stack pointer and stack limit - __set_PSPLIM((uint32_t)ProcessStackMemory); - __set_PSP ((uint32_t)ProcessStackMemory); - - return 1U; // Success -} diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.c b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.c deleted file mode 100644 index e4871014..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2013-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * - * $Revision: V5.1.0 - * - * Project: CMSIS-RTOS RTX - * Title: RTX Configuration - * - * ----------------------------------------------------------------------------- - */ - -#include "cmsis_compiler.h" -#include "rtx_os.h" - -// OS Idle Thread -__WEAK __NO_RETURN void osRtxIdleThread (void *argument) { - (void)argument; - - for (;;) {} -} - -// OS Error Callback function -__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) { - (void)object_id; - - switch (code) { - case osRtxErrorStackUnderflow: - // Stack overflow detected for thread (thread_id=object_id) - break; - case osRtxErrorISRQueueOverflow: - // ISR Queue overflow detected when inserting object (object_id) - break; - case osRtxErrorTimerQueueOverflow: - // User Timer Callback Queue overflow detected for timer (timer_id=object_id) - break; - case osRtxErrorClibSpace: - // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM - break; - case osRtxErrorClibMutex: - // Standard C/C++ library mutex initialization failed - break; - default: - // Reserved - break; - } - for (;;) {} -//return 0U; -} diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.h b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.h deleted file mode 100644 index 3021efbc..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/CMSIS/RTX_Config.h +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (c) 2013-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * - * $Revision: V5.5.0 - * - * Project: CMSIS-RTOS RTX - * Title: RTX Configuration definitions - * - * ----------------------------------------------------------------------------- - */ - -#ifndef RTX_CONFIG_H_ -#define RTX_CONFIG_H_ - -#ifdef _RTE_ -#include "RTE_Components.h" -#ifdef RTE_RTX_CONFIG_H -#include RTE_RTX_CONFIG_H -#endif -#endif - -//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- - -// System Configuration -// ======================= - -// Global Dynamic Memory size [bytes] <0-1073741824:8> -// Defines the combined global dynamic memory size. -// Default: 4096 -#ifndef OS_DYNAMIC_MEM_SIZE -#define OS_DYNAMIC_MEM_SIZE 4096 -#endif - -// Kernel Tick Frequency [Hz] <1-1000000> -// Defines base time unit for delays and timeouts. -// Default: 1000 (1ms tick) -#ifndef OS_TICK_FREQ -#define OS_TICK_FREQ 1000 -#endif - -// Round-Robin Thread switching -// Enables Round-Robin Thread switching. -#ifndef OS_ROBIN_ENABLE -#define OS_ROBIN_ENABLE 1 -#endif - -// Round-Robin Timeout <1-1000> -// Defines how many ticks a thread will execute before a thread switch. -// Default: 5 -#ifndef OS_ROBIN_TIMEOUT -#define OS_ROBIN_TIMEOUT 5 -#endif - -// - -// ISR FIFO Queue -// <4=> 4 entries <8=> 8 entries <12=> 12 entries <16=> 16 entries -// <24=> 24 entries <32=> 32 entries <48=> 48 entries <64=> 64 entries -// <96=> 96 entries <128=> 128 entries <196=> 196 entries <256=> 256 entries -// RTOS Functions called from ISR store requests to this buffer. -// Default: 16 entries -#ifndef OS_ISR_FIFO_QUEUE -#define OS_ISR_FIFO_QUEUE 16 -#endif - -// Object Memory usage counters -// Enables object memory usage counters (requires RTX source variant). -#ifndef OS_OBJ_MEM_USAGE -#define OS_OBJ_MEM_USAGE 0 -#endif - -// - -// Thread Configuration -// ======================= - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_THREAD_OBJ_MEM -#define OS_THREAD_OBJ_MEM 0 -#endif - -// Number of user Threads <1-1000> -// Defines maximum number of user threads that can be active at the same time. -// Applies to user threads with system provided memory for control blocks. -#ifndef OS_THREAD_NUM -#define OS_THREAD_NUM 1 -#endif - -// Number of user Threads with default Stack size <0-1000> -// Defines maximum number of user threads with default stack size. -// Applies to user threads with zero stack size specified. -#ifndef OS_THREAD_DEF_STACK_NUM -#define OS_THREAD_DEF_STACK_NUM 0 -#endif - -// Total Stack size [bytes] for user Threads with user-provided Stack size <0-1073741824:8> -// Defines the combined stack size for user threads with user-provided stack size. -// Applies to user threads with user-provided stack size and system provided memory for stack. -// Default: 0 -#ifndef OS_THREAD_USER_STACK_SIZE -#define OS_THREAD_USER_STACK_SIZE 0 -#endif - -// - -// Default Thread Stack size [bytes] <96-1073741824:8> -// Defines stack size for threads with zero stack size specified. -// Default: 256 -#ifndef OS_STACK_SIZE -#define OS_STACK_SIZE 256 -#endif - -// Idle Thread Stack size [bytes] <72-1073741824:8> -// Defines stack size for Idle thread. -// Default: 256 -#ifndef OS_IDLE_THREAD_STACK_SIZE -#define OS_IDLE_THREAD_STACK_SIZE 256 -#endif - -// Idle Thread TrustZone Module Identifier -// Defines TrustZone Thread Context Management Identifier. -// Applies only to cores with TrustZone technology. -// Default: 0 (not used) -#ifndef OS_IDLE_THREAD_TZ_MOD_ID -#define OS_IDLE_THREAD_TZ_MOD_ID 0 -#endif - -// Stack overrun checking -// Enables stack overrun check at thread switch. -// Enabling this option increases slightly the execution time of a thread switch. -#ifndef OS_STACK_CHECK -#define OS_STACK_CHECK 1 -#endif - -// Stack usage watermark -// Initializes thread stack with watermark pattern for analyzing stack usage. -// Enabling this option increases significantly the execution time of thread creation. -#ifndef OS_STACK_WATERMARK -#define OS_STACK_WATERMARK 0 -#endif - -// Processor mode for Thread execution -// <0=> Unprivileged mode -// <1=> Privileged mode -// Default: Privileged mode -#ifndef OS_PRIVILEGE_MODE -#define OS_PRIVILEGE_MODE 1 -#endif - -// - -// Timer Configuration -// ====================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_TIMER_OBJ_MEM -#define OS_TIMER_OBJ_MEM 0 -#endif - -// Number of Timer objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_TIMER_NUM -#define OS_TIMER_NUM 1 -#endif - -// - -// Timer Thread Priority -// <8=> Low -// <16=> Below Normal <24=> Normal <32=> Above Normal -// <40=> High -// <48=> Realtime -// Defines priority for timer thread -// Default: High -#ifndef OS_TIMER_THREAD_PRIO -#define OS_TIMER_THREAD_PRIO 40 -#endif - -// Timer Thread Stack size [bytes] <0-1073741824:8> -// Defines stack size for Timer thread. -// May be set to 0 when timers are not used. -// Default: 256 -#ifndef OS_TIMER_THREAD_STACK_SIZE -#define OS_TIMER_THREAD_STACK_SIZE 256 -#endif - -// Timer Thread TrustZone Module Identifier -// Defines TrustZone Thread Context Management Identifier. -// Applies only to cores with TrustZone technology. -// Default: 0 (not used) -#ifndef OS_TIMER_THREAD_TZ_MOD_ID -#define OS_TIMER_THREAD_TZ_MOD_ID 0 -#endif - -// Timer Callback Queue entries <0-256> -// Number of concurrent active timer callback functions. -// May be set to 0 when timers are not used. -// Default: 4 -#ifndef OS_TIMER_CB_QUEUE -#define OS_TIMER_CB_QUEUE 4 -#endif - -// - -// Event Flags Configuration -// ============================ - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_EVFLAGS_OBJ_MEM -#define OS_EVFLAGS_OBJ_MEM 0 -#endif - -// Number of Event Flags objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_EVFLAGS_NUM -#define OS_EVFLAGS_NUM 1 -#endif - -// - -// - -// Mutex Configuration -// ====================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_MUTEX_OBJ_MEM -#define OS_MUTEX_OBJ_MEM 0 -#endif - -// Number of Mutex objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_MUTEX_NUM -#define OS_MUTEX_NUM 1 -#endif - -// - -// - -// Semaphore Configuration -// ========================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_SEMAPHORE_OBJ_MEM -#define OS_SEMAPHORE_OBJ_MEM 0 -#endif - -// Number of Semaphore objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_SEMAPHORE_NUM -#define OS_SEMAPHORE_NUM 1 -#endif - -// - -// - -// Memory Pool Configuration -// ============================ - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_MEMPOOL_OBJ_MEM -#define OS_MEMPOOL_OBJ_MEM 0 -#endif - -// Number of Memory Pool objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_MEMPOOL_NUM -#define OS_MEMPOOL_NUM 1 -#endif - -// Data Storage Memory size [bytes] <0-1073741824:8> -// Defines the combined data storage memory size. -// Applies to objects with system provided memory for data storage. -// Default: 0 -#ifndef OS_MEMPOOL_DATA_SIZE -#define OS_MEMPOOL_DATA_SIZE 0 -#endif - -// - -// - -// Message Queue Configuration -// ============================== - -// Object specific Memory allocation -// Enables object specific memory allocation. -#ifndef OS_MSGQUEUE_OBJ_MEM -#define OS_MSGQUEUE_OBJ_MEM 0 -#endif - -// Number of Message Queue objects <1-1000> -// Defines maximum number of objects that can be active at the same time. -// Applies to objects with system provided memory for control blocks. -#ifndef OS_MSGQUEUE_NUM -#define OS_MSGQUEUE_NUM 1 -#endif - -// Data Storage Memory size [bytes] <0-1073741824:8> -// Defines the combined data storage memory size. -// Applies to objects with system provided memory for data storage. -// Default: 0 -#ifndef OS_MSGQUEUE_DATA_SIZE -#define OS_MSGQUEUE_DATA_SIZE 0 -#endif - -// - -// - -// Event Recorder Configuration -// =============================== - -// Global Initialization -// Initialize Event Recorder during 'osKernelInitialize'. -#ifndef OS_EVR_INIT -#define OS_EVR_INIT 0 -#endif - -// Start recording -// Start event recording after initialization. -#ifndef OS_EVR_START -#define OS_EVR_START 1 -#endif - -// Global Event Filter Setup -// Initial recording level applied to all components. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_LEVEL -#define OS_EVR_LEVEL 0x00U -#endif - -// RTOS Event Filter Setup -// Recording levels for RTX components. -// Only applicable if events for the respective component are generated. - -// Memory Management -// Recording level for Memory Management events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MEMORY_LEVEL -#define OS_EVR_MEMORY_LEVEL 0x01U -#endif - -// Kernel -// Recording level for Kernel events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_KERNEL_LEVEL -#define OS_EVR_KERNEL_LEVEL 0x01U -#endif - -// Thread -// Recording level for Thread events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_THREAD_LEVEL -#define OS_EVR_THREAD_LEVEL 0x05U -#endif - -// Generic Wait -// Recording level for Generic Wait events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_WAIT_LEVEL -#define OS_EVR_WAIT_LEVEL 0x01U -#endif - -// Thread Flags -// Recording level for Thread Flags events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_THFLAGS_LEVEL -#define OS_EVR_THFLAGS_LEVEL 0x01U -#endif - -// Event Flags -// Recording level for Event Flags events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_EVFLAGS_LEVEL -#define OS_EVR_EVFLAGS_LEVEL 0x01U -#endif - -// Timer -// Recording level for Timer events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_TIMER_LEVEL -#define OS_EVR_TIMER_LEVEL 0x01U -#endif - -// Mutex -// Recording level for Mutex events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MUTEX_LEVEL -#define OS_EVR_MUTEX_LEVEL 0x01U -#endif - -// Semaphore -// Recording level for Semaphore events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_SEMAPHORE_LEVEL -#define OS_EVR_SEMAPHORE_LEVEL 0x01U -#endif - -// Memory Pool -// Recording level for Memory Pool events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MEMPOOL_LEVEL -#define OS_EVR_MEMPOOL_LEVEL 0x01U -#endif - -// Message Queue -// Recording level for Message Queue events. -// Error events -// API function call events -// Operation events -// Detailed operation events -// -#ifndef OS_EVR_MSGQUEUE_LEVEL -#define OS_EVR_MSGQUEUE_LEVEL 0x01U -#endif - -// - -// - -// RTOS Event Generation -// Enables event generation for RTX components (requires RTX source variant). - -// Memory Management -// Enables Memory Management event generation. -#ifndef OS_EVR_MEMORY -#define OS_EVR_MEMORY 1 -#endif - -// Kernel -// Enables Kernel event generation. -#ifndef OS_EVR_KERNEL -#define OS_EVR_KERNEL 1 -#endif - -// Thread -// Enables Thread event generation. -#ifndef OS_EVR_THREAD -#define OS_EVR_THREAD 1 -#endif - -// Generic Wait -// Enables Generic Wait event generation. -#ifndef OS_EVR_WAIT -#define OS_EVR_WAIT 1 -#endif - -// Thread Flags -// Enables Thread Flags event generation. -#ifndef OS_EVR_THFLAGS -#define OS_EVR_THFLAGS 1 -#endif - -// Event Flags -// Enables Event Flags event generation. -#ifndef OS_EVR_EVFLAGS -#define OS_EVR_EVFLAGS 1 -#endif - -// Timer -// Enables Timer event generation. -#ifndef OS_EVR_TIMER -#define OS_EVR_TIMER 1 -#endif - -// Mutex -// Enables Mutex event generation. -#ifndef OS_EVR_MUTEX -#define OS_EVR_MUTEX 1 -#endif - -// Semaphore -// Enables Semaphore event generation. -#ifndef OS_EVR_SEMAPHORE -#define OS_EVR_SEMAPHORE 1 -#endif - -// Memory Pool -// Enables Memory Pool event generation. -#ifndef OS_EVR_MEMPOOL -#define OS_EVR_MEMPOOL 1 -#endif - -// Message Queue -// Enables Message Queue event generation. -#ifndef OS_EVR_MSGQUEUE -#define OS_EVR_MSGQUEUE 1 -#endif - -// - -// - -// Number of Threads which use standard C/C++ library libspace -// (when thread specific memory allocation is not used). -#if (OS_THREAD_OBJ_MEM == 0) -#define OS_THREAD_LIBSPACE_NUM 4 -#else -#define OS_THREAD_LIBSPACE_NUM OS_THREAD_NUM -#endif - -//------------- <<< end of configuration section >>> --------------------------- - -#endif // RTX_CONFIG_H_ diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct deleted file mode 100644 index 3480c921..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct +++ /dev/null @@ -1,74 +0,0 @@ -#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m33 -xc -; command above MUST be in first line (no comment above!) - -/* -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------- -*/ - -/*--------------------- Flash Configuration ---------------------------------- -; Flash Configuration -; Flash Base Address <0x0-0xFFFFFFFF:8> -; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __ROM_BASE 0x00200000 -#define __ROM_SIZE 0x00200000 - -/*--------------------- Embedded RAM Configuration --------------------------- -; RAM Configuration -; RAM Base Address <0x0-0xFFFFFFFF:8> -; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __RAM_BASE 0x20200000 -#define __RAM_SIZE 0x00020000 - -/*--------------------- Stack / Heap Configuration --------------------------- -; Stack / Heap Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - *----------------------------------------------------------------------------*/ -#define __STACK_SIZE 0x00000400 -#define __HEAP_SIZE 0x00000C00 - - -/*---------------------------------------------------------------------------- - User Stack & Heap boundery definition - *----------------------------------------------------------------------------*/ -#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ -#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ - - -/*---------------------------------------------------------------------------- - Scatter File Definitions definition - *----------------------------------------------------------------------------*/ -#define __RO_BASE __ROM_BASE -#define __RO_SIZE __ROM_SIZE - -#define __RW_BASE (__RAM_BASE ) -#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) - - - -LR_ROM __RO_BASE __RO_SIZE { ; load region size_region - ER_ROM __RO_BASE __RO_SIZE { ; load address = execution address - *.o (RESET, +First) - *(InRoot$$Sections) -; *(Veneer$$CMSE) ; uncomment for secure applications - .ANY (+RO) - .ANY (+XO) - } - - RW_RAM __RW_BASE __RW_SIZE { ; RW data - .ANY (+RW +ZI) - } - -#if __HEAP_SIZE > 0 - ARM_LIB_HEAP __HEAP_BASE EMPTY __HEAP_SIZE { ; Reserve empty region for heap - } -#endif - - ARM_LIB_STACK __STACK_TOP EMPTY -__STACK_SIZE { ; Reserve empty region for stack - } -} diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/partition_ARMCM33.h b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/partition_ARMCM33.h deleted file mode 100644 index a7cb0d73..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/partition_ARMCM33.h +++ /dev/null @@ -1,1260 +0,0 @@ -/**************************************************************************//** - * @file partition_ARMCM33.h - * @brief CMSIS-CORE Initial Setup for Secure / Non-Secure Zones for ARMCM33 - * @version V1.1.1 - * @date 12. March 2019 - ******************************************************************************/ -/* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PARTITION_ARMCM33_H -#define PARTITION_ARMCM33_H - -/* -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -*/ - -/* -// Initialize Security Attribution Unit (SAU) CTRL register -*/ -#define SAU_INIT_CTRL 1 - -/* -// Enable SAU -// Value for SAU->CTRL register bit ENABLE -*/ -#define SAU_INIT_CTRL_ENABLE 1 - -/* -// When SAU is disabled -// <0=> All Memory is Secure -// <1=> All Memory is Non-Secure -// Value for SAU->CTRL register bit ALLNS -// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. -*/ -#define SAU_INIT_CTRL_ALLNS 0 - -/* -// -*/ - -/* -// Initialize Security Attribution Unit (SAU) Address Regions -// SAU configuration specifies regions to be one of: -// - Secure and Non-Secure Callable -// - Non-Secure -// Note: All memory regions not configured by SAU are Secure -*/ -#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ - -/* -// Initialize SAU Region 0 -// Setup SAU Region 0 memory attributes -*/ -#define SAU_INIT_REGION0 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START0 0x00000000 /* start address of SAU region 0 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END0 0x001FFFFF /* end address of SAU region 0 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC0 1 -/* -// -*/ - -/* -// Initialize SAU Region 1 -// Setup SAU Region 1 memory attributes -*/ -#define SAU_INIT_REGION1 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START1 0x00200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END1 0x003FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC1 0 -/* -// -*/ - -/* -// Initialize SAU Region 2 -// Setup SAU Region 2 memory attributes -*/ -#define SAU_INIT_REGION2 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START2 0x20200000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END2 0x203FFFFF - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC2 0 -/* -// -*/ - -/* -// Initialize SAU Region 3 -// Setup SAU Region 3 memory attributes -*/ -#define SAU_INIT_REGION3 1 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START3 0x40000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END3 0x40040000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC3 0 -/* -// -*/ - -/* -// Initialize SAU Region 4 -// Setup SAU Region 4 memory attributes -*/ -#define SAU_INIT_REGION4 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START4 0x00000000 /* start address of SAU region 4 */ - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END4 0x00000000 /* end address of SAU region 4 */ - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC4 0 -/* -// -*/ - -/* -// Initialize SAU Region 5 -// Setup SAU Region 5 memory attributes -*/ -#define SAU_INIT_REGION5 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START5 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END5 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC5 0 -/* -// -*/ - -/* -// Initialize SAU Region 6 -// Setup SAU Region 6 memory attributes -*/ -#define SAU_INIT_REGION6 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START6 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END6 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC6 0 -/* -// -*/ - -/* -// Initialize SAU Region 7 -// Setup SAU Region 7 memory attributes -*/ -#define SAU_INIT_REGION7 0 - -/* -// Start Address <0-0xFFFFFFE0> -*/ -#define SAU_INIT_START7 0x00000000 - -/* -// End Address <0x1F-0xFFFFFFFF> -*/ -#define SAU_INIT_END7 0x00000000 - -/* -// Region is -// <0=>Non-Secure -// <1=>Secure, Non-Secure Callable -*/ -#define SAU_INIT_NSC7 0 -/* -// -*/ - -/* -// -*/ - -/* -// Setup behaviour of Sleep and Exception Handling -*/ -#define SCB_CSR_AIRCR_INIT 1 - -/* -// Deep Sleep can be enabled by -// <0=>Secure and Non-Secure state -// <1=>Secure state only -// Value for SCB->CSR register bit DEEPSLEEPS -*/ -#define SCB_CSR_DEEPSLEEPS_VAL 1 - -/* -// System reset request accessible from -// <0=> Secure and Non-Secure state -// <1=> Secure state only -// Value for SCB->AIRCR register bit SYSRESETREQS -*/ -#define SCB_AIRCR_SYSRESETREQS_VAL 1 - -/* -// Priority of Non-Secure exceptions is -// <0=> Not altered -// <1=> Lowered to 0x80-0xFF -// Value for SCB->AIRCR register bit PRIS -*/ -#define SCB_AIRCR_PRIS_VAL 1 - -/* -// BusFault, HardFault, and NMI target -// <0=> Secure state -// <1=> Non-Secure state -// Value for SCB->AIRCR register bit BFHFNMINS -*/ -#define SCB_AIRCR_BFHFNMINS_VAL 0 - -/* -// -*/ - -/* -// Setup behaviour of Floating Point Unit -*/ -#define TZ_FPU_NS_USAGE 1 - -/* -// Floating Point Unit usage -// <0=> Secure state only -// <3=> Secure and Non-Secure state -// Value for SCB->NSACR register bits CP10, CP11 -*/ -#define SCB_NSACR_CP10_11_VAL 3 - -/* -// Treat floating-point registers as Secure -// <0=> Disabled -// <1=> Enabled -// Value for FPU->FPCCR register bit TS -*/ -#define FPU_FPCCR_TS_VAL 0 - -/* -// Clear on return (CLRONRET) accessibility -// <0=> Secure and Non-Secure state -// <1=> Secure state only -// Value for FPU->FPCCR register bit CLRONRETS -*/ -#define FPU_FPCCR_CLRONRETS_VAL 0 - -/* -// Clear floating-point caller saved registers on exception return -// <0=> Disabled -// <1=> Enabled -// Value for FPU->FPCCR register bit CLRONRET -*/ -#define FPU_FPCCR_CLRONRET_VAL 1 - -/* -// -*/ - -/* -// Setup Interrupt Target -*/ - -/* -// Initialize ITNS 0 (Interrupts 0..31) -*/ -#define NVIC_INIT_ITNS0 1 - -/* -// Interrupts 0..31 -// Interrupt 0 <0=> Secure state <1=> Non-Secure state -// Interrupt 1 <0=> Secure state <1=> Non-Secure state -// Interrupt 2 <0=> Secure state <1=> Non-Secure state -// Interrupt 3 <0=> Secure state <1=> Non-Secure state -// Interrupt 4 <0=> Secure state <1=> Non-Secure state -// Interrupt 5 <0=> Secure state <1=> Non-Secure state -// Interrupt 6 <0=> Secure state <1=> Non-Secure state -// Interrupt 7 <0=> Secure state <1=> Non-Secure state -// Interrupt 8 <0=> Secure state <1=> Non-Secure state -// Interrupt 9 <0=> Secure state <1=> Non-Secure state -// Interrupt 10 <0=> Secure state <1=> Non-Secure state -// Interrupt 11 <0=> Secure state <1=> Non-Secure state -// Interrupt 12 <0=> Secure state <1=> Non-Secure state -// Interrupt 13 <0=> Secure state <1=> Non-Secure state -// Interrupt 14 <0=> Secure state <1=> Non-Secure state -// Interrupt 15 <0=> Secure state <1=> Non-Secure state -// Interrupt 16 <0=> Secure state <1=> Non-Secure state -// Interrupt 17 <0=> Secure state <1=> Non-Secure state -// Interrupt 18 <0=> Secure state <1=> Non-Secure state -// Interrupt 19 <0=> Secure state <1=> Non-Secure state -// Interrupt 20 <0=> Secure state <1=> Non-Secure state -// Interrupt 21 <0=> Secure state <1=> Non-Secure state -// Interrupt 22 <0=> Secure state <1=> Non-Secure state -// Interrupt 23 <0=> Secure state <1=> Non-Secure state -// Interrupt 24 <0=> Secure state <1=> Non-Secure state -// Interrupt 25 <0=> Secure state <1=> Non-Secure state -// Interrupt 26 <0=> Secure state <1=> Non-Secure state -// Interrupt 27 <0=> Secure state <1=> Non-Secure state -// Interrupt 28 <0=> Secure state <1=> Non-Secure state -// Interrupt 29 <0=> Secure state <1=> Non-Secure state -// Interrupt 30 <0=> Secure state <1=> Non-Secure state -// Interrupt 31 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS0_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 1 (Interrupts 32..63) -*/ -#define NVIC_INIT_ITNS1 1 - -/* -// Interrupts 32..63 -// Interrupt 32 <0=> Secure state <1=> Non-Secure state -// Interrupt 33 <0=> Secure state <1=> Non-Secure state -// Interrupt 34 <0=> Secure state <1=> Non-Secure state -// Interrupt 35 <0=> Secure state <1=> Non-Secure state -// Interrupt 36 <0=> Secure state <1=> Non-Secure state -// Interrupt 37 <0=> Secure state <1=> Non-Secure state -// Interrupt 38 <0=> Secure state <1=> Non-Secure state -// Interrupt 39 <0=> Secure state <1=> Non-Secure state -// Interrupt 40 <0=> Secure state <1=> Non-Secure state -// Interrupt 41 <0=> Secure state <1=> Non-Secure state -// Interrupt 42 <0=> Secure state <1=> Non-Secure state -// Interrupt 43 <0=> Secure state <1=> Non-Secure state -// Interrupt 44 <0=> Secure state <1=> Non-Secure state -// Interrupt 45 <0=> Secure state <1=> Non-Secure state -// Interrupt 46 <0=> Secure state <1=> Non-Secure state -// Interrupt 47 <0=> Secure state <1=> Non-Secure state -// Interrupt 48 <0=> Secure state <1=> Non-Secure state -// Interrupt 49 <0=> Secure state <1=> Non-Secure state -// Interrupt 50 <0=> Secure state <1=> Non-Secure state -// Interrupt 51 <0=> Secure state <1=> Non-Secure state -// Interrupt 52 <0=> Secure state <1=> Non-Secure state -// Interrupt 53 <0=> Secure state <1=> Non-Secure state -// Interrupt 54 <0=> Secure state <1=> Non-Secure state -// Interrupt 55 <0=> Secure state <1=> Non-Secure state -// Interrupt 56 <0=> Secure state <1=> Non-Secure state -// Interrupt 57 <0=> Secure state <1=> Non-Secure state -// Interrupt 58 <0=> Secure state <1=> Non-Secure state -// Interrupt 59 <0=> Secure state <1=> Non-Secure state -// Interrupt 60 <0=> Secure state <1=> Non-Secure state -// Interrupt 61 <0=> Secure state <1=> Non-Secure state -// Interrupt 62 <0=> Secure state <1=> Non-Secure state -// Interrupt 63 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS1_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 2 (Interrupts 64..95) -*/ -#define NVIC_INIT_ITNS2 0 - -/* -// Interrupts 64..95 -// Interrupt 64 <0=> Secure state <1=> Non-Secure state -// Interrupt 65 <0=> Secure state <1=> Non-Secure state -// Interrupt 66 <0=> Secure state <1=> Non-Secure state -// Interrupt 67 <0=> Secure state <1=> Non-Secure state -// Interrupt 68 <0=> Secure state <1=> Non-Secure state -// Interrupt 69 <0=> Secure state <1=> Non-Secure state -// Interrupt 70 <0=> Secure state <1=> Non-Secure state -// Interrupt 71 <0=> Secure state <1=> Non-Secure state -// Interrupt 72 <0=> Secure state <1=> Non-Secure state -// Interrupt 73 <0=> Secure state <1=> Non-Secure state -// Interrupt 74 <0=> Secure state <1=> Non-Secure state -// Interrupt 75 <0=> Secure state <1=> Non-Secure state -// Interrupt 76 <0=> Secure state <1=> Non-Secure state -// Interrupt 77 <0=> Secure state <1=> Non-Secure state -// Interrupt 78 <0=> Secure state <1=> Non-Secure state -// Interrupt 79 <0=> Secure state <1=> Non-Secure state -// Interrupt 80 <0=> Secure state <1=> Non-Secure state -// Interrupt 81 <0=> Secure state <1=> Non-Secure state -// Interrupt 82 <0=> Secure state <1=> Non-Secure state -// Interrupt 83 <0=> Secure state <1=> Non-Secure state -// Interrupt 84 <0=> Secure state <1=> Non-Secure state -// Interrupt 85 <0=> Secure state <1=> Non-Secure state -// Interrupt 86 <0=> Secure state <1=> Non-Secure state -// Interrupt 87 <0=> Secure state <1=> Non-Secure state -// Interrupt 88 <0=> Secure state <1=> Non-Secure state -// Interrupt 89 <0=> Secure state <1=> Non-Secure state -// Interrupt 90 <0=> Secure state <1=> Non-Secure state -// Interrupt 91 <0=> Secure state <1=> Non-Secure state -// Interrupt 92 <0=> Secure state <1=> Non-Secure state -// Interrupt 93 <0=> Secure state <1=> Non-Secure state -// Interrupt 94 <0=> Secure state <1=> Non-Secure state -// Interrupt 95 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS2_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 3 (Interrupts 96..127) -*/ -#define NVIC_INIT_ITNS3 0 - -/* -// Interrupts 96..127 -// Interrupt 96 <0=> Secure state <1=> Non-Secure state -// Interrupt 97 <0=> Secure state <1=> Non-Secure state -// Interrupt 98 <0=> Secure state <1=> Non-Secure state -// Interrupt 99 <0=> Secure state <1=> Non-Secure state -// Interrupt 100 <0=> Secure state <1=> Non-Secure state -// Interrupt 101 <0=> Secure state <1=> Non-Secure state -// Interrupt 102 <0=> Secure state <1=> Non-Secure state -// Interrupt 103 <0=> Secure state <1=> Non-Secure state -// Interrupt 104 <0=> Secure state <1=> Non-Secure state -// Interrupt 105 <0=> Secure state <1=> Non-Secure state -// Interrupt 106 <0=> Secure state <1=> Non-Secure state -// Interrupt 107 <0=> Secure state <1=> Non-Secure state -// Interrupt 108 <0=> Secure state <1=> Non-Secure state -// Interrupt 109 <0=> Secure state <1=> Non-Secure state -// Interrupt 110 <0=> Secure state <1=> Non-Secure state -// Interrupt 111 <0=> Secure state <1=> Non-Secure state -// Interrupt 112 <0=> Secure state <1=> Non-Secure state -// Interrupt 113 <0=> Secure state <1=> Non-Secure state -// Interrupt 114 <0=> Secure state <1=> Non-Secure state -// Interrupt 115 <0=> Secure state <1=> Non-Secure state -// Interrupt 116 <0=> Secure state <1=> Non-Secure state -// Interrupt 117 <0=> Secure state <1=> Non-Secure state -// Interrupt 118 <0=> Secure state <1=> Non-Secure state -// Interrupt 119 <0=> Secure state <1=> Non-Secure state -// Interrupt 120 <0=> Secure state <1=> Non-Secure state -// Interrupt 121 <0=> Secure state <1=> Non-Secure state -// Interrupt 122 <0=> Secure state <1=> Non-Secure state -// Interrupt 123 <0=> Secure state <1=> Non-Secure state -// Interrupt 124 <0=> Secure state <1=> Non-Secure state -// Interrupt 125 <0=> Secure state <1=> Non-Secure state -// Interrupt 126 <0=> Secure state <1=> Non-Secure state -// Interrupt 127 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS3_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 4 (Interrupts 128..159) -*/ -#define NVIC_INIT_ITNS4 0 - -/* -// Interrupts 128..159 -// Interrupt 128 <0=> Secure state <1=> Non-Secure state -// Interrupt 129 <0=> Secure state <1=> Non-Secure state -// Interrupt 130 <0=> Secure state <1=> Non-Secure state -// Interrupt 131 <0=> Secure state <1=> Non-Secure state -// Interrupt 132 <0=> Secure state <1=> Non-Secure state -// Interrupt 133 <0=> Secure state <1=> Non-Secure state -// Interrupt 134 <0=> Secure state <1=> Non-Secure state -// Interrupt 135 <0=> Secure state <1=> Non-Secure state -// Interrupt 136 <0=> Secure state <1=> Non-Secure state -// Interrupt 137 <0=> Secure state <1=> Non-Secure state -// Interrupt 138 <0=> Secure state <1=> Non-Secure state -// Interrupt 139 <0=> Secure state <1=> Non-Secure state -// Interrupt 140 <0=> Secure state <1=> Non-Secure state -// Interrupt 141 <0=> Secure state <1=> Non-Secure state -// Interrupt 142 <0=> Secure state <1=> Non-Secure state -// Interrupt 143 <0=> Secure state <1=> Non-Secure state -// Interrupt 144 <0=> Secure state <1=> Non-Secure state -// Interrupt 145 <0=> Secure state <1=> Non-Secure state -// Interrupt 146 <0=> Secure state <1=> Non-Secure state -// Interrupt 147 <0=> Secure state <1=> Non-Secure state -// Interrupt 148 <0=> Secure state <1=> Non-Secure state -// Interrupt 149 <0=> Secure state <1=> Non-Secure state -// Interrupt 150 <0=> Secure state <1=> Non-Secure state -// Interrupt 151 <0=> Secure state <1=> Non-Secure state -// Interrupt 152 <0=> Secure state <1=> Non-Secure state -// Interrupt 153 <0=> Secure state <1=> Non-Secure state -// Interrupt 154 <0=> Secure state <1=> Non-Secure state -// Interrupt 155 <0=> Secure state <1=> Non-Secure state -// Interrupt 156 <0=> Secure state <1=> Non-Secure state -// Interrupt 157 <0=> Secure state <1=> Non-Secure state -// Interrupt 158 <0=> Secure state <1=> Non-Secure state -// Interrupt 159 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS4_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 5 (Interrupts 160..191) -*/ -#define NVIC_INIT_ITNS5 0 - -/* -// Interrupts 160..191 -// Interrupt 160 <0=> Secure state <1=> Non-Secure state -// Interrupt 161 <0=> Secure state <1=> Non-Secure state -// Interrupt 162 <0=> Secure state <1=> Non-Secure state -// Interrupt 163 <0=> Secure state <1=> Non-Secure state -// Interrupt 164 <0=> Secure state <1=> Non-Secure state -// Interrupt 165 <0=> Secure state <1=> Non-Secure state -// Interrupt 166 <0=> Secure state <1=> Non-Secure state -// Interrupt 167 <0=> Secure state <1=> Non-Secure state -// Interrupt 168 <0=> Secure state <1=> Non-Secure state -// Interrupt 169 <0=> Secure state <1=> Non-Secure state -// Interrupt 170 <0=> Secure state <1=> Non-Secure state -// Interrupt 171 <0=> Secure state <1=> Non-Secure state -// Interrupt 172 <0=> Secure state <1=> Non-Secure state -// Interrupt 173 <0=> Secure state <1=> Non-Secure state -// Interrupt 174 <0=> Secure state <1=> Non-Secure state -// Interrupt 175 <0=> Secure state <1=> Non-Secure state -// Interrupt 176 <0=> Secure state <1=> Non-Secure state -// Interrupt 177 <0=> Secure state <1=> Non-Secure state -// Interrupt 178 <0=> Secure state <1=> Non-Secure state -// Interrupt 179 <0=> Secure state <1=> Non-Secure state -// Interrupt 180 <0=> Secure state <1=> Non-Secure state -// Interrupt 181 <0=> Secure state <1=> Non-Secure state -// Interrupt 182 <0=> Secure state <1=> Non-Secure state -// Interrupt 183 <0=> Secure state <1=> Non-Secure state -// Interrupt 184 <0=> Secure state <1=> Non-Secure state -// Interrupt 185 <0=> Secure state <1=> Non-Secure state -// Interrupt 186 <0=> Secure state <1=> Non-Secure state -// Interrupt 187 <0=> Secure state <1=> Non-Secure state -// Interrupt 188 <0=> Secure state <1=> Non-Secure state -// Interrupt 189 <0=> Secure state <1=> Non-Secure state -// Interrupt 190 <0=> Secure state <1=> Non-Secure state -// Interrupt 191 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS5_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 6 (Interrupts 192..223) -*/ -#define NVIC_INIT_ITNS6 0 - -/* -// Interrupts 192..223 -// Interrupt 192 <0=> Secure state <1=> Non-Secure state -// Interrupt 193 <0=> Secure state <1=> Non-Secure state -// Interrupt 194 <0=> Secure state <1=> Non-Secure state -// Interrupt 195 <0=> Secure state <1=> Non-Secure state -// Interrupt 196 <0=> Secure state <1=> Non-Secure state -// Interrupt 197 <0=> Secure state <1=> Non-Secure state -// Interrupt 198 <0=> Secure state <1=> Non-Secure state -// Interrupt 199 <0=> Secure state <1=> Non-Secure state -// Interrupt 200 <0=> Secure state <1=> Non-Secure state -// Interrupt 201 <0=> Secure state <1=> Non-Secure state -// Interrupt 202 <0=> Secure state <1=> Non-Secure state -// Interrupt 203 <0=> Secure state <1=> Non-Secure state -// Interrupt 204 <0=> Secure state <1=> Non-Secure state -// Interrupt 205 <0=> Secure state <1=> Non-Secure state -// Interrupt 206 <0=> Secure state <1=> Non-Secure state -// Interrupt 207 <0=> Secure state <1=> Non-Secure state -// Interrupt 208 <0=> Secure state <1=> Non-Secure state -// Interrupt 209 <0=> Secure state <1=> Non-Secure state -// Interrupt 210 <0=> Secure state <1=> Non-Secure state -// Interrupt 211 <0=> Secure state <1=> Non-Secure state -// Interrupt 212 <0=> Secure state <1=> Non-Secure state -// Interrupt 213 <0=> Secure state <1=> Non-Secure state -// Interrupt 214 <0=> Secure state <1=> Non-Secure state -// Interrupt 215 <0=> Secure state <1=> Non-Secure state -// Interrupt 216 <0=> Secure state <1=> Non-Secure state -// Interrupt 217 <0=> Secure state <1=> Non-Secure state -// Interrupt 218 <0=> Secure state <1=> Non-Secure state -// Interrupt 219 <0=> Secure state <1=> Non-Secure state -// Interrupt 220 <0=> Secure state <1=> Non-Secure state -// Interrupt 221 <0=> Secure state <1=> Non-Secure state -// Interrupt 222 <0=> Secure state <1=> Non-Secure state -// Interrupt 223 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS6_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 7 (Interrupts 224..255) -*/ -#define NVIC_INIT_ITNS7 0 - -/* -// Interrupts 224..255 -// Interrupt 224 <0=> Secure state <1=> Non-Secure state -// Interrupt 225 <0=> Secure state <1=> Non-Secure state -// Interrupt 226 <0=> Secure state <1=> Non-Secure state -// Interrupt 227 <0=> Secure state <1=> Non-Secure state -// Interrupt 228 <0=> Secure state <1=> Non-Secure state -// Interrupt 229 <0=> Secure state <1=> Non-Secure state -// Interrupt 230 <0=> Secure state <1=> Non-Secure state -// Interrupt 231 <0=> Secure state <1=> Non-Secure state -// Interrupt 232 <0=> Secure state <1=> Non-Secure state -// Interrupt 233 <0=> Secure state <1=> Non-Secure state -// Interrupt 234 <0=> Secure state <1=> Non-Secure state -// Interrupt 235 <0=> Secure state <1=> Non-Secure state -// Interrupt 236 <0=> Secure state <1=> Non-Secure state -// Interrupt 237 <0=> Secure state <1=> Non-Secure state -// Interrupt 238 <0=> Secure state <1=> Non-Secure state -// Interrupt 239 <0=> Secure state <1=> Non-Secure state -// Interrupt 240 <0=> Secure state <1=> Non-Secure state -// Interrupt 241 <0=> Secure state <1=> Non-Secure state -// Interrupt 242 <0=> Secure state <1=> Non-Secure state -// Interrupt 243 <0=> Secure state <1=> Non-Secure state -// Interrupt 244 <0=> Secure state <1=> Non-Secure state -// Interrupt 245 <0=> Secure state <1=> Non-Secure state -// Interrupt 246 <0=> Secure state <1=> Non-Secure state -// Interrupt 247 <0=> Secure state <1=> Non-Secure state -// Interrupt 248 <0=> Secure state <1=> Non-Secure state -// Interrupt 249 <0=> Secure state <1=> Non-Secure state -// Interrupt 250 <0=> Secure state <1=> Non-Secure state -// Interrupt 251 <0=> Secure state <1=> Non-Secure state -// Interrupt 252 <0=> Secure state <1=> Non-Secure state -// Interrupt 253 <0=> Secure state <1=> Non-Secure state -// Interrupt 254 <0=> Secure state <1=> Non-Secure state -// Interrupt 255 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS7_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 8 (Interrupts 256..287) -*/ -#define NVIC_INIT_ITNS8 0 - -/* -// Interrupts 256..287 -// Interrupt 256 <0=> Secure state <1=> Non-Secure state -// Interrupt 257 <0=> Secure state <1=> Non-Secure state -// Interrupt 258 <0=> Secure state <1=> Non-Secure state -// Interrupt 259 <0=> Secure state <1=> Non-Secure state -// Interrupt 260 <0=> Secure state <1=> Non-Secure state -// Interrupt 261 <0=> Secure state <1=> Non-Secure state -// Interrupt 262 <0=> Secure state <1=> Non-Secure state -// Interrupt 263 <0=> Secure state <1=> Non-Secure state -// Interrupt 264 <0=> Secure state <1=> Non-Secure state -// Interrupt 265 <0=> Secure state <1=> Non-Secure state -// Interrupt 266 <0=> Secure state <1=> Non-Secure state -// Interrupt 267 <0=> Secure state <1=> Non-Secure state -// Interrupt 268 <0=> Secure state <1=> Non-Secure state -// Interrupt 269 <0=> Secure state <1=> Non-Secure state -// Interrupt 270 <0=> Secure state <1=> Non-Secure state -// Interrupt 271 <0=> Secure state <1=> Non-Secure state -// Interrupt 272 <0=> Secure state <1=> Non-Secure state -// Interrupt 273 <0=> Secure state <1=> Non-Secure state -// Interrupt 274 <0=> Secure state <1=> Non-Secure state -// Interrupt 275 <0=> Secure state <1=> Non-Secure state -// Interrupt 276 <0=> Secure state <1=> Non-Secure state -// Interrupt 277 <0=> Secure state <1=> Non-Secure state -// Interrupt 278 <0=> Secure state <1=> Non-Secure state -// Interrupt 279 <0=> Secure state <1=> Non-Secure state -// Interrupt 280 <0=> Secure state <1=> Non-Secure state -// Interrupt 281 <0=> Secure state <1=> Non-Secure state -// Interrupt 282 <0=> Secure state <1=> Non-Secure state -// Interrupt 283 <0=> Secure state <1=> Non-Secure state -// Interrupt 284 <0=> Secure state <1=> Non-Secure state -// Interrupt 285 <0=> Secure state <1=> Non-Secure state -// Interrupt 286 <0=> Secure state <1=> Non-Secure state -// Interrupt 287 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS8_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 9 (Interrupts 288..319) -*/ -#define NVIC_INIT_ITNS9 0 - -/* -// Interrupts 288..319 -// Interrupt 288 <0=> Secure state <1=> Non-Secure state -// Interrupt 289 <0=> Secure state <1=> Non-Secure state -// Interrupt 290 <0=> Secure state <1=> Non-Secure state -// Interrupt 291 <0=> Secure state <1=> Non-Secure state -// Interrupt 292 <0=> Secure state <1=> Non-Secure state -// Interrupt 293 <0=> Secure state <1=> Non-Secure state -// Interrupt 294 <0=> Secure state <1=> Non-Secure state -// Interrupt 295 <0=> Secure state <1=> Non-Secure state -// Interrupt 296 <0=> Secure state <1=> Non-Secure state -// Interrupt 297 <0=> Secure state <1=> Non-Secure state -// Interrupt 298 <0=> Secure state <1=> Non-Secure state -// Interrupt 299 <0=> Secure state <1=> Non-Secure state -// Interrupt 300 <0=> Secure state <1=> Non-Secure state -// Interrupt 301 <0=> Secure state <1=> Non-Secure state -// Interrupt 302 <0=> Secure state <1=> Non-Secure state -// Interrupt 303 <0=> Secure state <1=> Non-Secure state -// Interrupt 304 <0=> Secure state <1=> Non-Secure state -// Interrupt 305 <0=> Secure state <1=> Non-Secure state -// Interrupt 306 <0=> Secure state <1=> Non-Secure state -// Interrupt 307 <0=> Secure state <1=> Non-Secure state -// Interrupt 308 <0=> Secure state <1=> Non-Secure state -// Interrupt 309 <0=> Secure state <1=> Non-Secure state -// Interrupt 310 <0=> Secure state <1=> Non-Secure state -// Interrupt 311 <0=> Secure state <1=> Non-Secure state -// Interrupt 312 <0=> Secure state <1=> Non-Secure state -// Interrupt 313 <0=> Secure state <1=> Non-Secure state -// Interrupt 314 <0=> Secure state <1=> Non-Secure state -// Interrupt 315 <0=> Secure state <1=> Non-Secure state -// Interrupt 316 <0=> Secure state <1=> Non-Secure state -// Interrupt 317 <0=> Secure state <1=> Non-Secure state -// Interrupt 318 <0=> Secure state <1=> Non-Secure state -// Interrupt 319 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS9_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 10 (Interrupts 320..351) -*/ -#define NVIC_INIT_ITNS10 0 - -/* -// Interrupts 320..351 -// Interrupt 320 <0=> Secure state <1=> Non-Secure state -// Interrupt 321 <0=> Secure state <1=> Non-Secure state -// Interrupt 322 <0=> Secure state <1=> Non-Secure state -// Interrupt 323 <0=> Secure state <1=> Non-Secure state -// Interrupt 324 <0=> Secure state <1=> Non-Secure state -// Interrupt 325 <0=> Secure state <1=> Non-Secure state -// Interrupt 326 <0=> Secure state <1=> Non-Secure state -// Interrupt 327 <0=> Secure state <1=> Non-Secure state -// Interrupt 328 <0=> Secure state <1=> Non-Secure state -// Interrupt 329 <0=> Secure state <1=> Non-Secure state -// Interrupt 330 <0=> Secure state <1=> Non-Secure state -// Interrupt 331 <0=> Secure state <1=> Non-Secure state -// Interrupt 332 <0=> Secure state <1=> Non-Secure state -// Interrupt 333 <0=> Secure state <1=> Non-Secure state -// Interrupt 334 <0=> Secure state <1=> Non-Secure state -// Interrupt 335 <0=> Secure state <1=> Non-Secure state -// Interrupt 336 <0=> Secure state <1=> Non-Secure state -// Interrupt 337 <0=> Secure state <1=> Non-Secure state -// Interrupt 338 <0=> Secure state <1=> Non-Secure state -// Interrupt 339 <0=> Secure state <1=> Non-Secure state -// Interrupt 340 <0=> Secure state <1=> Non-Secure state -// Interrupt 341 <0=> Secure state <1=> Non-Secure state -// Interrupt 342 <0=> Secure state <1=> Non-Secure state -// Interrupt 343 <0=> Secure state <1=> Non-Secure state -// Interrupt 344 <0=> Secure state <1=> Non-Secure state -// Interrupt 345 <0=> Secure state <1=> Non-Secure state -// Interrupt 346 <0=> Secure state <1=> Non-Secure state -// Interrupt 347 <0=> Secure state <1=> Non-Secure state -// Interrupt 348 <0=> Secure state <1=> Non-Secure state -// Interrupt 349 <0=> Secure state <1=> Non-Secure state -// Interrupt 350 <0=> Secure state <1=> Non-Secure state -// Interrupt 351 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS10_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 11 (Interrupts 352..383) -*/ -#define NVIC_INIT_ITNS11 0 - -/* -// Interrupts 352..383 -// Interrupt 352 <0=> Secure state <1=> Non-Secure state -// Interrupt 353 <0=> Secure state <1=> Non-Secure state -// Interrupt 354 <0=> Secure state <1=> Non-Secure state -// Interrupt 355 <0=> Secure state <1=> Non-Secure state -// Interrupt 356 <0=> Secure state <1=> Non-Secure state -// Interrupt 357 <0=> Secure state <1=> Non-Secure state -// Interrupt 358 <0=> Secure state <1=> Non-Secure state -// Interrupt 359 <0=> Secure state <1=> Non-Secure state -// Interrupt 360 <0=> Secure state <1=> Non-Secure state -// Interrupt 361 <0=> Secure state <1=> Non-Secure state -// Interrupt 362 <0=> Secure state <1=> Non-Secure state -// Interrupt 363 <0=> Secure state <1=> Non-Secure state -// Interrupt 364 <0=> Secure state <1=> Non-Secure state -// Interrupt 365 <0=> Secure state <1=> Non-Secure state -// Interrupt 366 <0=> Secure state <1=> Non-Secure state -// Interrupt 367 <0=> Secure state <1=> Non-Secure state -// Interrupt 368 <0=> Secure state <1=> Non-Secure state -// Interrupt 369 <0=> Secure state <1=> Non-Secure state -// Interrupt 370 <0=> Secure state <1=> Non-Secure state -// Interrupt 371 <0=> Secure state <1=> Non-Secure state -// Interrupt 372 <0=> Secure state <1=> Non-Secure state -// Interrupt 373 <0=> Secure state <1=> Non-Secure state -// Interrupt 374 <0=> Secure state <1=> Non-Secure state -// Interrupt 375 <0=> Secure state <1=> Non-Secure state -// Interrupt 376 <0=> Secure state <1=> Non-Secure state -// Interrupt 377 <0=> Secure state <1=> Non-Secure state -// Interrupt 378 <0=> Secure state <1=> Non-Secure state -// Interrupt 379 <0=> Secure state <1=> Non-Secure state -// Interrupt 380 <0=> Secure state <1=> Non-Secure state -// Interrupt 381 <0=> Secure state <1=> Non-Secure state -// Interrupt 382 <0=> Secure state <1=> Non-Secure state -// Interrupt 383 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS11_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 12 (Interrupts 384..415) -*/ -#define NVIC_INIT_ITNS12 0 - -/* -// Interrupts 384..415 -// Interrupt 384 <0=> Secure state <1=> Non-Secure state -// Interrupt 385 <0=> Secure state <1=> Non-Secure state -// Interrupt 386 <0=> Secure state <1=> Non-Secure state -// Interrupt 387 <0=> Secure state <1=> Non-Secure state -// Interrupt 388 <0=> Secure state <1=> Non-Secure state -// Interrupt 389 <0=> Secure state <1=> Non-Secure state -// Interrupt 390 <0=> Secure state <1=> Non-Secure state -// Interrupt 391 <0=> Secure state <1=> Non-Secure state -// Interrupt 392 <0=> Secure state <1=> Non-Secure state -// Interrupt 393 <0=> Secure state <1=> Non-Secure state -// Interrupt 394 <0=> Secure state <1=> Non-Secure state -// Interrupt 395 <0=> Secure state <1=> Non-Secure state -// Interrupt 396 <0=> Secure state <1=> Non-Secure state -// Interrupt 397 <0=> Secure state <1=> Non-Secure state -// Interrupt 398 <0=> Secure state <1=> Non-Secure state -// Interrupt 399 <0=> Secure state <1=> Non-Secure state -// Interrupt 400 <0=> Secure state <1=> Non-Secure state -// Interrupt 401 <0=> Secure state <1=> Non-Secure state -// Interrupt 402 <0=> Secure state <1=> Non-Secure state -// Interrupt 403 <0=> Secure state <1=> Non-Secure state -// Interrupt 404 <0=> Secure state <1=> Non-Secure state -// Interrupt 405 <0=> Secure state <1=> Non-Secure state -// Interrupt 406 <0=> Secure state <1=> Non-Secure state -// Interrupt 407 <0=> Secure state <1=> Non-Secure state -// Interrupt 408 <0=> Secure state <1=> Non-Secure state -// Interrupt 409 <0=> Secure state <1=> Non-Secure state -// Interrupt 410 <0=> Secure state <1=> Non-Secure state -// Interrupt 411 <0=> Secure state <1=> Non-Secure state -// Interrupt 412 <0=> Secure state <1=> Non-Secure state -// Interrupt 413 <0=> Secure state <1=> Non-Secure state -// Interrupt 414 <0=> Secure state <1=> Non-Secure state -// Interrupt 415 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS12_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 13 (Interrupts 416..447) -*/ -#define NVIC_INIT_ITNS13 0 - -/* -// Interrupts 416..447 -// Interrupt 416 <0=> Secure state <1=> Non-Secure state -// Interrupt 417 <0=> Secure state <1=> Non-Secure state -// Interrupt 418 <0=> Secure state <1=> Non-Secure state -// Interrupt 419 <0=> Secure state <1=> Non-Secure state -// Interrupt 420 <0=> Secure state <1=> Non-Secure state -// Interrupt 421 <0=> Secure state <1=> Non-Secure state -// Interrupt 422 <0=> Secure state <1=> Non-Secure state -// Interrupt 423 <0=> Secure state <1=> Non-Secure state -// Interrupt 424 <0=> Secure state <1=> Non-Secure state -// Interrupt 425 <0=> Secure state <1=> Non-Secure state -// Interrupt 426 <0=> Secure state <1=> Non-Secure state -// Interrupt 427 <0=> Secure state <1=> Non-Secure state -// Interrupt 428 <0=> Secure state <1=> Non-Secure state -// Interrupt 429 <0=> Secure state <1=> Non-Secure state -// Interrupt 430 <0=> Secure state <1=> Non-Secure state -// Interrupt 431 <0=> Secure state <1=> Non-Secure state -// Interrupt 432 <0=> Secure state <1=> Non-Secure state -// Interrupt 433 <0=> Secure state <1=> Non-Secure state -// Interrupt 434 <0=> Secure state <1=> Non-Secure state -// Interrupt 435 <0=> Secure state <1=> Non-Secure state -// Interrupt 436 <0=> Secure state <1=> Non-Secure state -// Interrupt 437 <0=> Secure state <1=> Non-Secure state -// Interrupt 438 <0=> Secure state <1=> Non-Secure state -// Interrupt 439 <0=> Secure state <1=> Non-Secure state -// Interrupt 440 <0=> Secure state <1=> Non-Secure state -// Interrupt 441 <0=> Secure state <1=> Non-Secure state -// Interrupt 442 <0=> Secure state <1=> Non-Secure state -// Interrupt 443 <0=> Secure state <1=> Non-Secure state -// Interrupt 444 <0=> Secure state <1=> Non-Secure state -// Interrupt 445 <0=> Secure state <1=> Non-Secure state -// Interrupt 446 <0=> Secure state <1=> Non-Secure state -// Interrupt 447 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS13_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 14 (Interrupts 448..479) -*/ -#define NVIC_INIT_ITNS14 0 - -/* -// Interrupts 448..479 -// Interrupt 448 <0=> Secure state <1=> Non-Secure state -// Interrupt 449 <0=> Secure state <1=> Non-Secure state -// Interrupt 450 <0=> Secure state <1=> Non-Secure state -// Interrupt 451 <0=> Secure state <1=> Non-Secure state -// Interrupt 452 <0=> Secure state <1=> Non-Secure state -// Interrupt 453 <0=> Secure state <1=> Non-Secure state -// Interrupt 454 <0=> Secure state <1=> Non-Secure state -// Interrupt 455 <0=> Secure state <1=> Non-Secure state -// Interrupt 456 <0=> Secure state <1=> Non-Secure state -// Interrupt 457 <0=> Secure state <1=> Non-Secure state -// Interrupt 458 <0=> Secure state <1=> Non-Secure state -// Interrupt 459 <0=> Secure state <1=> Non-Secure state -// Interrupt 460 <0=> Secure state <1=> Non-Secure state -// Interrupt 461 <0=> Secure state <1=> Non-Secure state -// Interrupt 462 <0=> Secure state <1=> Non-Secure state -// Interrupt 463 <0=> Secure state <1=> Non-Secure state -// Interrupt 464 <0=> Secure state <1=> Non-Secure state -// Interrupt 465 <0=> Secure state <1=> Non-Secure state -// Interrupt 466 <0=> Secure state <1=> Non-Secure state -// Interrupt 467 <0=> Secure state <1=> Non-Secure state -// Interrupt 468 <0=> Secure state <1=> Non-Secure state -// Interrupt 469 <0=> Secure state <1=> Non-Secure state -// Interrupt 470 <0=> Secure state <1=> Non-Secure state -// Interrupt 471 <0=> Secure state <1=> Non-Secure state -// Interrupt 472 <0=> Secure state <1=> Non-Secure state -// Interrupt 473 <0=> Secure state <1=> Non-Secure state -// Interrupt 474 <0=> Secure state <1=> Non-Secure state -// Interrupt 475 <0=> Secure state <1=> Non-Secure state -// Interrupt 476 <0=> Secure state <1=> Non-Secure state -// Interrupt 477 <0=> Secure state <1=> Non-Secure state -// Interrupt 478 <0=> Secure state <1=> Non-Secure state -// Interrupt 479 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS14_VAL 0x00000000 - -/* -// -*/ - -/* -// Initialize ITNS 15 (Interrupts 480..511) -*/ -#define NVIC_INIT_ITNS15 0 - -/* -// Interrupts 480..511 -// Interrupt 480 <0=> Secure state <1=> Non-Secure state -// Interrupt 481 <0=> Secure state <1=> Non-Secure state -// Interrupt 482 <0=> Secure state <1=> Non-Secure state -// Interrupt 483 <0=> Secure state <1=> Non-Secure state -// Interrupt 484 <0=> Secure state <1=> Non-Secure state -// Interrupt 485 <0=> Secure state <1=> Non-Secure state -// Interrupt 486 <0=> Secure state <1=> Non-Secure state -// Interrupt 487 <0=> Secure state <1=> Non-Secure state -// Interrupt 488 <0=> Secure state <1=> Non-Secure state -// Interrupt 489 <0=> Secure state <1=> Non-Secure state -// Interrupt 490 <0=> Secure state <1=> Non-Secure state -// Interrupt 491 <0=> Secure state <1=> Non-Secure state -// Interrupt 492 <0=> Secure state <1=> Non-Secure state -// Interrupt 493 <0=> Secure state <1=> Non-Secure state -// Interrupt 494 <0=> Secure state <1=> Non-Secure state -// Interrupt 495 <0=> Secure state <1=> Non-Secure state -// Interrupt 496 <0=> Secure state <1=> Non-Secure state -// Interrupt 497 <0=> Secure state <1=> Non-Secure state -// Interrupt 498 <0=> Secure state <1=> Non-Secure state -// Interrupt 499 <0=> Secure state <1=> Non-Secure state -// Interrupt 500 <0=> Secure state <1=> Non-Secure state -// Interrupt 501 <0=> Secure state <1=> Non-Secure state -// Interrupt 502 <0=> Secure state <1=> Non-Secure state -// Interrupt 503 <0=> Secure state <1=> Non-Secure state -// Interrupt 504 <0=> Secure state <1=> Non-Secure state -// Interrupt 505 <0=> Secure state <1=> Non-Secure state -// Interrupt 506 <0=> Secure state <1=> Non-Secure state -// Interrupt 507 <0=> Secure state <1=> Non-Secure state -// Interrupt 508 <0=> Secure state <1=> Non-Secure state -// Interrupt 509 <0=> Secure state <1=> Non-Secure state -// Interrupt 510 <0=> Secure state <1=> Non-Secure state -// Interrupt 511 <0=> Secure state <1=> Non-Secure state -*/ -#define NVIC_INIT_ITNS15_VAL 0x00000000 - -/* -// -*/ - -/* -// -*/ - - - -/* - max 128 SAU regions. - SAU regions are defined in partition.h - */ - -#define SAU_INIT_REGION(n) \ - SAU->RNR = (n & SAU_RNR_REGION_Msk); \ - SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ - SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ - ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U - -/** - \brief Setup a SAU Region - \details Writes the region information contained in SAU_Region to the - registers SAU_RNR, SAU_RBAR, and SAU_RLAR - */ -__STATIC_INLINE void TZ_SAU_Setup (void) -{ - -#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) - - #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) - SAU_INIT_REGION(0); - #endif - - #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) - SAU_INIT_REGION(1); - #endif - - #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) - SAU_INIT_REGION(2); - #endif - - #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) - SAU_INIT_REGION(3); - #endif - - #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) - SAU_INIT_REGION(4); - #endif - - #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) - SAU_INIT_REGION(5); - #endif - - #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) - SAU_INIT_REGION(6); - #endif - - #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) - SAU_INIT_REGION(7); - #endif - - /* repeat this for all possible SAU regions */ - -#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ - - - #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) - SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | - ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; - #endif - - #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) - SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | - ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); - - SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | - SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk )) | - ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | - ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | - ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | - ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); - #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ - - #if defined (__FPU_USED) && (__FPU_USED == 1U) && \ - defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U) - - SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | - ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); - - FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | - ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | - ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | - ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); - #endif - - #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) - NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; - #endif - - #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) - NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; - #endif - - #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) - NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; - #endif - - #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) - NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; - #endif - - #if defined (NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U) - NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL; - #endif - - #if defined (NVIC_INIT_ITNS5) && (NVIC_INIT_ITNS5 == 1U) - NVIC->ITNS[5] = NVIC_INIT_ITNS5_VAL; - #endif - - #if defined (NVIC_INIT_ITNS6) && (NVIC_INIT_ITNS6 == 1U) - NVIC->ITNS[6] = NVIC_INIT_ITNS6_VAL; - #endif - - #if defined (NVIC_INIT_ITNS7) && (NVIC_INIT_ITNS7 == 1U) - NVIC->ITNS[7] = NVIC_INIT_ITNS7_VAL; - #endif - - #if defined (NVIC_INIT_ITNS8) && (NVIC_INIT_ITNS8 == 1U) - NVIC->ITNS[8] = NVIC_INIT_ITNS8_VAL; - #endif - - #if defined (NVIC_INIT_ITNS9) && (NVIC_INIT_ITNS9 == 1U) - NVIC->ITNS[9] = NVIC_INIT_ITNS9_VAL; - #endif - - #if defined (NVIC_INIT_ITNS10) && (NVIC_INIT_ITNS10 == 1U) - NVIC->ITNS[10] = NVIC_INIT_ITNS10_VAL; - #endif - - #if defined (NVIC_INIT_ITNS11) && (NVIC_INIT_ITNS11 == 1U) - NVIC->ITNS[11] = NVIC_INIT_ITNS11_VAL; - #endif - - #if defined (NVIC_INIT_ITNS12) && (NVIC_INIT_ITNS12 == 1U) - NVIC->ITNS[12] = NVIC_INIT_ITNS12_VAL; - #endif - - #if defined (NVIC_INIT_ITNS13) && (NVIC_INIT_ITNS13 == 1U) - NVIC->ITNS[13] = NVIC_INIT_ITNS13_VAL; - #endif - - #if defined (NVIC_INIT_ITNS14) && (NVIC_INIT_ITNS14 == 1U) - NVIC->ITNS[14] = NVIC_INIT_ITNS14_VAL; - #endif - - #if defined (NVIC_INIT_ITNS15) && (NVIC_INIT_ITNS15 == 1U) - NVIC->ITNS[15] = NVIC_INIT_ITNS15_VAL; - #endif - - /* repeat this for all possible ITNS elements */ - -} - -#endif /* PARTITION_ARMCM33_H */ diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c deleted file mode 100644 index 5ee4322c..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c +++ /dev/null @@ -1,138 +0,0 @@ -/****************************************************************************** - * @file startup_ARMCM33.c - * @brief CMSIS Core Device Startup File for Cortex-M33 Device - * @version V2.0.0 - * @date 20. May 2019 - ******************************************************************************/ -/* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM33) - #include "ARMCM33.h" -#elif defined (ARMCM33_TZ) - #include "ARMCM33_TZ.h" -#elif defined (ARMCM33_DSP_FP) - #include "ARMCM33_DSP_FP.h" -#elif defined (ARMCM33_DSP_FP_TZ) - #include "ARMCM33_DSP_FP_TZ.h" -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler Function Prototype - *----------------------------------------------------------------------------*/ -typedef void( *pFunc )( void ); - -/*---------------------------------------------------------------------------- - External References - *----------------------------------------------------------------------------*/ -extern uint32_t __INITIAL_SP; -extern uint32_t __STACK_LIMIT; - -extern void __PROGRAM_START(void) __NO_RETURN; - -/*---------------------------------------------------------------------------- - Internal References - *----------------------------------------------------------------------------*/ -void Default_Handler(void) __NO_RETURN; -void Reset_Handler (void) __NO_RETURN; - -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler - *----------------------------------------------------------------------------*/ -/* Exceptions */ -void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SecureFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - -void Interrupt0_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt1_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt2_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt3_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt4_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt5_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt6_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt7_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt8_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void Interrupt9_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); - - -/*---------------------------------------------------------------------------- - Exception / Interrupt Vector table - *----------------------------------------------------------------------------*/ -extern const pFunc __VECTOR_TABLE[496]; - const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { - (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ - Reset_Handler, /* Reset Handler */ - NMI_Handler, /* -14 NMI Handler */ - HardFault_Handler, /* -13 Hard Fault Handler */ - MemManage_Handler, /* -12 MPU Fault Handler */ - BusFault_Handler, /* -11 Bus Fault Handler */ - UsageFault_Handler, /* -10 Usage Fault Handler */ - SecureFault_Handler, /* -9 Secure Fault Handler */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - SVC_Handler, /* -5 SVCall Handler */ - DebugMon_Handler, /* -4 Debug Monitor Handler */ - 0, /* Reserved */ - PendSV_Handler, /* -2 PendSV Handler */ - SysTick_Handler, /* -1 SysTick Handler */ - - /* Interrupts */ - Interrupt0_Handler, /* 0 Interrupt 0 */ - Interrupt1_Handler, /* 1 Interrupt 1 */ - Interrupt2_Handler, /* 2 Interrupt 2 */ - Interrupt3_Handler, /* 3 Interrupt 3 */ - Interrupt4_Handler, /* 4 Interrupt 4 */ - Interrupt5_Handler, /* 5 Interrupt 5 */ - Interrupt6_Handler, /* 6 Interrupt 6 */ - Interrupt7_Handler, /* 7 Interrupt 7 */ - Interrupt8_Handler, /* 8 Interrupt 8 */ - Interrupt9_Handler /* 9 Interrupt 9 */ - /* Interrupts 10 .. 480 are left out */ -}; - - -/*---------------------------------------------------------------------------- - Reset Handler called on controller reset - *----------------------------------------------------------------------------*/ -void Reset_Handler(void) -{ - __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); - - SystemInit(); /* CMSIS System Initialization */ - __PROGRAM_START(); /* Enter PreMain (C library entry point) */ -} - - -/*---------------------------------------------------------------------------- - Default Handler for Exceptions / Interrupts - *----------------------------------------------------------------------------*/ -void Default_Handler(void) -{ - while(1); -} diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c deleted file mode 100644 index 17679234..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************//** - * @file system_ARMCM33.c - * @brief CMSIS Device System Source File for - * ARMCM33 Device - * @version V5.3.1 - * @date 09. July 2018 - ******************************************************************************/ -/* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined (ARMCM33) - #include "ARMCM33.h" -#elif defined (ARMCM33_TZ) - #include "ARMCM33_TZ.h" - - #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - #include "partition_ARMCM33.h" - #endif -#elif defined (ARMCM33_DSP_FP) - #include "ARMCM33_DSP_FP.h" -#elif defined (ARMCM33_DSP_FP_TZ) - #include "ARMCM33_DSP_FP_TZ.h" - - #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - #include "partition_ARMCM33.h" - #endif -#else - #error device not specified! -#endif - -/*---------------------------------------------------------------------------- - Define clocks - *----------------------------------------------------------------------------*/ -#define XTAL (50000000UL) /* Oscillator frequency */ - -#define SYSTEM_CLOCK (XTAL / 2U) - - -/*---------------------------------------------------------------------------- - Externals - *----------------------------------------------------------------------------*/ -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - extern uint32_t __Vectors; -#endif - -/*---------------------------------------------------------------------------- - System Core Clock Variable - *----------------------------------------------------------------------------*/ -uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Core Clock Frequency */ - - -/*---------------------------------------------------------------------------- - System Core Clock update function - *----------------------------------------------------------------------------*/ -void SystemCoreClockUpdate (void) -{ - SystemCoreClock = SYSTEM_CLOCK; -} - -/*---------------------------------------------------------------------------- - System initialization function - *----------------------------------------------------------------------------*/ -void SystemInit (void) -{ - -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - SCB->VTOR = (uint32_t) &__Vectors; -#endif - -#if defined (__FPU_USED) && (__FPU_USED == 1U) - SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ - (3U << 11U*2U) ); /* enable CP11 Full Access */ -#endif - -#ifdef UNALIGNED_SUPPORT_DISABLE - SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; -#endif - -#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) - TZ_SAU_Setup(); -#endif - - SystemCoreClock = SYSTEM_CLOCK; -} diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h deleted file mode 100644 index 78d1b429..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'demo_threadx_non-secure_zone' - * Target: 'FVP Simulation Model' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM33_DSP_FP_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/_ThreadX_Library_Project/RTE_Components.h b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/_ThreadX_Library_Project/RTE_Components.h deleted file mode 100644 index 1eb74752..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/RTE/_ThreadX_Library_Project/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'ThreadX_Library' - * Target: 'ThreadX_Library_Project' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "ARMCM33_DSP_FP_TZ.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt deleted file mode 100644 index 7ec4b36b..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt +++ /dev/null @@ -1,305 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - ThreadX_Demo - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 1 - 0 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 255 - - 1 - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - -1 - - - - - - - - - - - - - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGDARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(101=-1,-1,-1,-1,0)(102=-1,-1,-1,-1,0)(103=-1,-1,-1,-1,0)(104=-1,-1,-1,-1,0)(105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(163=-1,-1,-1,-1,0)(164=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0)(152=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1013=-1,-1,-1,-1,0)(171=-1,-1,-1,-1,0)(172=-1,-1,-1,-1,0)(173=-1,-1,-1,-1,0)(1014=-1,-1,-1,-1,0)(1016=-1,-1,-1,-1,0)(136=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - -T5F - - - 0 - UL2CM3 - -UV0289BJE -O14 -S0 -C0 -N00("ARM CoreSight JTAG-DP") -D00(3BA00477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0LM3S_16 -FS00 -FL04000 - - - - - - 0 - 1 - thread_0_counter - - - 1 - 1 - thread_1_counter - - - 2 - 1 - thread_2_counter - - - 3 - 1 - thread_3_counter - - - 4 - 1 - thread_4_counter - - - 5 - 1 - thread_5_counter - - - 6 - 1 - _tx_thread_current_ptr - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - - - Source Group - 1 - 0 - 0 - 0 - - 1 - 1 - 2 - 0 - 0 - 0 - .\tx_initialize_low_level.s - tx_initialize_low_level.s - 0 - 0 - - - 1 - 2 - 1 - 1 - 0 - 0 - .\demo_threadx.c - demo_threadx.c - 0 - 0 - - 44 - 0 - 1 - - -1 - -1 - - - -1 - -1 - - - 56 - 12 - 1633 - 671 - - - - - - - Library_Group - 1 - 0 - 0 - 0 - - 2 - 3 - 4 - 0 - 0 - 0 - .\ThreadX_Library.lib - ThreadX_Library.lib - 0 - 0 - - - -
diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj deleted file mode 100644 index 5f5dcbdb..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj +++ /dev/null @@ -1,556 +0,0 @@ - - - - 1.1 - -
### uVision Project, (C) Keil Software
- - - - ThreadX_Demo - 0x4 - ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC - 0 - - - Cortex-M4 FPU - ARM - CLOCK(12000000) CPUTYPE("Cortex-M4") ESEL ELITTLE FPU2 - - - - 5237 - - - - - - - - - - - - 0 - 0 - - - - Luminary\ - Luminary\ - - 0 - 0 - 0 - 0 - 1 - - .\ - threadx_demo - 1 - 0 - 0 - 1 - 1 - .\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 0 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - SARMCM3.DLL - - DCM.DLL - -pCM4F - SARMCM3.DLL - - TCM.DLL - -pCM4F - - - - 1 - 0 - 0 - 0 - 16 - - - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - - - 0 - 1 - 0 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - - 0 - -1 - - - - - - - - - - - - - - - - - - - 1 - 0 - 0 - 0 - 1 - 4096 - - 0 - BIN\UL2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M4" - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 1 - 0x0 - 0x40000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - - - - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - - - - - - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - - - - --first __tx_vectors --entry=__main - - - - - - - - Source Group - - - 0 - 1 - 1 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 11 - - - 0 - - - - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - - - - - - - - - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - - - - - - - - - - - - tx_initialize_low_level.s - 2 - .\tx_initialize_low_level.s - - - 2 - 0 - 0 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 11 - - - 1 - - - - 2 - 2 - 2 - 1 - 2 - 2 - 2 - 2 - 2 - 2 - - - - - - - - - - - - demo_threadx.c - 1 - .\demo_threadx.c - - - - - Library_Group - - - ThreadX_Library.lib - 4 - .\ThreadX_Library.lib - - - - - - - -
diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx.c b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx.c deleted file mode 100644 index 3d4032a4..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx.c +++ /dev/null @@ -1,400 +0,0 @@ -/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight - threads of different priorities, using a message queue, semaphore, mutex, event flags group, - byte pool, and block pool. Please refer to Chapter 6 of the ThreadX User Guide for a complete - description of this demonstration. */ - -#include "tx_api.h" -#include "..\demo_secure_zone\interface.h" /* Interface to sample secure functions. */ - -#define DEMO_STACK_SIZE 1024 -#define DEMO_BYTE_POOL_SIZE 9120 -#define DEMO_BLOCK_POOL_SIZE 100 -#define DEMO_QUEUE_SIZE 100 - - -/* Define the ThreadX object control blocks... */ - -static TX_THREAD thread_0; -static TX_THREAD thread_1; -static TX_THREAD thread_2; -static TX_THREAD thread_3; -static TX_THREAD thread_4; -static TX_THREAD thread_5; -static TX_THREAD thread_6; -static TX_THREAD thread_7; -static TX_QUEUE queue_0; -static TX_SEMAPHORE semaphore_0; -static TX_MUTEX mutex_0; -static TX_EVENT_FLAGS_GROUP event_flags_0; -static TX_BYTE_POOL byte_pool_0; -static TX_BLOCK_POOL block_pool_0; - -/* Define byte pool memory. */ - -static UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE]; - - -/* Define event buffer. */ - -#ifdef TX_ENABLE_EVENT_TRACE -UCHAR trace_buffer[0x10000]; -#endif - - -/* Define the counters used in the demo application... */ - -static ULONG thread_0_counter; -static ULONG thread_1_counter; -static ULONG thread_1_messages_sent; -static ULONG thread_2_counter; -static ULONG thread_2_messages_received; -static ULONG thread_3_counter; -static ULONG thread_4_counter; -static ULONG thread_5_counter; -static ULONG thread_6_counter; -static ULONG thread_7_counter; - - -/* Define thread prototypes. */ - -void thread_0_entry(ULONG thread_input); -void thread_1_entry(ULONG thread_input); -void thread_2_entry(ULONG thread_input); -void thread_3_and_4_entry(ULONG thread_input); -void thread_5_entry(ULONG thread_input); -void thread_6_and_7_entry(ULONG thread_input); - -/* Define main entry point. */ - -int main() -{ - - /* Please refer to Chapter 6 of the ThreadX User Guide for a complete - description of this demonstration. */ - - - /* Enter the ThreadX kernel. */ - tx_kernel_enter(); -} - - -/* Define what the initial system looks like. */ - -void tx_application_define(void *first_unused_memory) -{ - -CHAR *pointer; - - (VOID)first_unused_memory; /* unused parameter. */ - -#ifdef TX_ENABLE_EVENT_TRACE - tx_trace_enable(trace_buffer, sizeof(trace_buffer), 32); -#endif - - /* Create a byte memory pool from which to allocate the thread stacks. */ - tx_byte_pool_create(&byte_pool_0, "byte pool 0", byte_pool_memory, DEMO_BYTE_POOL_SIZE); - - /* Put system definition stuff in here, e.g. thread creates and other assorted - create information. */ - - /* Allocate the stack for thread 0. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create the main thread. */ - tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, - pointer, DEMO_STACK_SIZE, - 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate the stack for thread 1. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create threads 1 and 2. These threads pass information through a ThreadX - message queue. It is also interesting to note that these threads have a time - slice. */ - tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, - pointer, DEMO_STACK_SIZE, - 16, 16, 4, TX_AUTO_START); - - /* Allocate the stack for thread 2. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, - pointer, DEMO_STACK_SIZE, - 16, 16, 4, TX_AUTO_START); - - /* Allocate the stack for thread 3. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore. - An interesting thing here is that both threads share the same instruction area. */ - tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate the stack for thread 4. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate the stack for thread 5. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create thread 5. This thread simply pends on an event flag which will be set - by thread_0. */ - tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, - pointer, DEMO_STACK_SIZE, - 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate the stack for thread 6. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */ - tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate the stack for thread 7. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - - tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7, - pointer, DEMO_STACK_SIZE, - 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); - - /* Allocate the message queue. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT); - - /* Create the message queue shared by threads 1 and 2. */ - tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG)); - - /* Create the semaphore used by threads 3 and 4. */ - tx_semaphore_create(&semaphore_0, "semaphore 0", 1); - - /* Create the event flags group used by threads 1 and 5. */ - tx_event_flags_create(&event_flags_0, "event flags 0"); - - /* Create the mutex used by thread 6 and 7 without priority inheritance. */ - tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); - - /* Allocate the memory for a small block pool. */ - tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT); - - /* Create a block memory pool to allocate a message buffer from. */ - tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE); - - /* Allocate a block and release the block memory. */ - tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT); - - /* Release the block back to the pool. */ - tx_block_release(pointer); - - tx_thread_secure_stack_allocate(&thread_0,256); - tx_thread_secure_stack_allocate(&thread_1,256); - tx_thread_secure_stack_allocate(&thread_2,256); - tx_thread_secure_stack_allocate(&thread_3,256); - tx_thread_secure_stack_allocate(&thread_4,256); - tx_thread_secure_stack_allocate(&thread_5,256); - tx_thread_secure_stack_allocate(&thread_6,256); - tx_thread_secure_stack_allocate(&thread_7,256); -} - - - -/* Define the test threads. */ - -void thread_0_entry(ULONG thread_input) -{ -UINT status; - - (VOID)thread_input; /* unused parameter. */ - - /* This thread simply sits in while-forever-sleep loop. */ - while(1) - { - - /* Increment the thread counter. */ - thread_0_counter++; - - /* Sleep for 10 ticks. */ - tx_thread_sleep(10); - - /* Set event flag 0 to wakeup thread 5. */ - status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - } -} - - -void thread_1_entry(ULONG thread_input) -{ - -UINT status; - - (VOID)thread_input; /* unused parameter. */ - - /* This thread simply sends messages to a queue shared by thread 2. */ - while(1) - { - /* Increment the thread counter. */ - thread_1_counter++; - - /* Send message to queue 0. */ - status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER); - - /* Check completion status. */ - if (status != TX_SUCCESS) - break; - - /* Increment the message sent. */ - thread_1_messages_sent++; - } -} - - -void thread_2_entry(ULONG thread_input) -{ - -ULONG received_message; -UINT status; - - (VOID)thread_input; /* unused parameter. */ - - /* This thread retrieves messages placed on the queue by thread 1. */ - while(1) - { - - /* Increment the thread counter. */ - thread_2_counter++; - - /* Retrieve a message from the queue. */ - status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER); - - /* Check completion status and make sure the message is what we - expected. */ - if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received)) - break; - - /* Otherwise, all is okay. Increment the received message count. */ - thread_2_messages_received++; - } -} - - -void thread_3_and_4_entry(ULONG thread_input) -{ - -UINT status; - - /* This function is executed from thread 3 and thread 4. As the loop - below shows, these function compete for ownership of semaphore_0. */ - while(1) - { - - /* Increment the thread counter. */ - if (thread_input == 3) - thread_3_counter++; - else - thread_4_counter++; - - /* Get the semaphore with suspension. */ - status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Sleep for 2 ticks to hold the semaphore. */ - tx_thread_sleep(2); - - /* Release the semaphore. */ - status = tx_semaphore_put(&semaphore_0); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - } -} - - -void thread_5_entry(ULONG thread_input) -{ - -UINT status; -ULONG actual_flags; - - (VOID)thread_input; /* unused parameter. */ - - /* This thread simply waits for an event in a forever loop. */ - while(1) - { - - /* Increment the thread counter. */ - thread_5_counter++; - - /* Wait for event flag 0. */ - status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR, - &actual_flags, TX_WAIT_FOREVER); - - /* Check status. */ - if ((status != TX_SUCCESS) || (actual_flags != 0x1)) - break; - } -} - - -void thread_6_and_7_entry(ULONG thread_input) -{ - -UINT status; - - - /* This function is executed from thread 6 and thread 7. As the loop - below shows, these function compete for ownership of mutex_0. */ - while(1) - { - - /* Increment the thread counter. */ - if (thread_input == 6) - thread_6_counter++; - else - thread_7_counter++; - - /* Get the mutex with suspension. */ - status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Get the mutex again with suspension. This shows - that an owning thread may retrieve the mutex it - owns multiple times. */ - status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Sleep for 2 ticks to hold the mutex. */ - tx_thread_sleep(2); - - /* Release the mutex. */ - status = tx_mutex_put(&mutex_0); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - - /* Release the mutex again. This will actually - release ownership since it was obtained twice. */ - status = tx_mutex_put(&mutex_0); - - /* Check status. */ - if (status != TX_SUCCESS) - break; - } -} diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx deleted file mode 100644 index c6f15929..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx +++ /dev/null @@ -1,359 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - FVP Simulation Model - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\Listings\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 0 - 0 - 1 - - 7 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 15 - - - - - - - - - - ..\Debug.ini - BIN\DbgFMv8M.DLL - - - - 0 - PWSTATINFO - 200,50,700 - - - 0 - DLGTARM - (6010=636,564,1113,1160,0)(6018=1284,352,1473,701,0)(6019=1328,34,1517,370,0)(6008=-1,-1,-1,-1,0)(6009=1290,960,1584,1146,0)(6014=1111,129,1369,860,0)(6015=872,146,1130,768,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - (105=150,186,829,544,0)(106=511,345,1277,659,0)(107=-1,-1,-1,-1,0) - - - 0 - DbgFMv8M - -I -S -L"cpu0" -O4102 -C0 -MC".\FVP\MPS2_Cortex-M\FVP_MPS2_Cortex-M33_MDK.exe" -MF"..\ARMCM33_DSP_FP_TZ_config.txt" -MA - - - 0 - UL2V8M - UL2V8M(-S0 -C0 -P0 -FC1000 -FD20000000 - - - - - 0 - 0 - 251 - 1 -
2111470
- 0 - 0 - 0 - 0 - 0 - 1 - <3>.\tx_initialize_low_level.S - - \\demo_threadx_non_secure_zone\tx_initialize_low_level.S\251 -
-
- - - 0 - 1 - thread_0_counter - - - 1 - 1 - thread_1_counter - - - 2 - 1 - thread_2_counter - - - 3 - 1 - thread_3_counter - - - 4 - 1 - thread_4_counter - - - 5 - 1 - thread_5_counter - - - 6 - 1 - thread_6_counter - - - 7 - 1 - thread_7_counter - - - - - 1 - 2 - 0x2001ffd8 - 0 - - - - - 2 - 2 - 0xE000ED28 - 0 - - - - 0 - - - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - 1 - 0 - 0 - 1 - 10000000 - -
-
- - - Non-secure Code - 1 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - .\demo_threadx.c - demo_threadx.c - 0 - 0 - - - 1 - 2 - 4 - 0 - 0 - 0 - ..\ThreadX_Library.lib - ThreadX_Library.lib - 0 - 0 - - - - - CMSE Library - 1 - 0 - 0 - 0 - - 2 - 3 - 5 - 0 - 0 - 0 - ..\demo_secure_zone\interface.h - interface.h - 0 - 0 - - - 2 - 4 - 3 - 0 - 0 - 0 - ..\demo_secure_zone\Objects\demo_secure_zone_CMSE_Lib.o - demo_secure_zone_CMSE_Lib.o - 0 - 0 - - - - - ::CMSIS - 1 - 0 - 0 - 1 - - - - ::Device - 1 - 0 - 0 - 1 - - -
diff --git a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx b/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx deleted file mode 100644 index f6bb1598..00000000 --- a/ports/cortex_m33/ac5/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx +++ /dev/null @@ -1,585 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - FVP Simulation Model - 0x4 - ARM-ADS - 6140000::V6.14::ARMCLANG - 1 - - - ARMCM33_DSP_FP_TZ - ARM - ARM.CMSIS.5.7.0 - http://www.keil.com/pack/ - IRAM(0x20000000,0x00020000) IRAM2(0x20200000,0x00020000) IROM(0x00000000,0x00200000) IROM2(0x00200000,0x00200000) CPUTYPE("Cortex-M33") FPU3(SFPU) DSP TZ CLOCK(12000000) ESEL ELITTLE - - - UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000) - 0 - $$Device:ARMCM33_DSP_FP_TZ$Device\ARM\ARMCM33\Include\ARMCM33_DSP_FP_TZ.h - - - - - - - - - - $$Device:ARMCM33_DSP_FP_TZ$Device\ARM\SVD\ARMCM33.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\Objects\ - demo_threadx_non-secure_zone - 1 - 0 - 0 - 1 - 1 - .\Listings\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - - - - - SARMV8M.DLL - -MPU - TCM.DLL - -pCM33 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 0 - -1 - - 1 - BIN\UL2V8M.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M33" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 2 - 0 - 0 - 1 - 1 - 16 - 1 - 1 - 0 - 0 - 4 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 1 - 0x0 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x200000 - - - 1 - 0x200000 - 0x200000 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x20000 - - - 0 - 0x20200000 - 0x20000 - - - - - - 1 - 2 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 0 - 3 - 1 - 1 - 1 - 0 - 0 - 0 - - -Wno-unused-function -Wno-visibility - - - ..\..\..\..\..\common\inc, ..\..\inc - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 13 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - .\RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_AC6.sct - - - - - - - - - - - Non-secure Code - - - demo_threadx.c - 1 - .\demo_threadx.c - - - ThreadX_Library.lib - 4 - ..\ThreadX_Library.lib - - - - - CMSE Library - - - interface.h - 5 - ..\demo_secure_zone\interface.h - - - demo_secure_zone_CMSE_Lib.o - 3 - ..\demo_secure_zone\Objects\demo_secure_zone_CMSE_Lib.o - - - - - ::CMSIS - - - ::Device - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RTE\CMSIS\RTX_Config.c - - - - - - RTE\CMSIS\RTX_Config.h - - - - - - RTE\Device\ARMCM33_DSP_FP\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_DSP_FP\system_ARMCM33.c - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_ac6.sct - - - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\partition_ARMCM33.h - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.c - - - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_DSP_FP_TZ\system_ARMCM33.c - - - - - - - - RTE\Device\ARMCM33_TZ\partition_ARMCM33.h - - - - - - RTE\Device\ARMCM33_TZ\startup_ARMCM33.s - - - - - - RTE\Device\ARMCM33_TZ\system_ARMCM33.c - - - - - - RTE\Device\ARMv8MBL\partition_ARMv8MBL.h - - - - - - RTE\Device\ARMv8MBL\startup_ARMv8MBL.s - - - - - - RTE\Device\ARMv8MBL\system_ARMv8MBL.c - - - - - - RTE\Device\CMSDK_ARMv8MBL\RTE_Device.h - - - - - - RTE\Device\CMSDK_ARMv8MBL\partition_CMSDK_ARMv8MBL.h - - - - - - RTE\Device\CMSDK_ARMv8MBL\startup_CMSDK_ARMv8MBL.s - - - - - - RTE\Device\CMSDK_ARMv8MBL\system_CMSDK_ARMv8MBL.c - - - - - - - - - - - <Project Info> - - - - - - 0 - 1 - - - - -
diff --git a/ports/cortex_m33/ac5/example_build/tx_initialize_low_level.S b/ports/cortex_m33/ac5/example_build/tx_initialize_low_level.S deleted file mode 100644 index 6ea775c6..00000000 --- a/ports/cortex_m33/ac5/example_build/tx_initialize_low_level.S +++ /dev/null @@ -1,284 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IMPORT _tx_thread_system_stack_ptr - IMPORT _tx_initialize_unused_memory - IMPORT _tx_thread_context_save - IMPORT _tx_thread_context_restore - IMPORT _tx_timer_interrupt - IMPORT __main - IMPORT |Image$$RW_RAM$$ZI$$Limit| - IMPORT __Vectors - IMPORT SystemInit - IMPORT _tx_thread_current_ptr - IMPORT _tx_thread_stack_error_handler -; -; -SYSTEM_CLOCK EQU 6000000 -SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 100) -1) -; -; -;/* Setup the stack and heap areas. */ -; -STACK_SIZE EQU 0x00000400 -HEAP_SIZE EQU 0x00000000 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -StackMem - SPACE STACK_SIZE -__initial_sp - - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -HeapMem - SPACE HEAP_SIZE -__heap_limit - - - AREA ||.text||, CODE, READONLY - PRESERVE8 - -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_initialize_low_level Cortex-M33/AC5 */ -;/* 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) -;{ - EXPORT _tx_initialize_low_level -_tx_initialize_low_level FUNCTION -; -; /* 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$$RW_RAM$$ZI$$Limit| ; Build first free address - ADD r1, r1, #4 ; - STR r1, [r0] ; Setup first unused memory pointer -; -; /* Setup Vector Table Offset Register. */ -; - MOV r0, #0xE000E000 ; Build address of NVIC registers - LDR r1, =__Vectors ; Pickup address of vector table - STR r1, [r0, #0xD08] ; 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. */ -; - MOV r0, #0xE000E000 ; Build address of NVIC registers - LDR r1, =SYSTICK_CYCLES - STR r1, [r0, #0x14] ; Setup SysTick Reload Value - MOV r1, #0x7 ; Build SysTick Control Enable Value - STR r1, [r0, #0x10] ; Setup SysTick Control -; -; /* Configure handler priorities. */ -; - LDR r1, =0x00000000 ; Rsrv, UsgF, BusF, MemM - STR r1, [r0, #0xD18] ; Setup System Handlers 4-7 Priority Registers - - LDR r1, =0xFF000000 ; SVCl, Rsrv, Rsrv, Rsrv - STR r1, [r0, #0xD1C] ; Setup System Handlers 8-11 Priority Registers - ; Note: SVC must be lowest priority, which is 0xFF - - LDR r1, =0x40FF0000 ; SysT, PnSV, Rsrv, DbgM - STR r1, [r0, #0xD20] ; Setup System Handlers 12-15 Priority Registers - ; Note: PnSV must be lowest priority, which is 0xFF -; -; /* Return to caller. */ -; - BX lr - ENDFUNC -;} -; -; -;/* Define initial heap/stack routine for the ARM startup code. -; This routine will set the initial stack and heap locations. */ -; - EXPORT __user_initial_stackheap -__user_initial_stackheap FUNCTION - LDR r0, =HeapMem - LDR r1, =(StackMem + STACK_SIZE) - LDR r2, =(HeapMem + HEAP_SIZE) - LDR r3, =StackMem - BX lr - ENDFUNC -; -; -;/* Define shells for each of the unused vectors. */ -; - EXPORT __tx_BadHandler -__tx_BadHandler FUNCTION - B __tx_BadHandler - ENDFUNC - - EXPORT __tx_IntHandler -__tx_IntHandler FUNCTION -; VOID InterruptHandler (VOID) -; { - PUSH {r0, lr} ; Save LR (and dummy r0 to maintain stack alignment) - -; /* Do interrupt handler work here */ -; /* .... */ - - POP {r0, lr} - BX lr -; } - ENDFUNC - - - EXPORT __tx_SysTickHandler - EXPORT SysTick_Handler -SysTick_Handler FUNCTION -__tx_SysTickHandler -; VOID TimerInterruptHandler (VOID) -; { -; - PUSH {r0, lr} ; Save LR (and dummy r0 to maintain stack alignment) - BL _tx_timer_interrupt - POP {r0, lr} - BX lr -; } - ENDFUNC - - - EXPORT HardFault_Handler -HardFault_Handler FUNCTION - B HardFault_Handler - ENDFUNC - - - EXPORT UsageFault_Handler -UsageFault_Handler FUNCTION - CPSID i ; Disable interrupts - ; Check for stack limit fault - LDR r0, =0xE000ED28 ; CFSR address - LDR r1,[r0] ; Pick up CFSR - TST r1, #0x00100000 ; Check for Stack Overflow -_unhandled_usage_loop - BEQ _unhandled_usage_loop ; If not stack overflow then loop - - ; Handle stack overflow - STR r1, [r0] ; Clear CFSR flag(s) - - IF {TARGET_FPU_VFP} = {TRUE} - 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 - ENDIF - - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r0,[r0] ; Pick up current thread pointer - PUSH {r0,lr} ; Save LR (and r0 to maintain stack alignment) - BL _tx_thread_stack_error_handler ; Call ThreadX/user handler - POP {r0,lr} ; Restore LR and dummy reg - - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY - ; Call the thread exit function to indicate the thread is no longer executing. - 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 - ENDIF - - MOV r1, #0 ; Build NULL value - LDR r0, =_tx_thread_current_ptr ; Pickup address of current thread pointer - STR r1, [r0] ; Clear current thread pointer - - ; Return from UsageFault_Handler exception - LDR r0, =0xE000ED04 ; Load ICSR - LDR r1, =0x10000000 ; Set PENDSVSET bit - STR r1, [r0] ; Store ICSR - DSB ; Wait for memory access to complete - CPSIE i ; Enable interrupts - BX lr ; Return from exception - ENDFUNC - - - - EXPORT __tx_NMIHandler -__tx_NMIHandler FUNCTION - B __tx_NMIHandler - ENDFUNC - - - EXPORT __tx_DBGHandler -__tx_DBGHandler FUNCTION - B __tx_DBGHandler - ENDFUNC - - ALIGN - LTORG - END diff --git a/ports/cortex_m33/ac5/inc/tx_port.h b/ports/cortex_m33/ac5/inc/tx_port.h deleted file mode 100644 index 4cf5588e..00000000 --- a/ports/cortex_m33/ac5/inc/tx_port.h +++ /dev/null @@ -1,550 +0,0 @@ -/**************************************************************************/ -/* */ -/* 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 */ -/** */ -/** Port Specific */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - - -/**************************************************************************/ -/* */ -/* PORT SPECIFIC C INFORMATION RELEASE */ -/* */ -/* tx_port.h Cortex-M33/AC5 */ -/* 6.1.6 */ -/* */ -/* AUTHOR */ -/* */ -/* Scott Larson, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This file contains data type definitions that make the ThreadX */ -/* real-time kernel function identically on a variety of different */ -/* processor architectures. For example, the size or number of bits */ -/* in an "int" data type vary between microprocessor architectures and */ -/* even C compilers for the same microprocessor. ThreadX does not */ -/* directly use native C data types. Instead, ThreadX creates its */ -/* own special types that can be mapped to actual data types by this */ -/* file to guarantee consistency in the interface and functionality. */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ -/* */ -/**************************************************************************/ - -#ifndef TX_PORT_H -#define TX_PORT_H - -/* Determine if the optional ThreadX user define file should be used. */ -#ifdef TX_INCLUDE_USER_DEFINE_FILE - -/* Yes, include the user defines in tx_user.h. The defines in this file may - alternately be defined on the command line. */ - -#include "tx_user.h" -#endif - -/* Define compiler library include files. */ - -#include -#include -#include -#include "ARMCM33_DSP_FP_TZ.h" /* For intrinsic functions. */ - -/* Define ThreadX basic types for this port. */ - -#define VOID void -typedef char CHAR; -typedef unsigned char UCHAR; -typedef int INT; -typedef unsigned int UINT; -typedef long LONG; -typedef unsigned long ULONG; -typedef unsigned long long ULONG64; -typedef short SHORT; -typedef unsigned short USHORT; - -/* Function prototypes for this port. */ -struct TX_THREAD_STRUCT; -UINT _txe_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *thread_ptr, ULONG stack_size); -UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); -UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); -UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); - -/* This hardware has stack checking that we take advantage of - do NOT define. */ -#ifdef TX_ENABLE_STACK_CHECKING - #error "Do not define TX_ENABLE_STACK_CHECKING" -#endif - -/* If user does not want to terminate thread on stack overflow, - #define the TX_THREAD_NO_TERMINATE_STACK_ERROR symbol. - The thread will be rescheduled and continue to cause the exception. - It is suggested user code handle this by registering a notification with the - tx_thread_stack_error_notify function. */ -/*#define TX_THREAD_NO_TERMINATE_STACK_ERROR */ - -/* Define the system API mappings based on the error checking - selected by the user. Note: this section is only applicable to - application source code, hence the conditional that turns off this - stuff when the include file is processed by the ThreadX source. */ - -#ifndef TX_SOURCE_CODE - - -/* Determine if error checking is desired. If so, map API functions - to the appropriate error checking front-ends. Otherwise, map API - functions to the core functions that actually perform the work. - Note: error checking is enabled by default. */ - -#ifdef TX_DISABLE_ERROR_CHECKING - -/* Services without error checking. */ - -#define tx_thread_secure_stack_allocate _tx_thread_secure_stack_allocate -#define tx_thread_secure_stack_free _tx_thread_secure_stack_free - -#else - -/* Services with error checking. */ - -#define tx_thread_secure_stack_allocate _txe_thread_secure_stack_allocate -#define tx_thread_secure_stack_free _txe_thread_secure_stack_free - -#endif -#endif - - - -/* Define the priority levels for ThreadX. Legal values range - from 32 to 1024 and MUST be evenly divisible by 32. */ - -#ifndef TX_MAX_PRIORITIES -#define TX_MAX_PRIORITIES 32 -#endif - - -/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during - thread creation is less than this value, the thread create call will return an error. */ - -#ifndef TX_MINIMUM_STACK -#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */ -#endif - - -/* Define the system timer thread's default stack size and priority. These are only applicable - if TX_TIMER_PROCESS_IN_ISR is not defined. */ - -#ifndef TX_TIMER_THREAD_STACK_SIZE -#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ -#endif - -#ifndef TX_TIMER_THREAD_PRIORITY -#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ -#endif - - -/* Define various constants for the ThreadX Cortex-M33 port. */ - -#define TX_INT_DISABLE 1 /* Disable interrupts */ -#define TX_INT_ENABLE 0 /* Enable interrupts */ - - -/* 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 - source constants would be: - -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) -#define TX_TRACE_TIME_MASK 0x0000FFFFUL - -*/ - -#ifndef TX_MISRA_ENABLE -#ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) -#endif -#else -ULONG _tx_misra_time_stamp_get(VOID); -#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() -#endif - -#ifndef TX_TRACE_TIME_MASK -#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL -#endif - - -/* Define the port specific options for the _tx_build_options variable. This variable indicates - how the ThreadX library was built. */ - -#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) - - -/* Define the in-line initialization constant so that modules with in-line - initialization capabilities can prevent their initialization from being - a function call. */ - -#ifdef TX_MISRA_ENABLE -#define TX_DISABLE_INLINE -#else -#define TX_INLINE_INITIALIZATION -#endif - - -/* 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 - logic. */ - -#ifndef TX_MISRA_ENABLE -#ifdef TX_ENABLE_STACK_CHECKING -#undef TX_DISABLE_STACK_FILLING -#endif -#endif - - -/* 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 - existing ThreadX kernel awareness modules. */ - -#define TX_THREAD_EXTENSION_0 -#define TX_THREAD_EXTENSION_1 -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -#define TX_THREAD_EXTENSION_2 VOID *tx_thread_secure_stack_context; -#else -#define TX_THREAD_EXTENSION_2 -#endif -#define TX_THREAD_EXTENSION_3 - - -/* Define the port extensions of the remaining ThreadX objects. */ - -#define TX_BLOCK_POOL_EXTENSION -#define TX_BYTE_POOL_EXTENSION -#define TX_EVENT_FLAGS_GROUP_EXTENSION -#define TX_MUTEX_EXTENSION -#define TX_QUEUE_EXTENSION -#define TX_SEMAPHORE_EXTENSION -#define TX_TIMER_EXTENSION - - -/* 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 -#define TX_THREAD_USER_EXTENSION -#endif - - -/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, - tx_thread_shell_entry, and tx_thread_terminate. */ - - -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) if(thread_ptr -> tx_thread_secure_stack_context){_tx_thread_secure_stack_free(thread_ptr);} -#else -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) -#endif - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -/* Define the size of the secure stack for the timer thread and use the extension to allocate the secure stack. */ -#define TX_TIMER_THREAD_SECURE_STACK_SIZE 256 -#define TX_TIMER_INITIALIZE_EXTENSION(status) _tx_thread_secure_stack_allocate(&_tx_timer_thread, TX_TIMER_THREAD_SECURE_STACK_SIZE); -#endif - - -#ifndef TX_MISRA_ENABLE - -//register unsigned int _ipsr __asm ("MRS %[result], ipsr" : [result] "=r" (_ipsr) : ); -inline static unsigned int _get_ipsr(void); -inline static unsigned int _get_ipsr(void) -{ - unsigned int _ipsr; - __asm("MRS %[result], ipsr" : [result] "=r" (_ipsr) : ); - return _ipsr; -} - -#endif - - -#ifdef __ARM_PCS_VFP - -#ifdef TX_MISRA_ENABLE - -ULONG _tx_misra_control_get(void); -void _tx_misra_control_set(ULONG value); -ULONG _tx_misra_fpccr_get(void); -void _tx_misra_vfp_touch(void); - -#else - -#ifdef TX_SOURCE_CODE - -static unsigned int _get_control(void); -static unsigned int _get_control(void) -{ - unsigned int _control; - __asm("MRS %[result], control" : [result] "=r" (_control) : ); - return _control; -} - -static void _set_control(unsigned int _control); -static void _set_control(unsigned int _control) -{ - __asm("MSR control, %[input]" : : [input] "r" (_control)); -} - -#endif -#endif - -/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA - in order to ensure no lazy stacking will occur. */ - -#ifndef TX_MISRA_ENABLE - -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _set_control(_tx_vfp_state);; \ - } -#else - -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif - -/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. - If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating - this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush - the lazy FPU save, then restore the CONTROL.FPCA state. */ - -#ifndef TX_MISRA_ENABLE - -void _tx_vfp_access(void); - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((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 = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_vfp_access(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } -#else - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } -#endif - -#else - -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) - -#endif - - -/* Define the ThreadX object creation extensions for the remaining objects. */ - -#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) -#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) -#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) -#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) -#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) -#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) -#define TX_TIMER_CREATE_EXTENSION(timer_ptr) - - -/* Define the ThreadX object deletion extensions for the remaining objects. */ - -#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) -#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) -#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) -#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) -#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) -#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) -#define TX_TIMER_DELETE_EXTENSION(timer_ptr) - - -/* 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()) -#else -ULONG _tx_misra_ipsr_get(VOID); -#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif - - -/* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h - for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always - zero after initialization for Cortex-M ports. */ - -#ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); -#endif - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -/* Initialize secure stacks for threads calling secure functions. */ -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 - 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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); - -#endif - - -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ - -#ifdef TX_DISABLE_INLINE - -UINT _tx_thread_interrupt_disable(VOID); -VOID _tx_thread_interrupt_restore(UINT previous_posture); - -#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; - -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); - -#define _tx_thread_system_return _tx_thread_system_return_inline - - -static void _tx_thread_system_return_inline(void) -{ -unsigned int was_masked; - - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (_get_ipsr() == 0) - { - was_masked = __disable_irq(); - __enable_irq(); - if (was_masked != 0) - __disable_irq(); - } -} -#endif - - -/* 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-M33/AC5 Version 6.1.6 *"; -#else -#ifdef TX_MISRA_ENABLE -extern CHAR _tx_version_id[100]; -#else -extern CHAR _tx_version_id[]; -#endif -#endif - -#endif diff --git a/ports/cortex_m33/ac5/readme_threadx.txt b/ports/cortex_m33/ac5/readme_threadx.txt deleted file mode 100644 index 65f9624e..00000000 --- a/ports/cortex_m33/ac5/readme_threadx.txt +++ /dev/null @@ -1,217 +0,0 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M33 - - Using the AC5 Tools in Keil uVision - -1. Import the ThreadX Projects - -In order to build the ThreadX library and the ThreadX demonstration, first open -the AzureRTOS.uvmpw workspace (located in the "example_build" directory) -into Keil. - - -2. Building the ThreadX run-time Library - -Building the ThreadX library is easy; simply set the ThreadX_Library project -as active, then then build the library. You should now observe the compilation -and assembly of the ThreadX library. This project build produces the ThreadX -library file ThreadX_Library.lib. - - -3. Demonstration System - -The ThreadX demonstration is designed to execute under the Keil debugger on the -FVP_MPS2_Cortex-M33_MDK simulator. - -Building the demonstration is easy; simply select the "Batch Build" button. -You should now observe the compilation and assembly of the ThreadX demonstration of -both the demo_secure_zone and demo_threadx_non-secure_zone projects. -Then click the Start/Stop Debug Session button to start the simulator and begin debugging. -You are now ready to execute the ThreadX demonstration. - - -4. System Initialization - -The entry point in ThreadX for the Cortex-M33 using AC5 tools uses the standard AC5 -Cortex-M33 reset sequence. From the reset vector the C runtime will be initialized. - -The ThreadX tx_initialize_low_level.S file is responsible for setting up -various system data structures, the vector area, and a periodic timer interrupt -source. - -In addition, _tx_initialize_low_level determines the first available -address for use by the application, which is supplied as the sole input -parameter to your application definition function, tx_application_define. - - -5. Register Usage and Stack Frames - -The following defines the saved context stack frames for context switches -that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M33 version of -ThreadX. The top of the suspended thread's stack is pointed to by -tx_thread_stack_ptr in the associated thread control block TX_THREAD. - -Non-FPU Stack Frame: - - Stack Offset Stack Contents - - 0x00 LR Interrupted LR (LR at time of PENDSV) - 0x04 r4 Software stacked GP registers - 0x08 r5 - 0x0C r6 - 0x10 r7 - 0x14 r8 - 0x18 r9 - 0x1C r10 - 0x20 r11 - 0x24 r0 Hardware stacked registers - 0x28 r1 - 0x2C r2 - 0x30 r3 - 0x34 r12 - 0x38 lr - 0x3C pc - 0x40 xPSR - -FPU Stack Frame (only interrupted thread with FPU enabled): - - Stack Offset Stack Contents - - 0x00 LR Interrupted LR (LR at time of PENDSV) - 0x04 s16 Software stacked FPU registers - 0x08 s17 - 0x0C s18 - 0x10 s19 - 0x14 s20 - 0x18 s21 - 0x1C s22 - 0x20 s23 - 0x24 s24 - 0x28 s25 - 0x2C s26 - 0x30 s27 - 0x34 s28 - 0x38 s29 - 0x3C s30 - 0x40 s31 - 0x44 r4 Software stacked registers - 0x48 r5 - 0x4C r6 - 0x50 r7 - 0x54 r8 - 0x58 r9 - 0x5C r10 - 0x60 r11 - 0x64 r0 Hardware stacked registers - 0x68 r1 - 0x6C r2 - 0x70 r3 - 0x74 r12 - 0x78 lr - 0x7C pc - 0x80 xPSR - 0x84 s0 Hardware stacked FPU registers - 0x88 s1 - 0x8C s2 - 0x90 s3 - 0x94 s4 - 0x98 s5 - 0x9C s6 - 0xA0 s7 - 0xA4 s8 - 0xA8 s9 - 0xAC s10 - 0xB0 s11 - 0xB4 s12 - 0xB8 s13 - 0xBC s14 - 0xC0 s15 - 0xC4 fpscr - - -6. Improving Performance - -To make ThreadX and the application(s) run faster, you can enable -all compiler optimizations. - -In addition, you can eliminate the ThreadX basic API error checking by -compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING -defined. - - -7. Interrupt Handling - -ThreadX provides complete and high-performance interrupt handling for Cortex-M33 -targets. There are a certain set of requirements that are defined in the -following sub-sections: - - -7.1 Vector Area - -The Cortex-M33 vectors start at the label __Vectors or similar. The application may modify -the vector area according to its needs. There is code in tx_initialize_low_level() that will -configure the vector base register. - - -7.2 Managed Interrupts - -ISRs can be written completely in C (or assembly language) without any calls to -_tx_thread_context_save or _tx_thread_context_restore. These ISRs are allowed access to the -ThreadX API that is available to ISRs. - -ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): - -void your_C_isr(void) -{ - - /* ISR processing goes here, including any needed function calls. */ -} - -ISRs written in assembly language will take the form: - - - .global your_assembly_isr - .thumb_func -your_assembly_isr: -; VOID your_assembly_isr(VOID) -; { - PUSH {r0, lr} -; -; /* Do interrupt handler work here */ -; /* BL */ - - POP {r0, lr} - BX lr -; } - -Note: the Cortex-M33 requires exception handlers to be thumb labels, this implies bit 0 set. -To accomplish this, the declaration of the label has to be preceded by the assembler directive -.thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to -be inserted in the correct location in the interrupt vector table. This table is typically -located in either your runtime startup file or in the tx_initialize_low_level.S file. - - -8. FPU Support - -ThreadX for Cortex-M33 supports automatic ("lazy") VFP support, which means that applications threads -can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread -context. - - -9. Revision History - -For generic code revision information, please refer to the readme_threadx_generic.txt -file, which is included in your distribution. The following details the revision -information associated with this specific port of ThreadX: - -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M33 using AC5 tools. - - -Copyright(c) 1996-2020 Microsoft Corporation - - -https://azure.com/rtos - diff --git a/ports/cortex_m33/ac5/src/tx_thread_interrupt_restore.s b/ports/cortex_m33/ac5/src/tx_thread_interrupt_restore.s deleted file mode 100644 index 9b83987c..00000000 --- a/ports/cortex_m33/ac5/src/tx_thread_interrupt_restore.s +++ /dev/null @@ -1,76 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M33/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_interrupt_restore -_tx_thread_interrupt_restore FUNCTION -; -; /* Restore previous interrupt lockout posture. */ -; - MSR PRIMASK, r0 - BX lr -; -;} - ENDFUNC - END diff --git a/ports/cortex_m33/ac5/src/tx_thread_schedule.s b/ports/cortex_m33/ac5/src/tx_thread_schedule.s deleted file mode 100644 index 55393cab..00000000 --- a/ports/cortex_m33/ac5/src/tx_thread_schedule.s +++ /dev/null @@ -1,341 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IMPORT _tx_thread_current_ptr - IMPORT _tx_thread_execute_ptr - IMPORT _tx_timer_time_slice - IMPORT _tx_thread_system_stack_ptr - IMPORT _tx_thread_preempt_disable - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY - IMPORT _tx_execution_thread_enter - IMPORT _tx_execution_thread_exit - ENDIF - - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: TX_SINGLE_MODE_NON_SECURE - IMPORT _tx_thread_secure_stack_context_restore - IMPORT _tx_thread_secure_stack_context_save - IMPORT _tx_thread_secure_mode_stack_allocate - IMPORT _tx_thread_secure_mode_stack_free - ENDIF -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M33/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_schedule -_tx_thread_schedule FUNCTION -; -; /* This function should only ever be called on Cortex-M -; from the first schedule request. Subsequent scheduling occurs -; from the PendSV handling routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 -; -; /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -; - IF {TARGET_FPU_VFP} = {TRUE} - MRS r0, CONTROL ; Pickup current CONTROL register - BIC r0, r0, #4 ; Clear the FPCA bit - MSR CONTROL, r0 ; Setup new CONTROL register - ENDIF -; -; /* Enable the interrupts */ -; - CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 - ENDFUNC -;} -; -; /* Generic context switching PendSV handler. */ -; - EXPORT PendSV_Handler -PendSV_Handler FUNCTION -; -; /* Get current thread value and new thread pointer. */ -; -__tx_ts_handler - - IF :DEF: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, lr} ; Recover LR - CPSIE i ; Enable interrupts - ENDIF - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers - IF {TARGET_FPU_VFP} = {TRUE} - TST LR, #0x10 ; Determine if the VFP extended frame is present - BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} ; Yes, save additional VFP registers -_skip_vfp_save - ENDIF - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack - STR r12, [r1, #8] ; Save the thread stack pointer - - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: TX_SINGLE_MODE_NON_SECURE - ; Save secure context - LDR r5, [r1,#0x90] ; 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 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. */ -; - STR r3, [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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 - - IF :DEF: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 :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: TX_SINGLE_MODE_NON_SECURE - ; Restore secure context - LDR r0, [r1,#0x90] ; 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. */ -; - LDR r12, [r1, #12] ; Get stack start - MSR PSPLIM, r12 ; Set stack limit - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR - IF {TARGET_FPU_VFP} = {TRUE} - TST LR, #0x10 ; Determine if the VFP extended frame is present - BNE _skip_vfp_restore ; If not, skip VFP restore - VLDMIA r12!, {s16-s31} ; Yes, restore additional VFP registers -_skip_vfp_restore - ENDIF - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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! - IF :DEF: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 - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread - ENDFUNC - - - - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: TX_SINGLE_MODE_NON_SECURE - ; SVC_Handler is not needed when ThreadX is running in single mode. - EXPORT SVC_Handler -SVC_Handler FUNCTION - TST lr, #0x04 ; Determine return stack from EXC_RETURN bit 2 - ITE EQ - 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 r1, [r1,#-2] ; 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 {r12,lr} ; Restore SP and EXC_RETURN - STR r0,[r12] ; Store function return value - 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 {r12,lr} ; Restore SP and EXC_RETURN - STR r0,[r12] ; Store function return value - BX lr - ENDFUNC - ENDIF ; End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE - - - EXPORT _tx_vfp_access -_tx_vfp_access FUNCTION - VMOV.F32 s0, s0 ; Simply access the VFP - BX lr ; Return to caller - ENDFUNC - - ALIGN - LTORG - END diff --git a/ports/cortex_m33/ac5/src/tx_thread_secure_stack.c b/ports/cortex_m33/ac5/src/tx_thread_secure_stack.c deleted file mode 100644 index fed7daca..00000000 --- a/ports/cortex_m33/ac5/src/tx_thread_secure_stack.c +++ /dev/null @@ -1,482 +0,0 @@ -/**************************************************************************/ -/* */ -/* 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 "ARMCM33_DSP_FP_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 - -/* 8 bytes added to stack size to "seal" stack. */ -#define TX_THREAD_STACK_SEAL_SIZE 8 -#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5 - -/* 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-M33/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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-M33/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* added stack sealing, */ -/* resulting in version 6.1.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; - - 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 & seal. */ - stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_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; - - /* Seal bottom of stack. */ - *(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE; - - /* Save info pointer in thread. */ - thread_ptr -> tx_thread_secure_stack_context = info_ptr; - - /* Check if this thread is running by looking at its stack start and PSPLIM_NS */ - if(((ULONG) thread_ptr -> tx_thread_stack_start & 0xFFFFFFF8) == __TZ_get_PSPLIM_NS()) - { - /* 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-M33/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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-M33/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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-M33/AC5 */ -/* 6.1.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 */ -/* 10-16-2020 Scott Larson Modified comment(s), */ -/* resulting in version 6.1.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 diff --git a/ports/cortex_m33/ac5/src/tx_thread_secure_stack_allocate.s b/ports/cortex_m33/ac5/src/tx_thread_secure_stack_allocate.s deleted file mode 100644 index f516bcd4..00000000 --- a/ports/cortex_m33/ac5/src/tx_thread_secure_stack_allocate.s +++ /dev/null @@ -1,83 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_secure_stack_allocate Cortex-M33/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_secure_stack_allocate -_tx_thread_secure_stack_allocate FUNCTION - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: 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 - MOV32 r0, #0xFF ; Feature not enabled - ENDIF -_alloc_return_interrupt_enabled - BX lr - ENDFUNC - - END diff --git a/ports/cortex_m33/ac5/src/tx_thread_secure_stack_free.s b/ports/cortex_m33/ac5/src/tx_thread_secure_stack_free.s deleted file mode 100644 index b0dc2312..00000000 --- a/ports/cortex_m33/ac5/src/tx_thread_secure_stack_free.s +++ /dev/null @@ -1,81 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_secure_stack_free Cortex-M33/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_secure_stack_free -_tx_thread_secure_stack_free FUNCTION - IF :LNOT::DEF: TX_SINGLE_MODE_SECURE :LAND: :LNOT::DEF: 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 - MOV32 r0, #0xFF ; Feature not enabled - ENDIF -_free_return_interrupt_enabled - BX lr - ENDFUNC - END - \ No newline at end of file diff --git a/ports/cortex_m33/ac5/src/tx_timer_interrupt.s b/ports/cortex_m33/ac5/src/tx_timer_interrupt.s deleted file mode 100644 index 7e2ce1a7..00000000 --- a/ports/cortex_m33/ac5/src/tx_timer_interrupt.s +++ /dev/null @@ -1,260 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IMPORT _tx_timer_time_slice - IMPORT _tx_timer_system_clock - IMPORT _tx_timer_current_ptr - IMPORT _tx_timer_list_start - IMPORT _tx_timer_list_end - IMPORT _tx_timer_expired_time_slice - IMPORT _tx_timer_expired - IMPORT _tx_thread_time_slice - IMPORT _tx_timer_expiration_process - IMPORT _tx_thread_preempt_disable - IMPORT _tx_thread_current_ptr - IMPORT _tx_thread_execute_ptr -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M33/AC5 */ -;/* 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 */ -;/* the expiration functions are called. */ -;/* */ -;/* 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) -;{ - EXPORT _tx_timer_interrupt -_tx_timer_interrupt FUNCTION -; -; /* 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++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock - LDR r0, [r1, #0] ; Pickup system clock - ADD r0, r0, #1 ; Increment system clock - STR r0, [r1, #0] ; Store new system clock -; -; /* Test for time-slice expiration. */ -; if (_tx_timer_time_slice) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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--; -; - SUB 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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++; -; - ADD r0, r0, #4 ; Move to next timer -; -; /* Check for wrap-around. */ -; if (_tx_timer_current_ptr == _tx_timer_list_end) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 -; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for - ; the 8-byte stack alignment -; -; } -; -__tx_timer_nothing_expired - - DSB ; Complete all memory access - BX lr ; Return to caller -; -;} - ENDFUNC - ALIGN - LTORG - END - diff --git a/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvoptx b/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvoptx index 0e0618f6..4b357786 100644 --- a/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvoptx +++ b/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvoptx @@ -2551,6 +2551,18 @@ 0 0 + + 1 + 199 + 2 + 0 + 0 + 0 + ..\src\tx_thread_secure_stack_initialize.S + tx_thread_secure_stack_initialize.S + 0 + 0 +
diff --git a/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvprojx b/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvprojx index 08ce8a59..469091b5 100644 --- a/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvprojx +++ b/ports/cortex_m33/ac6/example_build/ThreadX_Library.uvprojx @@ -1373,6 +1373,11 @@ 2 .\tx_initialize_low_level.S + + tx_thread_secure_stack_initialize.S + 2 + ..\src\tx_thread_secure_stack_initialize.S + diff --git a/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct b/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct index f1424c35..4f774274 100644 --- a/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct +++ b/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/ARMCM33_AC6.sct @@ -11,8 +11,8 @@ ; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> ; *----------------------------------------------------------------------------*/ -#define __ROM_BASE 0x00000000 -#define __ROM_SIZE 0x00200000 +#define __ROM_BASE 0x00000000 +#define __ROM_SIZE 0x00080000 /*--------------------- Embedded RAM Configuration --------------------------- ; RAM Configuration @@ -20,8 +20,8 @@ ; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> ; *----------------------------------------------------------------------------*/ -#define __RAM_BASE 0x20000000 -#define __RAM_SIZE 0x00020000 +#define __RAM_BASE 0x20000000 +#define __RAM_SIZE 0x00040000 /*--------------------- Stack / Heap Configuration --------------------------- ; Stack / Heap Configuration @@ -29,26 +29,29 @@ ; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> ; *----------------------------------------------------------------------------*/ -#define __STACK_SIZE 0x00000400 -#define __HEAP_SIZE 0x00000C00 +#define __STACK_SIZE 0x00000200 +#define __HEAP_SIZE 0x00000C00 + +/* +;------------- <<< end of configuration section >>> --------------------------- +*/ /*---------------------------------------------------------------------------- - User Stack & Heap boundery definition + User Stack & Heap boundary definition *----------------------------------------------------------------------------*/ -#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ -#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ +#define __STACK_TOP (__RAM_BASE + __RAM_SIZE) /* starts at end of RAM */ +#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ /*---------------------------------------------------------------------------- Scatter File Definitions definition *----------------------------------------------------------------------------*/ -#define __RO_BASE __ROM_BASE -#define __RO_SIZE __ROM_SIZE - -#define __RW_BASE (__RAM_BASE ) -#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) +#define __RO_BASE __ROM_BASE +#define __RO_SIZE __ROM_SIZE +#define __RW_BASE __RAM_BASE +#define __RW_SIZE (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE) LR_ROM __RO_BASE __RO_SIZE { ; load region size_region diff --git a/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c b/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c index 4fcc5dbc..4d09521f 100644 --- a/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c +++ b/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/startup_ARMCM33.c @@ -1,11 +1,11 @@ /****************************************************************************** * @file startup_ARMCM33.c * @brief CMSIS Core Device Startup File for Cortex-M33 Device - * @version V2.0.0 - * @date 20. May 2019 + * @version V2.0.3 + * @date 31. March 2020 ******************************************************************************/ /* - * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -34,31 +34,26 @@ #error device not specified! #endif -/*---------------------------------------------------------------------------- - Exception / Interrupt Handler Function Prototype - *----------------------------------------------------------------------------*/ -typedef void( *pFunc )( void ); - /*---------------------------------------------------------------------------- External References *----------------------------------------------------------------------------*/ extern uint32_t __INITIAL_SP; extern uint32_t __STACK_LIMIT; -extern void __PROGRAM_START(void) __NO_RETURN; +extern __NO_RETURN void __PROGRAM_START(void); /*---------------------------------------------------------------------------- Internal References *----------------------------------------------------------------------------*/ -void Default_Handler(void) __NO_RETURN; -void Reset_Handler (void) __NO_RETURN; +__NO_RETURN void Reset_Handler (void); + void Default_Handler(void); /*---------------------------------------------------------------------------- Exception / Interrupt Handler *----------------------------------------------------------------------------*/ /* Exceptions */ void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); -void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void HardFault_Handler (void) __attribute__ ((weak)); void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); @@ -83,9 +78,15 @@ void Interrupt9_Handler (void) __attribute__ ((weak, alias("Default_Handler" /*---------------------------------------------------------------------------- Exception / Interrupt Vector table *----------------------------------------------------------------------------*/ -extern const pFunc __VECTOR_TABLE[496]; - const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { - (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const VECTOR_TABLE_Type __VECTOR_TABLE[496]; + const VECTOR_TABLE_Type __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { + (VECTOR_TABLE_Type)(&__INITIAL_SP), /* Initial Stack Pointer */ Reset_Handler, /* Reset Handler */ NMI_Handler, /* -14 NMI Handler */ HardFault_Handler, /* -13 Hard Fault Handler */ @@ -116,13 +117,17 @@ extern const pFunc __VECTOR_TABLE[496]; /* Interrupts 10 .. 480 are left out */ }; +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + /* The linker will place this value at the bottom of the stack to seal the secure main stack. */ const int stack_seal __attribute__((section (".seal"))) = 0xFEF5EDA5; /*---------------------------------------------------------------------------- Reset Handler called on controller reset *----------------------------------------------------------------------------*/ -void Reset_Handler(void) +__NO_RETURN void Reset_Handler(void) { __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); @@ -130,6 +135,20 @@ void Reset_Handler(void) __PROGRAM_START(); /* Enter PreMain (C library entry point) */ } + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wmissing-noreturn" +#endif + +/*---------------------------------------------------------------------------- + Hard Fault Handler + *----------------------------------------------------------------------------*/ +void HardFault_Handler(void) +{ + while(1); +} + /*---------------------------------------------------------------------------- Default Handler for Exceptions / Interrupts *----------------------------------------------------------------------------*/ @@ -137,3 +156,8 @@ void Default_Handler(void) { while(1); } + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop +#endif + diff --git a/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c b/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c index 36cb0c63..2df478ae 100644 --- a/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c +++ b/ports/cortex_m33/ac6/example_build/demo_secure_zone/RTE/Device/ARMCM33_DSP_FP_TZ/system_ARMCM33.c @@ -2,11 +2,11 @@ * @file system_ARMCM33.c * @brief CMSIS Device System Source File for * ARMCM33 Device - * @version V5.3.1 - * @date 09. July 2018 + * @version V1.0.1 + * @date 15. November 2019 ******************************************************************************/ /* - * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -50,13 +50,11 @@ #define SYSTEM_CLOCK (XTAL / 2U) - /*---------------------------------------------------------------------------- - Externals + Exception / Interrupt Vector table *----------------------------------------------------------------------------*/ -#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - extern uint32_t __Vectors; -#endif +extern const VECTOR_TABLE_Type __VECTOR_TABLE[496]; + /*---------------------------------------------------------------------------- System Core Clock Variable @@ -79,7 +77,7 @@ void SystemInit (void) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) - SCB->VTOR = (uint32_t) &__Vectors; + SCB->VTOR = (uint32_t) &(__VECTOR_TABLE[0]); #endif #if defined (__FPU_USED) && (__FPU_USED == 1U) diff --git a/ports/cortex_m33/ac6/inc/tx_port.h b/ports/cortex_m33/ac6/inc/tx_port.h index c53e8b37..7fdcb011 100644 --- a/ports/cortex_m33/ac6/inc/tx_port.h +++ b/ports/cortex_m33/ac6/inc/tx_port.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M33/AC6 */ -/* 6.1.5 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ @@ -51,6 +51,11 @@ /* 03-02-2021 Scott Larson Modified comment(s), added */ /* ULONG64_DEFINED, */ /* resulting in version 6.1.5 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), removed */ +/* unneeded header file, */ +/* added symbol to enable */ +/* stack error handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -71,7 +76,6 @@ #include #include #include -#include "ARMCM33_DSP_FP_TZ.h" /* For intrinsic functions. */ /* Define ThreadX basic types for this port. */ @@ -94,6 +98,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" @@ -229,14 +239,14 @@ ULONG _tx_misra_time_stamp_get(VOID); for the multiple macros is so that backward compatibility can be maintained with existing ThreadX kernel awareness modules. */ -#define TX_THREAD_EXTENSION_0 -#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 #if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) #define TX_THREAD_EXTENSION_2 VOID *tx_thread_secure_stack_context; #else -#define TX_THREAD_EXTENSION_2 +#define TX_THREAD_EXTENSION_2 #endif -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_3 /* Define the port extensions of the remaining ThreadX objects. */ @@ -485,7 +495,7 @@ extern void _tx_thread_secure_stack_initialize(void); #ifndef TX_DISABLE_INLINE -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__clz(__rbit((m))); +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); #endif @@ -539,7 +549,7 @@ unsigned int was_masked; #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33/AC6 Version 6.1 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33/AC6 Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -548,8 +558,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif - - - diff --git a/ports/cortex_m33/ac6/readme_threadx.txt b/ports/cortex_m33/ac6/readme_threadx.txt index e9a434ad..9311ffd4 100644 --- a/ports/cortex_m33/ac6/readme_threadx.txt +++ b/ports/cortex_m33/ac6/readme_threadx.txt @@ -205,6 +205,12 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +06-02-2021 Release 6.1.7 changes: + tx_port.h Remove unneeded include file + tx_thread_secure_stack_initialize.S New file + tx_thread_schedule.S Added secure stack initialize to SVC hander + tx_thread_secure_stack.c Fixed stack pointer save, initialize in handler mode + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition tx_thread_schedule.s Added low power support diff --git a/ports/cortex_m33/ac6/src/tx_thread_context_restore.S b/ports/cortex_m33/ac6/src/tx_thread_context_restore.S index 26e64ab4..a148559a 100644 --- a/ports/cortex_m33/ac6/src/tx_thread_context_restore.S +++ b/ports/cortex_m33/ac6/src/tx_thread_context_restore.S @@ -19,6 +19,9 @@ /** */ /**************************************************************************/ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif /**************************************************************************/ @@ -68,7 +71,14 @@ .thumb_func .type _tx_thread_context_restore, function _tx_thread_context_restore: - /* Just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr // } .end diff --git a/ports/cortex_m33/ac6/src/tx_thread_context_save.S b/ports/cortex_m33/ac6/src/tx_thread_context_save.S index 2d2314fb..90c8e61a 100644 --- a/ports/cortex_m33/ac6/src/tx_thread_context_save.S +++ b/ports/cortex_m33/ac6/src/tx_thread_context_save.S @@ -21,6 +21,9 @@ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_enter +#endif /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -68,7 +71,16 @@ .thumb_func .type _tx_thread_context_save, function _tx_thread_context_save: - /* Return to interrupt processing. */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr // } .end diff --git a/ports/cortex_m33/ac6/src/tx_thread_schedule.S b/ports/cortex_m33/ac6/src/tx_thread_schedule.S index 1f50c8bc..e0c71318 100644 --- a/ports/cortex_m33/ac6/src/tx_thread_schedule.S +++ b/ports/cortex_m33/ac6/src/tx_thread_schedule.S @@ -21,6 +21,10 @@ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit +#endif /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -62,6 +66,9 @@ /* 04-02-2021 Scott Larson Modified comment(s), added */ /* low power code, */ /* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Added secure stack initialize */ +/* in SVC handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -83,9 +90,8 @@ _tx_thread_schedule: LDR r2, =_tx_thread_preempt_disable // Build address of preempt disable flag STR r0, [r2, #0] // Clear preempt disable flag - /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ - #ifdef __ARM_PCS_VFP + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ MRS r0, CONTROL // Pickup current CONTROL register BIC r0, r0, #4 // Clear the FPCA bit MSR CONTROL, r0 // Setup new CONTROL register @@ -121,10 +127,8 @@ __tx_wait_here: PendSV_Handler: __tx_ts_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 PUSH {r0, lr} // Save LR (and r0 just for alignment) BL _tx_execution_thread_exit // Call the thread exit function @@ -207,11 +211,11 @@ __tx_ts_restore: STR r5, [r4] // Setup global time-slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) /* Call the thread entry function to indicate the thread is executing. */ - PUSH {r0, r1} // Save r0/r1 + PUSH {r0, r1} // Save r0 and r1 BL _tx_execution_thread_enter // Call the thread execution enter function - POP {r0, r1} // Recover r0/r1 + POP {r0, r1} // Recover r0 and r1 #endif #if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) @@ -308,6 +312,9 @@ SVC_Handler: CMP r1, #2 // Is it a secure stack free request? BEQ _tx_svc_secure_free // Yes, go there + + CMP r1, #3 // Is it a secure stack init request? + BEQ _tx_svc_secure_init // Yes, go there // Unknown SVC argument - just return BX lr @@ -326,7 +333,12 @@ _tx_svc_secure_free: POP {r12,lr} // Restore SP and EXC_RETURN STR r0,[r12] // Store function return value BX lr -#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE +_tx_svc_secure_init: + PUSH {r0,lr} // Save SP and EXC_RETURN + BL _tx_thread_secure_mode_stack_initialize + POP {r12,lr} // Restore SP and EXC_RETURN + BX lr +#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE .section .text diff --git a/ports/cortex_m33/ac6/src/tx_thread_secure_stack.c b/ports/cortex_m33/ac6/src/tx_thread_secure_stack.c index e66a7bf1..e8edd2f5 100644 --- a/ports/cortex_m33/ac6/src/tx_thread_secure_stack.c +++ b/ports/cortex_m33/ac6/src/tx_thread_secure_stack.c @@ -62,8 +62,8 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_secure_stack_initialize Cortex-M33/AC6 */ -/* 6.1.1 */ +/* _tx_thread_secure_mode_stack_initialize Cortex-M33/AC6 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -78,7 +78,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* OUTPUT */ /* */ -/* None */ +/* status */ /* */ /* CALLS */ /* */ @@ -98,21 +98,35 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Modified comment(s), and */ +/* changed name, execute in */ +/* handler mode, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) -void _tx_thread_secure_stack_initialize(void) +UINT _tx_thread_secure_mode_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; +UINT status; + + /* Make sure function is called from interrupt (threads should not call). */ + if (__get_IPSR() == 0) + { + status = TX_CALLER_ERROR; + } + else + { + /* 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); + + status = TX_SUCCESS; + } + return status; } @@ -332,7 +346,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M33/AC6 */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -367,6 +381,8 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -399,7 +415,7 @@ ULONG sp; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports/cortex_m33/ac6/src/tx_thread_secure_stack_initialize.S b/ports/cortex_m33/ac6/src/tx_thread_secure_stack_initialize.S new file mode 100644 index 00000000..4baf378a --- /dev/null +++ b/ports/cortex_m33/ac6/src/tx_thread_secure_stack_initialize.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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_initialize Cortex-M33/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enters the SVC handler to initialize a secure stack. */ +/* */ +/* INPUT */ +/* */ +/* none */ +/* */ +/* OUTPUT */ +/* */ +/* none */ +/* */ +/* CALLS */ +/* */ +/* SVC 3 */ +/* */ +/* CALLED BY */ +/* */ +/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_secure_stack_initialize(VOID) +// { + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global _tx_thread_secure_stack_initialize + .thumb_func +.type _tx_thread_secure_stack_initialize, function +_tx_thread_secure_stack_initialize: +#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) + CPSIE i // Enable interrupts for SVC call + SVC 3 + CPSID i // Disable interrupts +#else + MOV r0, #0xFF // Feature not enabled +#endif + BX lr + .end diff --git a/ports/cortex_m33/gnu/inc/tx_port.h b/ports/cortex_m33/gnu/inc/tx_port.h index 653be90e..4d6ff5cf 100644 --- a/ports/cortex_m33/gnu/inc/tx_port.h +++ b/ports/cortex_m33/gnu/inc/tx_port.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M33/GNU */ -/* 6.1.5 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ @@ -51,6 +51,12 @@ /* 03-02-2021 Scott Larson Modified comment(s), added */ /* ULONG64_DEFINED, */ /* resulting in version 6.1.5 */ +/* 06-02-2021 Scott Larson Modified comment(s), changed */ +/* set_control and get_control */ +/* to be inline functions, */ +/* added symbol to enable */ +/* stack error handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -92,6 +98,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" @@ -302,16 +314,16 @@ void _tx_misra_vfp_touch(void); #ifdef TX_SOURCE_CODE -static unsigned int _get_control(void); -static unsigned int _get_control(void) +static inline unsigned int _get_control(void); +static inline unsigned int _get_control(void) { unsigned int _control; __asm("MRS %[result], control" : [result] "=r" (_control) : ); return _control; } -static void _set_control(unsigned int _control); -static void _set_control(unsigned int _control) +static inline void _set_control(unsigned int _control); +static inline void _set_control(unsigned int _control) { __asm("MSR control, %[input]" : : [input] "r" (_control)); } @@ -570,7 +582,7 @@ unsigned int interrupt_save; #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33/GNU Version 6.1 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33/GNU Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; diff --git a/ports/cortex_m33/gnu/readme_threadx.txt b/ports/cortex_m33/gnu/readme_threadx.txt index 51ab47f0..c7d5774e 100644 --- a/ports/cortex_m33/gnu/readme_threadx.txt +++ b/ports/cortex_m33/gnu/readme_threadx.txt @@ -188,6 +188,11 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +06-02-2021 Release 6.1.7 changes: + tx_thread_secure_stack_initialize.S New file + tx_thread_schedule.S Added secure stack initialize to SVC hander + tx_thread_secure_stack.c Fixed stack pointer save, initialize in handler mode + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition tx_thread_schedule.s Added low power support diff --git a/ports/cortex_m33/gnu/src/tx_thread_context_restore.S b/ports/cortex_m33/gnu/src/tx_thread_context_restore.S index 0cf97109..ab7931d0 100644 --- a/ports/cortex_m33/gnu/src/tx_thread_context_restore.S +++ b/ports/cortex_m33/gnu/src/tx_thread_context_restore.S @@ -19,6 +19,9 @@ /** */ /**************************************************************************/ /**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif /**************************************************************************/ @@ -68,7 +71,14 @@ .thumb_func .type _tx_thread_context_restore, function _tx_thread_context_restore: - /* Just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr // } .end diff --git a/ports/cortex_m33/gnu/src/tx_thread_context_save.S b/ports/cortex_m33/gnu/src/tx_thread_context_save.S index 29c21b85..0f76ccaa 100644 --- a/ports/cortex_m33/gnu/src/tx_thread_context_save.S +++ b/ports/cortex_m33/gnu/src/tx_thread_context_save.S @@ -68,7 +68,16 @@ .thumb_func .type _tx_thread_context_save, function _tx_thread_context_save: - /* Return to interrupt processing. */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr // } .end diff --git a/ports/cortex_m33/gnu/src/tx_thread_schedule.S b/ports/cortex_m33/gnu/src/tx_thread_schedule.S index e88d6897..31da6fc8 100644 --- a/ports/cortex_m33/gnu/src/tx_thread_schedule.S +++ b/ports/cortex_m33/gnu/src/tx_thread_schedule.S @@ -62,6 +62,9 @@ /* 04-02-2021 Scott Larson Modified comment(s), added */ /* low power code, */ /* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Added secure stack initialize */ +/* in SVC handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -83,9 +86,8 @@ _tx_thread_schedule: LDR r2, =_tx_thread_preempt_disable // Build address of preempt disable flag STR r0, [r2, #0] // Clear preempt disable flag - /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ - #ifdef __ARM_PCS_VFP + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ MRS r0, CONTROL // Pickup current CONTROL register BIC r0, r0, #4 // Clear the FPCA bit MSR CONTROL, r0 // Setup new CONTROL register @@ -121,10 +123,8 @@ __tx_wait_here: PendSV_Handler: __tx_ts_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 PUSH {r0, lr} // Save LR (and r0 just for alignment) BL _tx_execution_thread_exit // Call the thread exit function @@ -207,11 +207,11 @@ __tx_ts_restore: STR r5, [r4] // Setup global time-slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) /* Call the thread entry function to indicate the thread is executing. */ - PUSH {r0, r1} // Save r0/r1 + PUSH {r0, r1} // Save r0 and r1 BL _tx_execution_thread_enter // Call the thread execution enter function - POP {r0, r1} // Recover r0/r1 + POP {r0, r1} // Recover r0 and r1 #endif #if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) @@ -308,6 +308,9 @@ SVC_Handler: CMP r1, #2 // Is it a secure stack free request? BEQ _tx_svc_secure_free // Yes, go there + + CMP r1, #3 // Is it a secure stack init request? + BEQ _tx_svc_secure_init // Yes, go there // Unknown SVC argument - just return BX lr @@ -326,7 +329,12 @@ _tx_svc_secure_free: POP {r12,lr} // Restore SP and EXC_RETURN STR r0,[r12] // Store function return value BX lr -#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE +_tx_svc_secure_init: + PUSH {r0,lr} // Save SP and EXC_RETURN + BL _tx_thread_secure_mode_stack_initialize + POP {r12,lr} // Restore SP and EXC_RETURN + BX lr +#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE .section .text diff --git a/ports/cortex_m33/gnu/src/tx_thread_secure_stack.c b/ports/cortex_m33/gnu/src/tx_thread_secure_stack.c index 396aefb3..f1b7e8d5 100644 --- a/ports/cortex_m33/gnu/src/tx_thread_secure_stack.c +++ b/ports/cortex_m33/gnu/src/tx_thread_secure_stack.c @@ -61,8 +61,8 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_secure_stack_initialize Cortex-M33/GNU */ -/* 6.1.1 */ +/* _tx_thread_secure_mode_stack_initialize Cortex-M33/GNU */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -77,7 +77,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* OUTPUT */ /* */ -/* None */ +/* status */ /* */ /* CALLS */ /* */ @@ -97,24 +97,40 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Change name, execute in */ +/* handler mode, */ +/* disable optimizations, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ -__attribute__((cmse_nonsecure_entry)) -void _tx_thread_secure_stack_initialize(void) +__attribute__((cmse_nonsecure_entry, optimize(0))) +UINT _tx_thread_secure_mode_stack_initialize(void) { - ULONG control; - - /* Set secure mode to use PSP. */ - asm volatile("MRS %0, CONTROL" : "=r" (control)); /* Get CONTROL register. */ - control |= 2; /* Use PSP. */ - asm volatile("MSR CONTROL, %0" :: "r" (control)); /* Set CONTROL register. */ - - /* 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. */ - asm volatile("MSR PSPLIM, %0" :: "r" (0)); - asm volatile("MSR PSP, %0" :: "r" (0)); - - return; +UINT status; +ULONG control; +ULONG ipsr; + + /* Make sure function is called from interrupt (threads should not call). */ + asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */ + if (ipsr == 0) + { + status = TX_CALLER_ERROR; + } + else + { + /* Set secure mode to use PSP. */ + asm volatile("MRS %0, CONTROL" : "=r" (control)); /* Get CONTROL register. */ + control |= 2; /* Use PSP. */ + asm volatile("MSR CONTROL, %0" :: "r" (control)); /* Set CONTROL register. */ + + /* 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. */ + asm volatile("MSR PSPLIM, %0" :: "r" (0)); + asm volatile("MSR PSP, %0" :: "r" (0)); + + status = TX_SUCCESS; + } + return status; } @@ -339,7 +355,7 @@ ULONG ipsr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M33/GNU */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -374,6 +390,8 @@ ULONG ipsr; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -408,7 +426,7 @@ ULONG ipsr; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports/cortex_m33/gnu/src/tx_thread_secure_stack_initialize.S b/ports/cortex_m33/gnu/src/tx_thread_secure_stack_initialize.S new file mode 100644 index 00000000..9e9642fc --- /dev/null +++ b/ports/cortex_m33/gnu/src/tx_thread_secure_stack_initialize.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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_initialize Cortex-M33/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enters the SVC handler to initialize a secure stack. */ +/* */ +/* INPUT */ +/* */ +/* none */ +/* */ +/* OUTPUT */ +/* */ +/* none */ +/* */ +/* CALLS */ +/* */ +/* SVC 3 */ +/* */ +/* CALLED BY */ +/* */ +/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_secure_stack_initialize(VOID) +// { + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global _tx_thread_secure_stack_initialize + .thumb_func +.type _tx_thread_secure_stack_initialize, function +_tx_thread_secure_stack_initialize: +#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) + CPSIE i // Enable interrupts for SVC call + SVC 3 + CPSID i // Disable interrupts +#else + MOV r0, #0xFF // Feature not enabled +#endif + BX lr + .end diff --git a/ports/cortex_m33/iar/inc/tx_port.h b/ports/cortex_m33/iar/inc/tx_port.h index d0ff11ce..afbe0643 100644 --- a/ports/cortex_m33/iar/inc/tx_port.h +++ b/ports/cortex_m33/iar/inc/tx_port.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M33/IAR */ -/* 6.1.5 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ @@ -51,6 +51,10 @@ /* 03-02-2021 Scott Larson Modified comment(s), added */ /* ULONG64_DEFINED, */ /* resulting in version 6.1.5 */ +/* 06-02-2021 Yuxin Zhou Modified comment(s), and */ +/* added symbol to enable */ +/* stack error handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -97,6 +101,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" @@ -258,14 +268,7 @@ ULONG _tx_misra_time_stamp_get(VOID); #endif - -#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 -#else -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; -#endif - /* Define the port extensions of the remaining ThreadX objects. */ @@ -504,12 +507,6 @@ extern void _tx_thread_secure_stack_initialize(void); is used to define a local function save area for the disable and restore macros. */ -/* The embedded assembler blocks are design so as to be inlinable by the - armlink linker inlining. This requires them to consist of either a - single 32-bit instruction, or either one or two 16-bit instructions - followed by a "BX lr". Note that to reduce the critical region size, the - 16-bit "CPSID i" instruction is preceeded by a 16-bit NOP */ - #ifdef TX_DISABLE_INLINE UINT _tx_thread_interrupt_disable(VOID); @@ -560,7 +557,7 @@ __istate_t interrupt_save; #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33/IAR Version 6.1 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33/IAR Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -569,8 +566,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif - - - diff --git a/ports/cortex_m33/iar/readme_threadx.txt b/ports/cortex_m33/iar/readme_threadx.txt index 73895476..7758306e 100644 --- a/ports/cortex_m33/iar/readme_threadx.txt +++ b/ports/cortex_m33/iar/readme_threadx.txt @@ -199,6 +199,11 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +06-02-2021 Release 6.1.7 changes: + tx_thread_secure_stack_initialize.s New file + tx_thread_schedule.s Added secure stack initialize to SVC hander + tx_thread_secure_stack.c Fixed stack pointer save, initialize in handler mode + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition tx_thread_schedule.s Added low power support diff --git a/ports/cortex_m33/iar/src/tx_thread_schedule.s b/ports/cortex_m33/iar/src/tx_thread_schedule.s index a00e03d3..d9accd71 100644 --- a/ports/cortex_m33/iar/src/tx_thread_schedule.s +++ b/ports/cortex_m33/iar/src/tx_thread_schedule.s @@ -1,26 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_timer_time_slice @@ -32,320 +31,313 @@ EXTERN _tx_thread_secure_stack_context_save EXTERN _tx_thread_secure_mode_stack_allocate EXTERN _tx_thread_secure_mode_stack_free + EXTERN _tx_thread_secure_mode_stack_initialize #ifdef TX_LOW_POWER EXTERN tx_low_power_enter EXTERN tx_low_power_exit #endif -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M33/IAR */ -;/* 6.1.6 */ -;/* 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 */ -;/* 04-02-2021 Scott Larson Modified comment(s), added */ -;/* low power code, */ -;/* resulting in version 6.1.6 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_schedule(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M33/IAR */ +/* 6.1.7 */ +/* 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 */ +/* 04-02-2021 Scott Larson Modified comment(s), added */ +/* low power code, */ +/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Added secure stack initialize */ +/* in SVC handler, */ +/* resulting in version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { PUBLIC _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 -; -; /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -; + /* 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. */ + MOV 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 + #ifdef __ARMVFP__ - MRS r0, CONTROL ; Pickup current CONTROL register - BIC r0, r0, #4 ; Clear the FPCA bit - MSR CONTROL, r0 ; Setup new CONTROL register + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register #endif -; -; /* Enable interrupts */ -; + + /* Enable interrupts */ CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR - DSB ; Complete all memory accesses - ISB ; Flush pipeline -; -; /* Wait here for the PendSV to take place. */ -; + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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. */ -; + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + PUBLIC PendSV_Handler PendSV_Handler: -; -; /* Get current thread value and new thread pointer. */ -; __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, lr} ; Recover LR - CPSIE i ; Enable interrupts + /* 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, lr} // Recover LR + CPSIE i // Enable interrupts #endif - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers #ifdef __ARMVFP__ - TST LR, #0x10 ; Determine if the VFP extended frame is present + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} ; Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save: #endif - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack - STR r12, [r1, #8] ; Save the thread stack pointer + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack + STR r12, [r1, #8] // Save the thread stack pointer -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) - ; Save secure context - LDR r5, [r1,#0x90] ; 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 +#if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) + // Save secure context + LDR r5, [r1,#0x90] // 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 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. */ -; - STR r3, [r4] ; Clear time-slice -; -; /* Executing thread is now completely preserved!!! */ -; + + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + 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. */ + + STR r3, [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. */ -; + + /* 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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 + LDR r7, [r1, #4] // Pickup the current thread run count + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 #endif -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) - ; Restore secure context - LDR r0, [r1,#0x90] ; 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) +#if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) + // Restore secure context + LDR r0, [r1,#0x90] // 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. */ -; - LDR r12, [r1, #12] ; Get stack start - MSR PSPLIM, r12 ; Set stack limit - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR + /* Restore the thread context and PSP. */ + LDR r12, [r1, #12] // Get stack start + MSR PSPLIM, r12 // Set stack limit + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR #ifdef __ARMVFP__ - TST LR, #0x10 ; Determine if the VFP extended frame is present - BNE _skip_vfp_restore ; If not, skip VFP restore - VLDMIA r12!, {s16-s31} ; Yes, restore additional VFP registers + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore: #endif - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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. */ -; + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode + BL tx_low_power_enter // Possibly enter low power mode POP {r0-r3} #endif #ifdef TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode + BL tx_low_power_exit // Exit low power mode POP {r0-r3} #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! */ -; + 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: - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // 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. +#if (!defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)) + // SVC_Handler is not needed when ThreadX is running in single mode. PUBLIC SVC_Handler SVC_Handler: - TST lr, #0x04 ; Determine return stack from EXC_RETURN bit 2 + TST lr, #0x04 // Determine return stack from EXC_RETURN bit 2 ITE EQ - MRSEQ r0, MSP ; Get MSP if return stack is MSP - MRSNE r0, PSP ; Get PSP if return stack is 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 r1, [r1,#-2] ; Load SVC number + LDR r1, [r0,#24] // Load saved PC from stack + LDRB r1, [r1,#-2] // Load SVC number - CMP r1, #1 ; Is it a secure stack allocate request? - BEQ _tx_svc_secure_alloc ; Yes, go there + 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 + CMP r1, #2 // Is it a secure stack free request? + BEQ _tx_svc_secure_free // Yes, go there + + CMP r1, #3 // Is it a secure stack init request? + BEQ _tx_svc_secure_init // Yes, go there - ; Unknown SVC argument - just return + // 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 + 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 {r12,lr} ; Restore SP and EXC_RETURN - STR r0,[r12] ; Store function return value + POP {r12,lr} // Restore SP and EXC_RETURN + STR r0,[r12] // Store function return value BX lr _tx_svc_secure_free: - PUSH {r0,lr} ; Save SP and EXC_RETURN - LDM r0, {r0-r3} ; Load function parameters from stack + 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 {r12,lr} ; Restore SP and EXC_RETURN - STR r0,[r12] ; Store function return value + POP {r12,lr} // Restore SP and EXC_RETURN + STR r0,[r12] // Store function return value BX lr -#endif ; End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE +_tx_svc_secure_init: + PUSH {r0,lr} // Save SP and EXC_RETURN + BL _tx_thread_secure_mode_stack_initialize + POP {r12,lr} // Restore SP and EXC_RETURN + BX lr +#endif // End of ifndef TX_SINGLE_MODE_SECURE, TX_SINGLE_MODE_NON_SECURE PUBLIC _tx_vfp_access _tx_vfp_access: - VMOV.F32 s0, s0 ; Simply access the VFP - BX lr ; Return to caller + VMOV.F32 s0, s0 // Simply access the VFP + BX lr // Return to caller END diff --git a/ports/cortex_m33/iar/src/tx_thread_secure_stack.c b/ports/cortex_m33/iar/src/tx_thread_secure_stack.c index d790bca0..ab9fdedc 100644 --- a/ports/cortex_m33/iar/src/tx_thread_secure_stack.c +++ b/ports/cortex_m33/iar/src/tx_thread_secure_stack.c @@ -62,8 +62,8 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_secure_stack_initialize Cortex-M33/IAR */ -/* 6.1.1 */ +/* _tx_thread_secure_mode_stack_initialize Cortex-M33/IAR */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -78,7 +78,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* */ /* OUTPUT */ /* */ -/* None */ +/* status */ /* */ /* CALLS */ /* */ @@ -98,21 +98,34 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Change name, execute in */ +/* handler mode, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) -void _tx_thread_secure_stack_initialize(void) +UINT _tx_thread_secure_mode_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; +UINT status; + + /* Make sure function is called from interrupt (threads should not call). */ + if (__get_IPSR() == 0) + { + status = TX_CALLER_ERROR; + } + else + { + /* 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); + + status = TX_SUCCESS; + } + return status; } @@ -332,7 +345,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M33/IAR */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -367,6 +380,8 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -399,7 +414,7 @@ ULONG sp; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports/cortex_m33/iar/src/tx_thread_secure_stack_initialize.s b/ports/cortex_m33/iar/src/tx_thread_secure_stack_initialize.s new file mode 100644 index 00000000..69e84264 --- /dev/null +++ b/ports/cortex_m33/iar/src/tx_thread_secure_stack_initialize.s @@ -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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + SECTION `.text`:CODE:NOROOT(2) + THUMB +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_secure_stack_initialize Cortex-M33/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enters the SVC handler to initialize a secure stack. */ +/* */ +/* INPUT */ +/* */ +/* none */ +/* */ +/* OUTPUT */ +/* */ +/* none */ +/* */ +/* CALLS */ +/* */ +/* SVC 3 */ +/* */ +/* CALLED BY */ +/* */ +/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_secure_stack_initialize(VOID) +// { + EXPORT _tx_thread_secure_stack_initialize +_tx_thread_secure_stack_initialize: +#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) + CPSIE i // Enable interrupts for SVC call + SVC 3 + CPSID i // Disable interrupts +#else + MOV r0, #0xFF // Feature not enabled +#endif + BX lr + END diff --git a/ports/cortex_m4/ac5/inc/tx_port.h b/ports/cortex_m4/ac5/inc/tx_port.h index f4099d25..0790cd54 100644 --- a/ports/cortex_m4/ac5/inc/tx_port.h +++ b/ports/cortex_m4/ac5/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M4/AC5 */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,7 +156,7 @@ typedef unsigned short USHORT; #ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -144,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -162,7 +199,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 @@ -176,13 +213,24 @@ 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -196,11 +244,11 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -208,18 +256,28 @@ ULONG _tx_misra_time_stamp_get(VOID); tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - - -#ifndef TX_MISRA_ENABLE - -register unsigned int _ipsr __asm("ipsr"); +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __TARGET_FPU_VFP +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,35 +286,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -#ifdef TX_SOURCE_CODE +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ -register ULONG _control __asm("control"); +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ -#endif -#endif /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -266,78 +360,76 @@ register ULONG _control __asm("control"); #ifndef TX_MISRA_ENABLE -void _tx_vfp_access(void); - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_vfp_access(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -362,16 +454,38 @@ void _tx_vfp_access(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -380,35 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -#ifdef TX_DISABLE_INLINE +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -416,37 +684,11 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); - -#define _tx_thread_system_return _tx_thread_system_return_inline +#endif /* TX_DISABLE_INLINE */ -static void _tx_thread_system_return_inline(void) -{ -unsigned int was_masked; - - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (_ipsr == 0) - { - was_masked = __disable_irq(); - __enable_irq(); - if (was_masked != 0) - __disable_irq(); - } -} -#endif - - -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. 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); @@ -456,8 +698,8 @@ void tx_thread_fpu_disable(void); /* 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-M4/AC5 Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/AC5 Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -468,7 +710,3 @@ extern CHAR _tx_version_id[]; #endif - - - - diff --git a/ports/cortex_m4/ac5/readme_threadx.txt b/ports/cortex_m4/ac5/readme_threadx.txt index 7b91d12a..b7b7cee9 100644 --- a/ports/cortex_m4/ac5/readme_threadx.txt +++ b/ports/cortex_m4/ac5/readme_threadx.txt @@ -1,15 +1,14 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M4 - - Using ARM Compiler 5 (AC5) + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using ARM Compiler 5 (AC5) 1. Building the ThreadX run-time Library -First make sure you are in the "example_build" directory. Also, make sure that +Navigate to the "example_build" directory. Ensure that you have setup your path and other environment variables necessary for the AC5 -development environment. At this point you may run the build_threadx.bat batch -file. This will build the ThreadX run-time environment in the "example_build" -directory. +compiler. At this point you may run the build_threadx.bat batch file. This will +build the ThreadX run-time environment in the "example_build" directory. You should observe assembly and compilation of a series of ThreadX source files. At the end of the batch file, they are all combined into the @@ -19,20 +18,21 @@ application in order to use ThreadX. 2. Demonstration System -The ThreadX demonstration is designed to execute under the ARM -Windows-based simulator. +The ThreadX demonstration is designed to execute under the ARM DS Cortex-M +simulator. Building the demonstration is easy; simply execute the build_threadx_sample.bat -batch file while inside the "example_build" directory. +batch file while inside the "example_build" directory. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.axf -is a binary file that can be downloaded and executed on the ARM simulator. +is a binary file that can be downloaded and executed on the ARM DS Cortex-M +simulator. 3. System Initialization -The entry point in ThreadX for the Cortex-M4 using AC5 tools is at label +The entry point in ThreadX for the Cortex-M using AC5 tools is at label __main. This is defined within the AC5 compiler's startup code. In addition, this is where all static and global pre-set C variable initialization processing takes place. @@ -50,7 +50,7 @@ parameter to your application definition function, tx_application_define. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M4 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. @@ -58,7 +58,7 @@ Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -80,7 +80,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -137,8 +137,8 @@ FPU Stack Frame (only interrupted thread with FPU enabled): The distribution version of ThreadX is built without any compiler optimizations. This makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. Of course, this costs some -performance. To make it run faster, you can change the ThreadX_Library.Uv2 -project to debugging and enable all compiler optimizations. +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING @@ -147,14 +147,14 @@ defined. 6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M4 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: 6.1 Vector Area -The Cortex-M4 vectors start at the label __tx_vectors. The application may modify +The Cortex-M vectors start at the label __tx_vectors. The application may modify the vector area according to its needs. @@ -187,29 +187,21 @@ your_assembly_isr 7. FPU Support -ThreadX for Cortex-M4 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread context - no additional setup by the application. - 8. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - tx_thread_schedule.s Fix compilation error - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M4 using AC5 tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using AC5 tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m4/ac5/src/tx_thread_context_restore.s b/ports/cortex_m4/ac5/src/tx_thread_context_restore.s index 0ed36142..7fbd5068 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_context_restore.s +++ b/ports/cortex_m4/ac5/src/tx_thread_context_restore.s @@ -1,91 +1,83 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_exit - ENDIF -; -; +#endif + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function restores the interrupt context if it is processing a */ -;/* nested interrupt. If not, it returns to the interrupt thread if no */ -;/* preemption is necessary. Otherwise, if preemption is necessary or */ -;/* if no thread was running, the function returns to the scheduler. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* _tx_thread_schedule Thread scheduling routine */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs Interrupt Service Routines */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_restore(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M4/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { EXPORT _tx_thread_context_restore _tx_thread_context_restore - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR exit function to indicate an ISR is complete. */ -; - PUSH {r0,lr} ; Save ISR lr - BL _tx_execution_isr_exit ; Call the ISR exit function - POP {r0,lr} ; Restore ISR lr - ENDIF -; - POP {lr} + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -;} +// } ALIGN LTORG END diff --git a/ports/cortex_m4/ac5/src/tx_thread_context_save.s b/ports/cortex_m4/ac5/src/tx_thread_context_save.s index 03ec67e6..b922b93f 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_context_save.s +++ b/ports/cortex_m4/ac5/src/tx_thread_context_save.s @@ -1,91 +1,85 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_enter - ENDIF -; -; +#endif + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_save Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function saves the context of an executing thread in the */ -;/* beginning of interrupt processing. The function also ensures that */ -;/* the system stack is used upon return to the calling ISR. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* None */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M4/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { EXPORT _tx_thread_context_save _tx_thread_context_save - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR enter function to indicate an ISR is executing. */ -; - PUSH {r0, lr} ; Save ISR lr - BL _tx_execution_isr_enter ; Call the ISR enter function - POP {r0, lr} ; Recover ISR lr - ENDIF -; -; /* Return to interrupt processing. */ -; - BX lr ; Return to interrupt processing caller -;} + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + + BX lr +// } ALIGN LTORG END diff --git a/ports/cortex_m4/ac5/src/tx_thread_interrupt_control.s b/ports/cortex_m4/ac5/src/tx_thread_interrupt_control.s index ef983f17..7f66f181 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_interrupt_control.s +++ b/ports/cortex_m4/ac5/src/tx_thread_interrupt_control.s @@ -1,76 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_control Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_control(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M4/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { EXPORT _tx_thread_interrupt_control _tx_thread_interrupt_control -; -; /* Pickup current interrupt lockout posture. */ -; - MRS r1, PRIMASK - MSR PRIMASK, r0 - MOV r0, r1 - BX lr -; -;} +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } END diff --git a/ports/cortex_m4/ac5/src/tx_thread_interrupt_disable.s b/ports/cortex_m4/ac5/src/tx_thread_interrupt_disable.s index b0b31cb0..4712f26b 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_interrupt_disable.s +++ b/ports/cortex_m4/ac5/src/tx_thread_interrupt_disable.s @@ -1,75 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_disable Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_disable(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M4/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { EXPORT _tx_thread_interrupt_disable _tx_thread_interrupt_disable -; -; /* Return current interrupt lockout posture. */ -; + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else MRS r0, PRIMASK CPSID i +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m4/ac5/src/tx_thread_interrupt_restore.s b/ports/cortex_m4/ac5/src/tx_thread_interrupt_restore.s index c7350e36..a30922c3 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_interrupt_restore.s +++ b/ports/cortex_m4/ac5/src/tx_thread_interrupt_restore.s @@ -1,74 +1,75 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_interrupt_restore(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M4/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { EXPORT _tx_thread_interrupt_restore _tx_thread_interrupt_restore -; -; /* Restore previous interrupt lockout posture. */ -; + + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else MSR PRIMASK, r0 +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m4/ac5/src/tx_thread_schedule.s b/ports/cortex_m4/ac5/src/tx_thread_schedule.s index 0b3888a6..a9e00641 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_schedule.s +++ b/ports/cortex_m4/ac5/src/tx_thread_schedule.s @@ -1,308 +1,285 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IMPORT _tx_thread_current_ptr IMPORT _tx_thread_execute_ptr IMPORT _tx_timer_time_slice IMPORT _tx_thread_system_stack_ptr IMPORT _tx_thread_preempt_disable - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_thread_enter IMPORT _tx_execution_thread_exit - ENDIF - IF :DEF:TX_LOW_POWER - IMPORT tx_low_power_enter - IMPORT tx_low_power_exit - ENDIF -; -; - AREA ||.text||, CODE, READONLY +#endif + + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M4/AC5 */ -;/* 6.1.5 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* _tx_thread_context_restore Restore thread's context */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* 03-02-2021 Scott Larson Modified comment(s), add */ -;/* low power code, */ -;/* resulting in version 6.1.5 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_schedule(VOID) -;{ - EXPORT _tx_thread_schedule +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M4/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { + EXPORT _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 -; -; /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -; - IF {TARGET_FPU_VFP} = {TRUE} - MRS r0, CONTROL ; Pickup current CONTROL register - BIC r0, r0, #4 ; Clear the FPCA bit - MSR CONTROL, r0 ; Setup new CONTROL register - ENDIF -; -; /* Enable the interrupts */ -; + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __TARGET_FPU_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register +#endif + + /* Enable interrupts */ CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR - DSB ; Complete all memory accesses - ISB ; Flush pipeline -; -; /* Wait here for the PendSV to take place. */ -; + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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. */ -; - EXPORT __tx_PendSVHandler - EXPORT PendSV_Handler + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + + EXPORT __tx_PendSVHandler + EXPORT PendSV_Handler __tx_PendSVHandler PendSV_Handler -; -; /* Get current thread value and new thread pointer. */ -; + + /* Get current thread value and new thread pointer. */ + __tx_ts_handler - IF :DEF: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, lr} ; Recover LR - CPSIE i ; Enable interrupts - ENDIF - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers - IF {TARGET_FPU_VFP} = {TRUE} - TST LR, #0x10 ; Determine if the VFP extended frame is present +#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 + 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 + CPSIE i // Enable interrupts +#endif + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __TARGET_FPU_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} ; Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save - ENDIF - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack -; -; /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -; - LDR r5, [r4] ; Pickup current time-slice - STR r12, [r1, #8] ; Save the thread stack pointer - 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. */ -; - STR r3, [r4] ; Clear time-slice -; -; /* Executing thread is now completely preserved!!! */ -; +#endif + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack + + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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. */ -; + + /* 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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 + LDR r7, [r1, #4] // Pickup the current thread run count + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD r7, r7, #1 // Increment the thread run count + STR r7, [r1, #4] // Store the new run count - IF :DEF: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 r3 - ENDIF -; -; /* Restore the thread context and PSP. */ -; - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR - IF {TARGET_FPU_VFP} = {TRUE} - TST LR, #0x10 ; Determine if the VFP extended frame is present - BNE _skip_vfp_restore ; If not, skip VFP restore - VLDMIA r12!, {s16-s31} ; Yes, restore additional VFP registers + /* Setup global time-slice with thread's current time-slice. */ + + STR r5, [r4] // Setup global time-slice + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 +#endif + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __TARGET_FPU_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore - ENDIF - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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. */ -; +#endif + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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! - IF :DEF:TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode - POP {r0-r3} - ENDIF +#ifdef TX_LOW_POWER + BL tx_low_power_enter // Possibly enter low power mode +#endif - IF :DEF:TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed - ENDIF +#ifdef TX_ENABLE_WFI + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed +#endif - IF :DEF:TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode - POP {r0-r3} - ENDIF +#ifdef TX_LOW_POWER + BL tx_low_power_exit // Exit low power mode +#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! */ - 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 - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV - IF {TARGET_FPU_VFP} = {TRUE} + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __TARGET_FPU_VFP EXPORT tx_thread_fpu_enable tx_thread_fpu_enable -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller - EXPORT tx_thread_fpu_disable tx_thread_fpu_disable -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller EXPORT _tx_vfp_access _tx_vfp_access - VMOV.F32 s0, s0 ; Simply access the VFP - BX lr ; Return to caller + VMOV.F32 s0, s0 // Simply access the VFP + BX lr // Return to caller - - ENDIF +#endif ALIGN LTORG diff --git a/ports/cortex_m4/ac5/src/tx_thread_stack_build.s b/ports/cortex_m4/ac5/src/tx_thread_stack_build.s index f548938b..6336aad6 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_stack_build.s +++ b/ports/cortex_m4/ac5/src/tx_thread_stack_build.s @@ -1,133 +1,131 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_stack_build Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M4/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { EXPORT _tx_thread_stack_build _tx_thread_stack_build -; -; -; /* Build a fake interrupt frame. The form of the fake interrupt stack -; on the Cortex-M4 should look like the following after it is built: -; -; Stack Top: -; LR Interrupted LR (LR at time of PENDSV) -; r4 Initial value for r4 -; r5 Initial value for r5 -; r6 Initial value for r6 -; r7 Initial value for r7 -; r8 Initial value for r8 -; r9 Initial value for r9 -; r10 Initial value for r10 -; r11 Initial value for r11 -; 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 - BIC r2, r2, #0x7 ; Align frame for 8-byte alignment - SUB r2, r2, #68 ; Subtract frame size - LDR r3, =0xFFFFFFFD ; Build initial LR value - STR r3, [r2, #0] ; Save on the stack -; -; /* Actually build the stack frame. */ -; - MOV r3, #0 ; Build initial register value - STR r3, [r2, #4] ; Store initial r4 - STR r3, [r2, #8] ; Store initial r5 - STR r3, [r2, #12] ; Store initial r6 - STR r3, [r2, #16] ; Store initial r7 - STR r3, [r2, #20] ; Store initial r8 - STR r3, [r2, #24] ; Store initial r9 - STR r3, [r2, #28] ; Store initial r10 - STR r3, [r2, #32] ; Store initial r11 -; -; /* 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 - MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value - STR r3, [r2, #56] ; Store initial lr - STR r1, [r2, #60] ; Store initial pc - MOV 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 -;} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 diff --git a/ports/cortex_m4/ac5/src/tx_thread_system_return.s b/ports/cortex_m4/ac5/src/tx_thread_system_return.s index 9c453e61..9e28a138 100644 --- a/ports/cortex_m4/ac5/src/tx_thread_system_return.s +++ b/ports/cortex_m4/ac5/src/tx_thread_system_return.s @@ -1,85 +1,91 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_system_return Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_system_return(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M4/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { EXPORT _tx_thread_system_return _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. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 + + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif _isr_context - BX lr ; Return to caller -;} + BX lr // Return to caller +// } END diff --git a/ports/cortex_m4/ac5/src/tx_timer_interrupt.s b/ports/cortex_m4/ac5/src/tx_timer_interrupt.s index f5160174..7e694b07 100644 --- a/ports/cortex_m4/ac5/src/tx_timer_interrupt.s +++ b/ports/cortex_m4/ac5/src/tx_timer_interrupt.s @@ -1,26 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IMPORT _tx_timer_time_slice IMPORT _tx_timer_system_clock IMPORT _tx_timer_current_ptr @@ -33,227 +32,223 @@ IMPORT _tx_thread_preempt_disable IMPORT _tx_thread_current_ptr IMPORT _tx_thread_execute_ptr -; -; + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M4/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_timer_interrupt(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M4/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { EXPORT _tx_timer_interrupt _tx_timer_interrupt -; -; /* Upon entry to this routine, it is assumed that context save has already -; been called, and therefore the compiler scratch registers are available -; for use. */ -; -; /* Increment the system clock. */ -; _tx_timer_system_clock++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock - LDR r0, [r1, #0] ; Pickup system clock - ADD r0, r0, #1 ; Increment system clock - STR r0, [r1, #0] ; Store new system clock -; -; /* Test for time-slice expiration. */ -; if (_tx_timer_time_slice) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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--; -; - SUB 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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++; -; - ADD r0, r0, #4 ; Move to next timer -; -; /* Check for wrap-around. */ -; if (_tx_timer_current_ptr == _tx_timer_list_end) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + +__tx_something_expired + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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 -; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for -; -; } -; + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired - DSB ; Complete all memory access - BX lr ; Return to caller -; -;} + DSB // Complete all memory access + BX lr // Return to caller +// } ALIGN LTORG END diff --git a/ports/cortex_m4/ac6/inc/tx_port.h b/ports/cortex_m4/ac6/inc/tx_port.h index d99bcbc8..420bf62e 100644 --- a/ports/cortex_m4/ac6/inc/tx_port.h +++ b/ports/cortex_m4/ac6/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M4/AC6 */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -131,46 +154,83 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#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 logic. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#endif /* 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -184,11 +244,11 @@ typedef unsigned short USHORT; #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -196,12 +256,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif -#ifdef TX_ENABLE_FPU_SUPPORT - +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -210,26 +286,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) { - ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } - -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) { - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); } +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); -#endif +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -237,23 +336,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -262,79 +360,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((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 = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) - -#endif - +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -359,126 +454,242 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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++; -/* This 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 +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - #endif -#ifndef TX_DISABLE_INLINE -/* Define AC6 specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; -unsigned int primask_value; + int_posture = __get_interrupt_posture(); - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) -{ - - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); -} - -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) -{ - -unsigned int primask_value; - - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); -} - -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) -{ - - __asm__ volatile (" CPSIE i": : : "memory" ); -} - - __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_ipsr_value() == 0) { - interrupt_save = __get_primask_value(); + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ #define _tx_thread_system_return _tx_thread_system_return_inline -#else +#else /* TX_DISABLE_INLINE is defined */ -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing - thread. This is for legacy only, and not needed anylonger. */ +/* Define FPU extension for the Cortex-M. 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); @@ -487,16 +698,15 @@ void tx_thread_fpu_disable(void); /* 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-M4/AC6 Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/AC6 Version 6.1.7 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - - #endif - - - +#endif diff --git a/ports/cortex_m4/ac6/readme_threadx.txt b/ports/cortex_m4/ac6/readme_threadx.txt index f09babe9..d98c90cb 100644 --- a/ports/cortex_m4/ac6/readme_threadx.txt +++ b/ports/cortex_m4/ac6/readme_threadx.txt @@ -1,41 +1,39 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M4 + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using ARM Compiler 6 (AC6) - Using the AC6 Tools -1. Import the ThreadX Projects +1. Building the ThreadX run-time Library In order to build the ThreadX library and the ThreadX demonstration, first import the 'tx' and 'sample_threadx' projects (located in the "example_build" directory) into your DS workspace. - -2. Building the ThreadX run-time Library - Building the ThreadX library is easy; simply right-click the Eclipse project "tx" and then select the "Build Project" button. You should now observe the compilation and assembly of the ThreadX library. This project build produces the ThreadX library file tx.a. -3. Demonstration System +2. Demonstration System The ThreadX demonstration is designed to execute under the DS debugger on the -MPS2_Cortex_M4 Bare Metal simulator. +MPS2_Cortex_Mx Bare Metal simulator. Building the demonstration is easy; simply right-click the Eclipse project "sample_threadx" and then select the "Build Project" button. You should now observe the compilation and assembly of the ThreadX demonstration. This project build produces the ThreadX library file sample_threadx.axf. Next, expand the demo ThreadX project folder -in the Project Explorer window, right-click on the 'cortex-m4_tx.launch' file, click -'Debug As', and then click 'cortex-m4_tx' from the submenu. This will cause the +in the Project Explorer window, right-click on the 'cortex-mx_tx.launch' file, click +'Debug As', and then click 'cortex-mx_tx' from the submenu. This will cause the debugger to load the sample_threadx.axf ELF file and run to main. You are now ready to execute the ThreadX demonstration. -4. System Initialization +3. System Initialization -The entry point in ThreadX for the Cortex-M4 using AC6 tools uses the standard AC6 -Cortex-M4 reset sequence. From the reset vector the C runtime will be initialized. +The entry point in ThreadX for the Cortex-M using AC6 tools uses the standard GNU +Cortex-M reset sequence. From the reset vector the C runtime will be initialized. The ThreadX tx_initialize_low_level.S file is responsible for setting up various system data structures, the vector area, and a periodic timer interrupt @@ -46,11 +44,11 @@ address for use by the application, which is supplied as the sole input parameter to your application definition function, tx_application_define. -5. Register Usage and Stack Frames +4. Register Usage and Stack Frames The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M4 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. @@ -58,7 +56,7 @@ Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -80,7 +78,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -132,57 +130,47 @@ FPU Stack Frame (only interrupted thread with FPU enabled): 0xC4 fpscr -6. Improving Performance +5. Improving Performance -The distribution version of ThreadX is built without any compiler optimizations. -This makes it easy to debug because you can trace or set breakpoints inside of -ThreadX itself. Of course, this costs some performance. To make it run faster, -you can change the build_threadx.bat file to remove the -g option and enable -all compiler optimizations. +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING defined. -7. Interrupt Handling +6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M4 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: -7.1 Vector Area +6.1 Vector Area -The Cortex-M4 vectors start at the label __tx_vectors or similar. The application may modify +The Cortex-M vectors start at the label __tx_vectors or similar. The application may modify the vector area according to its needs. There is code in tx_initialize_low_level() that will configure the vector base register. -7.2 Managed Interrupts +6.2 Managed Interrupts -ISRs can be written completely in C (or assembly language) without any calls to -_tx_thread_context_save or _tx_thread_context_restore. These ISRs are allowed access to the -ThreadX API that is available to ISRs. - -ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): - -void your_C_isr(void) -{ - - /* ISR processing goes here, including any needed function calls. */ -} - -ISRs written in assembly language will take the form: +A ThreadX managed interrupt is defined below. By following these conventions, the +application ISR is then allowed access to various ThreadX services from the ISR. +Here is the standard template for managed ISRs in ThreadX: - .global your_assembly_isr + .global __tx_IntHandler .thumb_func -your_assembly_isr: -; VOID your_assembly_isr(VOID) +__tx_IntHandler: +; VOID InterruptHandler (VOID) ; { PUSH {r0, lr} -; + ; /* Do interrupt handler work here */ ; /* BL */ @@ -190,37 +178,31 @@ your_assembly_isr: BX lr ; } -Note: the Cortex-M4 requires exception handlers to be thumb labels, this implies bit 0 set. + +Note: the Cortex-M requires exception handlers to be thumb labels, this implies bit 0 set. To accomplish this, the declaration of the label has to be preceded by the assembler directive .thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to be inserted in the correct location in the interrupt vector table. This table is typically located in either your runtime startup file or in the tx_initialize_low_level.S file. -8. FPU Support +7. FPU Support -ThreadX for Cortex-M4 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread -context. If saving the context of the FPU registers is needed, the ThreadX library should be re-built -with TX_ENABLE_FPU_SUPPORT defined. +context - no additional setup by the application. -9. Revision History +8. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M4 using AC6 tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using AC6 tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m4/ac6/src/tx_thread_context_restore.S b/ports/cortex_m4/ac6/src/tx_thread_context_restore.S index daa78a7a..f19694aa 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_context_restore.S +++ b/ports/cortex_m4/ac6/src/tx_thread_context_restore.S @@ -1,86 +1,81 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr - .global _tx_thread_system_stack_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_schedule - .global _tx_thread_preempt_disable -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_restore Cortex-M4/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function restores the interrupt context if it is processing a */ -@/* nested interrupt. If not, it returns to the interrupt thread if no */ -@/* preemption is necessary. Otherwise, if preemption is necessary or */ -@/* if no thread was running, the function returns to the scheduler. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* _tx_thread_schedule Thread scheduling routine */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs Interrupt Service Routines */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_restore(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M4/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { .global _tx_thread_context_restore .thumb_func _tx_thread_context_restore: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -@} +// } diff --git a/ports/cortex_m4/ac6/src/tx_thread_context_save.S b/ports/cortex_m4/ac6/src/tx_thread_context_save.S index 43f2e4c9..932f84c4 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_context_save.S +++ b/ports/cortex_m4/ac6/src/tx_thread_context_save.S @@ -1,80 +1,83 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_save Cortex-M4/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function saves the context of an executing thread in the */ -@/* beginning of interrupt processing. The function also ensures that */ -@/* the system stack is used upon return to the calling ISR. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* None */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_save(VOID) -@{ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_enter +#endif +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M4/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { .global _tx_thread_context_save .thumb_func _tx_thread_context_save: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr -@} +// } diff --git a/ports/cortex_m4/ac6/src/tx_thread_interrupt_control.S b/ports/cortex_m4/ac6/src/tx_thread_interrupt_control.S index 892509bc..b79a59c1 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_interrupt_control.S +++ b/ports/cortex_m4/ac6/src/tx_thread_interrupt_control.S @@ -1,81 +1,79 @@ -@/**************************************************************************/ -@/* */ -@/* 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. */ -@/* */ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ - +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_interrupt_control Cortex-M4/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* UINT _tx_thread_interrupt_control(UINT new_posture) -{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M4/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { .global _tx_thread_interrupt_control .thumb_func _tx_thread_interrupt_control: - -@/* Pickup current interrupt lockout posture. */ - - MRS r1, PRIMASK @ Pickup current interrupt lockout - -@/* Apply the new interrupt posture. */ - - MSR PRIMASK, r0 @ Apply the new interrupt lockout - MOV r0, r1 @ Transfer old to return register - BX lr @ Return to caller - -@/* } */ +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } diff --git a/ports/cortex_m4/ac6/src/tx_thread_interrupt_disable.S b/ports/cortex_m4/ac6/src/tx_thread_interrupt_disable.S new file mode 100644 index 00000000..2adec1d8 --- /dev/null +++ b/ports/cortex_m4/ac6/src/tx_thread_interrupt_disable.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M4/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { + .global _tx_thread_interrupt_disable + .thumb_func +_tx_thread_interrupt_disable: + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else + MRS r0, PRIMASK + CPSID i +#endif + BX lr +// } diff --git a/ports/cortex_m23/ac5/src/tx_thread_stack_error_handler.c b/ports/cortex_m4/ac6/src/tx_thread_interrupt_restore.S similarity index 71% rename from ports/cortex_m23/ac5/src/tx_thread_stack_error_handler.c rename to ports/cortex_m4/ac6/src/tx_thread_interrupt_restore.S index ef98240c..a920cdbf 100644 --- a/ports/cortex_m23/ac5/src/tx_thread_stack_error_handler.c +++ b/ports/cortex_m4/ac6/src/tx_thread_interrupt_restore.S @@ -20,38 +20,27 @@ /**************************************************************************/ /**************************************************************************/ -#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); - + .text 32 + .align 4 + .syntax unified /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_stack_error_handler Cortex-M23 */ -/* 6.1 */ +/* _tx_thread_interrupt_restore Cortex-M4/AC6 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function processes stack errors detected during run-time. */ -/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ /* */ /* INPUT */ /* */ -/* thread_ptr Thread control block pointer */ +/* previous_posture Previous interrupt posture */ /* */ /* OUTPUT */ /* */ @@ -59,35 +48,29 @@ VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr); /* */ /* CALLS */ /* */ -/* _tx_thread_terminate */ -/* _tx_thread_application_stack_error_handler */ +/* None */ /* */ /* CALLED BY */ /* */ -/* ThreadX internal code */ +/* Application Code */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ -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); - } -} +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { + .global _tx_thread_interrupt_restore + .thumb_func +_tx_thread_interrupt_restore: + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else + MSR PRIMASK, r0 +#endif + BX lr +// } diff --git a/ports/cortex_m4/ac6/src/tx_thread_schedule.S b/ports/cortex_m4/ac6/src/tx_thread_schedule.S index bd08fc2f..4fb842db 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_schedule.S +++ b/ports/cortex_m4/ac6/src/tx_thread_schedule.S @@ -1,304 +1,286 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_current_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_system_stack_ptr +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_thread_current_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit +#endif #ifdef TX_LOW_POWER .global tx_low_power_enter .global tx_low_power_exit #endif - -@ -@ .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_schedule Cortex-M4/AC6 */ -@/* 6.1.5 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* _tx_thread_context_restore Restore thread's context */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* 03-02-2021 Scott Larson Modified comment(s), add */ -@/* low power code, */ -@/* resulting in version 6.1.5 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_schedule(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M4/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { .global _tx_thread_schedule .thumb_func _tx_thread_schedule: -@ -@ /* This function should only ever be called on Cortex-M4 -@ from the first schedule request. Subsequent scheduling occurs -@ from the PendSV handling routines below. */ -@ -@ /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -@ - MOV 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 -@ -@ /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -@ -#ifdef TX_ENABLE_FPU_SUPPORT - MRS r0, CONTROL @ Pickup current CONTROL register - BIC r0, r0, #4 @ Clear the FPCA bit - MSR CONTROL, r0 @ Setup new CONTROL register + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __ARM_PCS_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register #endif -@ -@ /* Enable interrupts */ -@ + + /* Enable interrupts */ CPSIE i -@ -@ /* Enter the scheduler for the first time. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ Set PENDSVBIT in ICSR - DSB @ Complete all memory accesses - ISB @ Flush pipeline -@ -@ /* Wait here for the PendSV to take place. */ -@ + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 switch-out switch-in handler... Note that this handler is -@ common for both PendSV and SVCall. */ -@ + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + .global PendSV_Handler .global __tx_PendSVHandler + .syntax unified .thumb_func PendSV_Handler: .thumb_func __tx_PendSVHandler: -@ -@ /* Get current thread value and new thread pointer. */ -@ + + /* Get current thread value and new thread pointer. */ + __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, lr} @ Recover LR - CPSIE i @ Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - MOV 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 r12, PSP @ Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} @ Save its remaining registers -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} @ Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save: #endif - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - STMDB r12!, {LR} @ Save LR on the stack -@ -@ /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -@ - LDR r5, [r4] @ Pickup current time-slice - STR r12, [r1, #8] @ Save the thread stack pointer - 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. */ -@ - STR r3, [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 - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - LDR r5, [r1, #24] @ Pickup thread's current time-slice - ADD 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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack -#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 r3 + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 #endif -@ -@ /* Restore the thread context and PSP. */ -@ - LDR r12, [r1, #8] @ Pickup thread's stack pointer - LDMIA r12!, {LR} @ Pickup LR -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present - BNE _skip_vfp_restore @ If not, skip VFP restore - VLDMIA r12!, {s16-s31} @ Yes, restore additional VFP registers + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore: #endif - LDMIA r12!, {r4-r11} @ Recover thread's registers - MSR PSP, r12 @ 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. */ -@ + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter @ Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB @ Ensure no outstanding memory transactions - WFI @ Wait for interrupt - ISB @ Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit @ Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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! */ -@ + 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: - MOV r7, #0x08000000 @ Build clear PendSV value - MOV r8, #0xE000E000 @ Build base NVIC address - STR r7, [r8, #0xD04] @ Clear any PendSV -@ -@ /* Re-enable interrupts and restore new thread. */ -@ - CPSIE i @ Enable interrupts - B __tx_ts_restore @ Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV -#ifdef TX_ENABLE_FPU_SUPPORT + /* Re-enable interrupts and restore new thread. */ - .global tx_thread_fpu_enable - .thumb_func + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __ARM_PCS_VFP + + .global tx_thread_fpu_enable + .thumb_func tx_thread_fpu_enable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller - - .global tx_thread_fpu_disable - .thumb_func + .global tx_thread_fpu_disable + .thumb_func tx_thread_fpu_disable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller #endif diff --git a/ports/cortex_m4/ac6/src/tx_thread_stack_build.S b/ports/cortex_m4/ac6/src/tx_thread_stack_build.S index f2639031..5e4eddb2 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_stack_build.S +++ b/ports/cortex_m4/ac6/src/tx_thread_stack_build.S @@ -1,135 +1,133 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_stack_build Cortex-M4/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M4/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { .global _tx_thread_stack_build .thumb_func _tx_thread_stack_build: -@ -@ -@ /* Build a fake interrupt frame. The form of the fake interrupt stack -@ on the Cortex-M4 should look like the following after it is built: -@ -@ Stack Top: -@ LR Interrupted LR (LR at time of PENDSV) -@ r4 Initial value for r4 -@ r5 Initial value for r5 -@ r6 Initial value for r6 -@ r7 Initial value for r7 -@ r8 Initial value for r8 -@ r9 Initial value for r9 -@ r10 Initial value for r10 -@ r11 Initial value for r11 -@ 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 - BIC r2, r2, #0x7 @ Align frame - SUB r2, r2, #68 @ Subtract frame size - LDR r3, =0xFFFFFFFD @ Build initial LR value - STR r3, [r2, #0] @ Save on the stack -@ -@ /* Actually build the stack frame. */ -@ - MOV r3, #0 @ Build initial register value - STR r3, [r2, #4] @ Store initial r4 - STR r3, [r2, #8] @ Store initial r5 - STR r3, [r2, #12] @ Store initial r6 - STR r3, [r2, #16] @ Store initial r7 - STR r3, [r2, #20] @ Store initial r8 - STR r3, [r2, #24] @ Store initial r9 - STR r3, [r2, #28] @ Store initial r10 - STR r3, [r2, #32] @ Store initial r11 -@ -@ /* 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 - MOV r3, #0xFFFFFFFF @ Poison EXC_RETURN value - STR r3, [r2, #56] @ Store initial lr - STR r1, [r2, #60] @ Store initial pc - MOV 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 -@} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 +// } diff --git a/ports/cortex_m4/ac6/src/tx_thread_system_return.S b/ports/cortex_m4/ac6/src/tx_thread_system_return.S index 3fa421c3..a8b6dc97 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m4/ac6/src/tx_thread_system_return.S @@ -1,88 +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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_system_return Cortex-M4/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* VOID _tx_thread_system_return(VOID) -@{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M4/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { .thumb_func .global _tx_thread_system_return _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. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ 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 -@/* } */ + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif +_isr_context: + BX lr // Return to caller +// } diff --git a/ports/cortex_m4/ac6/src/tx_timer_interrupt.S b/ports/cortex_m4/ac6/src/tx_timer_interrupt.S index 4f1175da..6116f875 100644 --- a/ports/cortex_m4/ac6/src/tx_timer_interrupt.S +++ b/ports/cortex_m4/ac6/src/tx_timer_interrupt.S @@ -1,257 +1,250 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_timer_time_slice - .global _tx_timer_system_clock - .global _tx_timer_current_ptr - .global _tx_timer_list_start - .global _tx_timer_list_end - .global _tx_timer_expired_time_slice - .global _tx_timer_expired - .global _tx_thread_time_slice - .global _tx_timer_expiration_process -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_timer_time_slice + .global _tx_timer_system_clock + .global _tx_timer_current_ptr + .global _tx_timer_list_start + .global _tx_timer_list_end + .global _tx_timer_expired_time_slice + .global _tx_timer_expired + .global _tx_thread_time_slice + .global _tx_timer_expiration_process + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_timer_interrupt Cortex-M4/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_timer_interrupt(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M4/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { .global _tx_timer_interrupt .thumb_func _tx_timer_interrupt: -@ -@ /* Upon entry to this routine, it is assumed that context save has already -@ been called, and therefore the compiler scratch registers are available -@ for use. */ -@ -@ /* Increment the system clock. */ -@ _tx_timer_system_clock++; -@ - LDR r1, =_tx_timer_system_clock @ Pickup address of system clock - LDR r0, [r1, #0] @ Pickup system clock - ADD r0, r0, #1 @ Increment system clock - STR r0, [r1, #0] @ Store new system clock -@ -@ /* Test for time-slice expiration. */ -@ if (_tx_timer_time_slice) -@ { -@ - LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice - LDR r2, [r3, #0] @ Pickup time-slice - CMP r2, #0 @ Is it non-active? - BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing -@ -@ /* Decrement the time_slice. */ -@ _tx_timer_time_slice--; -@ - SUB 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) -@ - CMP r2, #0 @ Has it expired? - BNE __tx_timer_no_time_slice @ No, skip expiration processing -@ -@ /* Set the time-slice expired flag. */ -@ _tx_timer_expired_time_slice = TX_TRUE; -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag - MOV r0, #1 @ Build expired value - STR r0, [r3, #0] @ Set time-slice expiration flag -@ -@ } -@ + + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) -@ { -@ - LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address - LDR r0, [r1, #0] @ Pickup current timer - LDR r2, [r0, #0] @ Pickup timer list entry - CMP r2, #0 @ Is there anything in the list? - BEQ __tx_timer_no_timer @ No, just increment the timer -@ -@ /* Set expiration flag. */ -@ _tx_timer_expired = TX_TRUE; -@ - LDR r3, =_tx_timer_expired @ Pickup expiration flag address - MOV r2, #1 @ Build expired value - STR r2, [r3, #0] @ Set expired flag - B __tx_timer_done @ Finished timer processing -@ -@ } -@ else -@ { + + /* Test for timer expiration. */ + // if (*_tx_timer_current_ptr) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; -@ - ADD r0, r0, #4 @ Move to next timer -@ -@ /* Check for wrap-around. */ -@ if (_tx_timer_current_ptr == _tx_timer_list_end) -@ - LDR r3, =_tx_timer_list_end @ Pickup addr of 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; -@ - LDR r3, =_tx_timer_list_start @ Pickup addr of timer list start - LDR r0, [r3, #0] @ Set current pointer to list start -@ + + /* No timer expired, increment the timer pointer. */ + // _tx_timer_current_ptr++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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 -@ } -@ + + 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)) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of expired flag - LDR r2, [r3, #0] @ Pickup time-slice expired flag - CMP r2, #0 @ Did a time-slice expire? - BNE __tx_something_expired @ If non-zero, time-slice expired - LDR r1, =_tx_timer_expired @ Pickup addr of other expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Did a timer expire? - BEQ __tx_timer_nothing_expired @ No, nothing expired -@ + + /* See if anything has expired. */ + // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + __tx_something_expired: -@ -@ - STMDB sp!, {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) -@ { -@ - LDR r1, =_tx_timer_expired @ Pickup addr of expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Check for timer expiration - BEQ __tx_timer_dont_activate @ If not set, skip timer activation -@ -@ /* Process timer expiration. */ -@ _tx_timer_expiration_process(); -@ - BL _tx_timer_expiration_process @ Call the timer expiration handling routine -@ -@ } + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of time-slice expired - LDR r2, [r3, #0] @ Pickup the actual flag - CMP r2, #0 @ See if the flag is set - BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing -@ -@ /* Time slice interrupted thread. */ -@ _tx_thread_time_slice(); -@ - BL _tx_thread_time_slice @ Call time-slice processing - LDR r0, =_tx_thread_preempt_disable @ Build address of preempt disable flag - LDR r1, [r0] @ Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice @ Yes, skip the PendSV logic - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r1, [r0] @ Pickup the current thread pointer - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - 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 + + /* Did time slice expire? */ + // if (_tx_timer_expired_time_slice) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -@ - LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for - @ the 8-byte stack alignment -@ -@ } -@ + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB @ Complete all memory access - BX lr @ Return to caller -@ -@} + DSB // Complete all memory access + BX lr // Return to caller +// } diff --git a/ports/cortex_m4/gnu/inc/tx_port.h b/ports/cortex_m4/gnu/inc/tx_port.h index 6b65e04c..7d1a4c07 100644 --- a/ports/cortex_m4/gnu/inc/tx_port.h +++ b/ports/cortex_m4/gnu/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M4/GNU */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,16 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -/* 09-30-2020 William E. Lamie Modified comment(s), */ -/* resulting in version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -64,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -76,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -86,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -113,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,46 +154,83 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#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 logic. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#endif /* 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -186,11 +244,11 @@ typedef unsigned short USHORT; #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -198,12 +256,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif -#ifdef TX_ENABLE_FPU_SUPPORT - +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -212,26 +286,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) { - ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } - -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) { - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); } +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); -#endif +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -239,23 +336,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -264,79 +360,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((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 = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) - -#endif - +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -361,126 +454,242 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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++; -/* This 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 +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - #endif -#ifndef TX_DISABLE_INLINE -/* Define GNU specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; -unsigned int primask_value; + int_posture = __get_interrupt_posture(); - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) -{ - - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); -} - -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) -{ - -unsigned int primask_value; - - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); -} - -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) -{ - - __asm__ volatile (" CPSIE i": : : "memory" ); -} - - __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_ipsr_value() == 0) { - interrupt_save = __get_primask_value(); + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ #define _tx_thread_system_return _tx_thread_system_return_inline -#else +#else /* TX_DISABLE_INLINE is defined */ -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing - thread. This is for legacy only, and not needed anylonger. */ +/* Define FPU extension for the Cortex-M. 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); @@ -489,16 +698,15 @@ void tx_thread_fpu_disable(void); /* 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-M4/GNU Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/GNU Version 6.1.7 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - - #endif - - - +#endif diff --git a/ports/cortex_m4/gnu/readme_threadx.txt b/ports/cortex_m4/gnu/readme_threadx.txt index 383c72fd..d9063d65 100644 --- a/ports/cortex_m4/gnu/readme_threadx.txt +++ b/ports/cortex_m4/gnu/readme_threadx.txt @@ -1,12 +1,13 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M4 - + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) Using the GNU Tools + 1. Building the ThreadX run-time Library -First make sure you are in the "example_build" directory. Also, make sure that +Navigate to the "example_build" directory. Ensure that you have setup your path and other environment variables necessary for the ARM -gnu (GNU) compiler. At this point you may run the build_threadx.bat batch file. +GNU compiler. At this point you may run the build_threadx.bat batch file. This will build the ThreadX run-time environment in the "example_build" directory. @@ -16,13 +17,13 @@ run-time library file: tx.a. This file must be linked with your application in order to use ThreadX. -2. Demonstration System for Cortex-M4 +2. Demonstration System -The ThreadX demonstration is designed to execute on Cortex-M4 evaluation boards +The ThreadX demonstration is designed to execute on Cortex-M evaluation boards or on a dedicated simulator. Building the demonstration is easy, simply execute the build_threadx_sample.bat -batch file while inside the "example_build" directory. +batch file while inside the "example_build" directory. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.out is a binary @@ -31,8 +32,8 @@ file that can be downloaded and executed on the a simulator, or downloaded to a 3. System Initialization -The entry point in ThreadX for the Cortex-M4 using gnu tools uses the standard GNU -Cortex-M4 reset sequence. From the reset vector the C runtime will be initialized. +The entry point in ThreadX for the Cortex-M using gnu tools uses the standard GNU +Cortex-M reset sequence. From the reset vector the C runtime will be initialized. The ThreadX tx_initialize_low_level.S file is responsible for setting up various system data structures, the vector area, and a periodic timer interrupt @@ -47,7 +48,7 @@ parameter to your application definition function, tx_application_define. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M4 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. @@ -55,7 +56,7 @@ Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -77,7 +78,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -144,42 +145,32 @@ defined. 6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M4 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: 6.1 Vector Area -The Cortex-M4 vectors start at the label __tx_vectors or similar. The application may modify +The Cortex-M vectors start at the label __tx_vectors or similar. The application may modify the vector area according to its needs. There is code in tx_initialize_low_level() that will configure the vector base register. 6.2 Managed Interrupts -ISRs can be written completely in C (or assembly language) without any calls to -_tx_thread_context_save or _tx_thread_context_restore. These ISRs are allowed access to the -ThreadX API that is available to ISRs. - -ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): - -void your_C_isr(void) -{ - - /* ISR processing goes here, including any needed function calls. */ -} - -ISRs written in assembly language will take the form: +A ThreadX managed interrupt is defined below. By following these conventions, the +application ISR is then allowed access to various ThreadX services from the ISR. +Here is the standard template for managed ISRs in ThreadX: - .global your_assembly_isr + .global __tx_IntHandler .thumb_func -your_assembly_isr: -; VOID your_assembly_isr(VOID) +__tx_IntHandler: +; VOID InterruptHandler (VOID) ; { PUSH {r0, lr} -; + ; /* Do interrupt handler work here */ ; /* BL */ @@ -187,7 +178,8 @@ your_assembly_isr: BX lr ; } -Note: the Cortex-M4 requires exception handlers to be thumb labels, this implies bit 0 set. + +Note: the Cortex-M requires exception handlers to be thumb labels, this implies bit 0 set. To accomplish this, the declaration of the label has to be preceded by the assembler directive .thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to be inserted in the correct location in the interrupt vector table. This table is typically @@ -196,10 +188,9 @@ located in either your runtime startup file or in the tx_initialize_low_level.S 7. FPU Support -ThreadX for Cortex-M4 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread -context. If saving the context of the FPU registers is needed, the ThreadX library should be re-built -with TX_ENABLE_FPU_SUPPORT defined. +context - no additional setup by the application. 8. Revision History @@ -208,21 +199,10 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 ThreadX update of Cortex-M4/GNU port. The following files were - changed/added for port specific version 6.1: - - *.S Modified comments and whitespace. - -05/19/2020 Initial ThreadX 6.0 version for Cortex-M4 using GNU tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using GNU tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m4/gnu/src/tx_thread_context_restore.S b/ports/cortex_m4/gnu/src/tx_thread_context_restore.S index 6dfd19df..5fb71275 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_context_restore.S +++ b/ports/cortex_m4/gnu/src/tx_thread_context_restore.S @@ -1,89 +1,81 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr - .global _tx_thread_system_stack_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_schedule - .global _tx_thread_preempt_disable - .global _tx_execution_isr_exit -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_restore Cortex-M4/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function restores the interrupt context if it is processing a */ -@/* nested interrupt. If not, it returns to the interrupt thread if no */ -@/* preemption is necessary. Otherwise, if preemption is necessary or */ -@/* if no thread was running, the function returns to the scheduler. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* _tx_thread_schedule Thread scheduling routine */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs Interrupt Service Routines */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_restore(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M4/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { .global _tx_thread_context_restore .thumb_func _tx_thread_context_restore: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -@} +// } diff --git a/ports/cortex_m4/gnu/src/tx_thread_context_save.S b/ports/cortex_m4/gnu/src/tx_thread_context_save.S index e086d467..08dafb44 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_context_save.S +++ b/ports/cortex_m4/gnu/src/tx_thread_context_save.S @@ -1,84 +1,80 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr - .global _tx_execution_isr_enter -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_save Cortex-M4/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function saves the context of an executing thread in the */ -@/* beginning of interrupt processing. The function also ensures that */ -@/* the system stack is used upon return to the calling ISR. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* None */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 Scott Larson Modified comment(s), and */ -@/* cleaned up whitespace, */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_save(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M4/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_enter] Execution profiling ISR enter */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { .global _tx_thread_context_save .thumb_func _tx_thread_context_save: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr -@} +// } diff --git a/ports/cortex_m4/gnu/src/tx_thread_interrupt_control.S b/ports/cortex_m4/gnu/src/tx_thread_interrupt_control.S index 4e6ec582..30960b56 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_interrupt_control.S +++ b/ports/cortex_m4/gnu/src/tx_thread_interrupt_control.S @@ -1,83 +1,79 @@ -@/**************************************************************************/ -@/* */ -@/* 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. */ -@/* */ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ - +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_interrupt_control Cortex-M4/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* UINT _tx_thread_interrupt_control(UINT new_posture) -{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M4/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { .global _tx_thread_interrupt_control .thumb_func _tx_thread_interrupt_control: - -@/* Pickup current interrupt lockout posture. */ - - MRS r1, PRIMASK @ Pickup current interrupt lockout - -@/* Apply the new interrupt posture. */ - - MSR PRIMASK, r0 @ Apply the new interrupt lockout - MOV r0, r1 @ Transfer old to return register - BX lr @ Return to caller - -@/* } */ +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } diff --git a/ports/cortex_m4/gnu/src/tx_thread_interrupt_disable.S b/ports/cortex_m4/gnu/src/tx_thread_interrupt_disable.S new file mode 100644 index 00000000..d2945f08 --- /dev/null +++ b/ports/cortex_m4/gnu/src/tx_thread_interrupt_disable.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M4/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { + .global _tx_thread_interrupt_disable + .thumb_func +_tx_thread_interrupt_disable: + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else + MRS r0, PRIMASK + CPSID i +#endif + BX lr +// } diff --git a/ports/cortex_m33/ac5/src/tx_thread_stack_error_handler.c b/ports/cortex_m4/gnu/src/tx_thread_interrupt_restore.S similarity index 71% rename from ports/cortex_m33/ac5/src/tx_thread_stack_error_handler.c rename to ports/cortex_m4/gnu/src/tx_thread_interrupt_restore.S index 5c643784..a2efd882 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_stack_error_handler.c +++ b/ports/cortex_m4/gnu/src/tx_thread_interrupt_restore.S @@ -20,38 +20,27 @@ /**************************************************************************/ /**************************************************************************/ -#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); - + .text 32 + .align 4 + .syntax unified /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _tx_thread_stack_error_handler Cortex-M33 */ -/* 6.1 */ +/* _tx_thread_interrupt_restore Cortex-M4/GNU */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function processes stack errors detected during run-time. */ -/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ /* */ /* INPUT */ /* */ -/* thread_ptr Thread control block pointer */ +/* previous_posture Previous interrupt posture */ /* */ /* OUTPUT */ /* */ @@ -59,35 +48,29 @@ VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr); /* */ /* CALLS */ /* */ -/* _tx_thread_terminate */ -/* _tx_thread_application_stack_error_handler */ +/* None */ /* */ /* CALLED BY */ /* */ -/* ThreadX internal code */ +/* Application Code */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ -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); - } -} +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { + .global _tx_thread_interrupt_restore + .thumb_func +_tx_thread_interrupt_restore: + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else + MSR PRIMASK, r0 +#endif + BX lr +// } diff --git a/ports/cortex_m4/gnu/src/tx_thread_schedule.S b/ports/cortex_m4/gnu/src/tx_thread_schedule.S index 47d5e3e9..9457c88e 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_schedule.S +++ b/ports/cortex_m4/gnu/src/tx_thread_schedule.S @@ -1,307 +1,284 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_current_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_system_stack_ptr - .global _tx_execution_thread_enter - .global _tx_execution_thread_exit +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_thread_current_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit #ifdef TX_LOW_POWER .global tx_low_power_enter .global tx_low_power_exit #endif -@ -@ .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_schedule Cortex-M4/GNU */ -@/* 6.1.5 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* _tx_thread_context_restore Restore thread's context */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* 03-02-2021 Scott Larson Modified comment(s), add */ -@/* low power code, */ -@/* resulting in version 6.1.5 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_schedule(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M4/GNU */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { .global _tx_thread_schedule .thumb_func _tx_thread_schedule: -@ -@ /* This function should only ever be called on Cortex-M4 -@ from the first schedule request. Subsequent scheduling occurs -@ from the PendSV handling routines below. */ -@ -@ /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -@ - MOV 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 -@ -@ /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -@ -#ifdef TX_ENABLE_FPU_SUPPORT - MRS r0, CONTROL @ Pickup current CONTROL register - BIC r0, r0, #4 @ Clear the FPCA bit - MSR CONTROL, r0 @ Setup new CONTROL register + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __ARM_PCS_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register #endif -@ -@ /* Enable interrupts */ -@ + + /* Enable interrupts */ CPSIE i -@ -@ /* Enter the scheduler for the first time. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ Set PENDSVBIT in ICSR - DSB @ Complete all memory accesses - ISB @ Flush pipeline -@ -@ /* Wait here for the PendSV to take place. */ -@ + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 switch-out switch-in handler... Note that this handler is -@ common for both PendSV and SVCall. */ -@ + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + .global PendSV_Handler .global __tx_PendSVHandler + .syntax unified .thumb_func PendSV_Handler: .thumb_func __tx_PendSVHandler: -@ -@ /* Get current thread value and new thread pointer. */ -@ + + /* Get current thread value and new thread pointer. */ + __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, lr} @ Recover LR - CPSIE i @ Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - MOV 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 r12, PSP @ Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} @ Save its remaining registers -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} @ Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save: #endif - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - STMDB r12!, {LR} @ Save LR on the stack -@ -@ /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -@ - LDR r5, [r4] @ Pickup current time-slice - STR r12, [r1, #8] @ Save the thread stack pointer - 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. */ -@ - STR r3, [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 - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - LDR r5, [r1, #24] @ Pickup thread's current time-slice - ADD 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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack -#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 r3 + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 #endif -@ -@ /* Restore the thread context and PSP. */ -@ - LDR r12, [r1, #8] @ Pickup thread's stack pointer - LDMIA r12!, {LR} @ Pickup LR -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present - BNE _skip_vfp_restore @ If not, skip VFP restore - VLDMIA r12!, {s16-s31} @ Yes, restore additional VFP registers + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore: #endif - LDMIA r12!, {r4-r11} @ Recover thread's registers - MSR PSP, r12 @ 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. */ -@ + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter @ Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB @ Ensure no outstanding memory transactions - WFI @ Wait for interrupt - ISB @ Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit @ Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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! */ -@ + 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: - MOV r7, #0x08000000 @ Build clear PendSV value - MOV r8, #0xE000E000 @ Build base NVIC address - STR r7, [r8, #0xD04] @ Clear any PendSV -@ -@ /* Re-enable interrupts and restore new thread. */ -@ - CPSIE i @ Enable interrupts - B __tx_ts_restore @ Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV -#ifdef TX_ENABLE_FPU_SUPPORT + /* Re-enable interrupts and restore new thread. */ - .global tx_thread_fpu_enable - .thumb_func + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __ARM_PCS_VFP + + .global tx_thread_fpu_enable + .thumb_func tx_thread_fpu_enable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller - - .global tx_thread_fpu_disable - .thumb_func + .global tx_thread_fpu_disable + .thumb_func tx_thread_fpu_disable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller #endif diff --git a/ports/cortex_m4/gnu/src/tx_thread_stack_build.S b/ports/cortex_m4/gnu/src/tx_thread_stack_build.S index c0e8bca9..536d815b 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_stack_build.S +++ b/ports/cortex_m4/gnu/src/tx_thread_stack_build.S @@ -1,141 +1,133 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_stack_build Cortex-M4/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified Comment(s), setting */ -@/* R10 to top of stack is not */ -@/* needed. Removed references */ -@/* to stack frame, clean up */ -@/* whitespace, resulting */ -@/* in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M4/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { .global _tx_thread_stack_build .thumb_func _tx_thread_stack_build: -@ -@ -@ /* Build a fake interrupt frame. The form of the fake interrupt stack -@ on the Cortex-M4 should look like the following after it is built: -@ -@ Stack Top: -@ LR Interrupted LR (LR at time of PENDSV) -@ r4 Initial value for r4 -@ r5 Initial value for r5 -@ r6 Initial value for r6 -@ r7 Initial value for r7 -@ r8 Initial value for r8 -@ r9 Initial value for r9 -@ r10 Initial value for r10 -@ r11 Initial value for r11 -@ 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 - BIC r2, r2, #0x7 @ Align frame - SUB r2, r2, #68 @ Subtract frame size - LDR r3, =0xFFFFFFFD @ Build initial LR value - STR r3, [r2, #0] @ Save on the stack -@ -@ /* Actually build the stack frame. */ -@ - MOV r3, #0 @ Build initial register value - STR r3, [r2, #4] @ Store initial r4 - STR r3, [r2, #8] @ Store initial r5 - STR r3, [r2, #12] @ Store initial r6 - STR r3, [r2, #16] @ Store initial r7 - STR r3, [r2, #20] @ Store initial r8 - STR r3, [r2, #24] @ Store initial r9 - STR r3, [r2, #28] @ Store initial r10 - STR r3, [r2, #32] @ Store initial r11 -@ -@ /* 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 - MOV r3, #0xFFFFFFFF @ Poison EXC_RETURN value - STR r3, [r2, #56] @ Store initial lr - STR r1, [r2, #60] @ Store initial pc - MOV 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 -@} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 +// } diff --git a/ports/cortex_m4/gnu/src/tx_thread_system_return.S b/ports/cortex_m4/gnu/src/tx_thread_system_return.S index 1a799fd4..3783ccd7 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m4/gnu/src/tx_thread_system_return.S @@ -1,90 +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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_system_return Cortex-M4/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* VOID _tx_thread_system_return(VOID) -@{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M4/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { .thumb_func .global _tx_thread_system_return _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. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ 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 -@/* } */ + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif +_isr_context: + BX lr // Return to caller +// } diff --git a/ports/cortex_m4/gnu/src/tx_timer_interrupt.S b/ports/cortex_m4/gnu/src/tx_timer_interrupt.S index 35923a33..810f959e 100644 --- a/ports/cortex_m4/gnu/src/tx_timer_interrupt.S +++ b/ports/cortex_m4/gnu/src/tx_timer_interrupt.S @@ -1,259 +1,250 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_timer_time_slice - .global _tx_timer_system_clock - .global _tx_timer_current_ptr - .global _tx_timer_list_start - .global _tx_timer_list_end - .global _tx_timer_expired_time_slice - .global _tx_timer_expired - .global _tx_thread_time_slice - .global _tx_timer_expiration_process -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_timer_time_slice + .global _tx_timer_system_clock + .global _tx_timer_current_ptr + .global _tx_timer_list_start + .global _tx_timer_list_end + .global _tx_timer_expired_time_slice + .global _tx_timer_expired + .global _tx_thread_time_slice + .global _tx_timer_expiration_process + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_timer_interrupt Cortex-M4/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_timer_interrupt(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M4/GNU */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { .global _tx_timer_interrupt .thumb_func _tx_timer_interrupt: -@ -@ /* Upon entry to this routine, it is assumed that context save has already -@ been called, and therefore the compiler scratch registers are available -@ for use. */ -@ -@ /* Increment the system clock. */ -@ _tx_timer_system_clock++; -@ - LDR r1, =_tx_timer_system_clock @ Pickup address of system clock - LDR r0, [r1, #0] @ Pickup system clock - ADD r0, r0, #1 @ Increment system clock - STR r0, [r1, #0] @ Store new system clock -@ -@ /* Test for time-slice expiration. */ -@ if (_tx_timer_time_slice) -@ { -@ - LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice - LDR r2, [r3, #0] @ Pickup time-slice - CMP r2, #0 @ Is it non-active? - BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing -@ -@ /* Decrement the time_slice. */ -@ _tx_timer_time_slice--; -@ - SUB 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) -@ - CMP r2, #0 @ Has it expired? - BNE __tx_timer_no_time_slice @ No, skip expiration processing -@ -@ /* Set the time-slice expired flag. */ -@ _tx_timer_expired_time_slice = TX_TRUE; -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag - MOV r0, #1 @ Build expired value - STR r0, [r3, #0] @ Set time-slice expiration flag -@ -@ } -@ + + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) -@ { -@ - LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address - LDR r0, [r1, #0] @ Pickup current timer - LDR r2, [r0, #0] @ Pickup timer list entry - CMP r2, #0 @ Is there anything in the list? - BEQ __tx_timer_no_timer @ No, just increment the timer -@ -@ /* Set expiration flag. */ -@ _tx_timer_expired = TX_TRUE; -@ - LDR r3, =_tx_timer_expired @ Pickup expiration flag address - MOV r2, #1 @ Build expired value - STR r2, [r3, #0] @ Set expired flag - B __tx_timer_done @ Finished timer processing -@ -@ } -@ else -@ { + + /* Test for timer expiration. */ + // if (*_tx_timer_current_ptr) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; -@ - ADD r0, r0, #4 @ Move to next timer -@ -@ /* Check for wrap-around. */ -@ if (_tx_timer_current_ptr == _tx_timer_list_end) -@ - LDR r3, =_tx_timer_list_end @ Pickup addr of 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; -@ - LDR r3, =_tx_timer_list_start @ Pickup addr of timer list start - LDR r0, [r3, #0] @ Set current pointer to list start -@ + + /* No timer expired, increment the timer pointer. */ + // _tx_timer_current_ptr++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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 -@ } -@ + + 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)) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of expired flag - LDR r2, [r3, #0] @ Pickup time-slice expired flag - CMP r2, #0 @ Did a time-slice expire? - BNE __tx_something_expired @ If non-zero, time-slice expired - LDR r1, =_tx_timer_expired @ Pickup addr of other expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Did a timer expire? - BEQ __tx_timer_nothing_expired @ No, nothing expired -@ + + /* See if anything has expired. */ + // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + __tx_something_expired: -@ -@ - STMDB sp!, {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) -@ { -@ - LDR r1, =_tx_timer_expired @ Pickup addr of expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Check for timer expiration - BEQ __tx_timer_dont_activate @ If not set, skip timer activation -@ -@ /* Process timer expiration. */ -@ _tx_timer_expiration_process(); -@ - BL _tx_timer_expiration_process @ Call the timer expiration handling routine -@ -@ } + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of time-slice expired - LDR r2, [r3, #0] @ Pickup the actual flag - CMP r2, #0 @ See if the flag is set - BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing -@ -@ /* Time slice interrupted thread. */ -@ _tx_thread_time_slice(); -@ - BL _tx_thread_time_slice @ Call time-slice processing - LDR r0, =_tx_thread_preempt_disable @ Build address of preempt disable flag - LDR r1, [r0] @ Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice @ Yes, skip the PendSV logic - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r1, [r0] @ Pickup the current thread pointer - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - 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 + + /* Did time slice expire? */ + // if (_tx_timer_expired_time_slice) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -@ - LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for - @ the 8-byte stack alignment -@ -@ } -@ + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB @ Complete all memory access - BX lr @ Return to caller -@ -@} + DSB // Complete all memory access + BX lr // Return to caller +// } diff --git a/ports/cortex_m4/iar/inc/tx_port.h b/ports/cortex_m4/iar/inc/tx_port.h index 11955598..e5f949a8 100644 --- a/ports/cortex_m4/iar/inc/tx_port.h +++ b/ports/cortex_m4/iar/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M4/IAR */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -73,11 +73,29 @@ #include #include -#include + +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #include #endif +#endif /* __ICCARM__ */ +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -88,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -115,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX ARM Cortex-M port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -137,7 +156,7 @@ typedef unsigned short USHORT; #ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -148,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -166,7 +199,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 @@ -180,24 +213,26 @@ 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 -#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT -#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ #else -#define TX_THREAD_EXTENSION_2 -#endif -#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -#define TX_THREAD_EXTENSION_3 -#else -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; +#define TX_THREAD_EXTENSION_2 #endif +#define TX_THREAD_EXTENSION_3 + + + /* Define the port extensions of the remaining ThreadX objects. */ #define TX_BLOCK_POOL_EXTENSION @@ -209,11 +244,11 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -223,27 +258,26 @@ ULONG _tx_misra_time_stamp_get(VOID); #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #if (__VER__ < 8000000) -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); #else void *_tx_iar_create_per_thread_tls_area(void); void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); void __iar_Initlocks(void); -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); -#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); #endif #else -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __ARMVFP__ +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -252,28 +286,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#endif +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -283,76 +360,76 @@ void _tx_misra_vfp_touch(void); #ifndef TX_MISRA_ENABLE -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((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 = _tx_vfp_state & ((ULONG) 0x4); \ - __asm volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -377,16 +454,38 @@ void _tx_misra_vfp_touch(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) -#else + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -395,35 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m))); - +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -#ifdef TX_DISABLE_INLINE +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -431,56 +684,22 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save; -#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();}; -#define TX_RESTORE {__set_interrupt_state(interrupt_save);}; - -#define _tx_thread_system_return _tx_thread_system_return_inline - -static void _tx_thread_system_return_inline(void) -{ -__istate_t interrupt_save; - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_IPSR() == 0) - { - interrupt_save = __get_interrupt_state(); - __enable_interrupt(); - __set_interrupt_state(interrupt_save); - } -} - -#endif +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. 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); -/* Define the interrupt lockout macros for each ThreadX object. */ - -#define TX_BLOCK_POOL_DISABLE TX_DISABLE -#define TX_BYTE_POOL_DISABLE TX_DISABLE -#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE -#define TX_MUTEX_DISABLE TX_DISABLE -#define TX_QUEUE_DISABLE TX_DISABLE -#define TX_SEMAPHORE_DISABLE TX_DISABLE - - /* 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-M4/IAR Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/IAR Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -491,6 +710,3 @@ extern CHAR _tx_version_id[]; #endif - - - diff --git a/ports/cortex_m4/iar/readme_threadx.txt b/ports/cortex_m4/iar/readme_threadx.txt index cd999e46..28b54e03 100644 --- a/ports/cortex_m4/iar/readme_threadx.txt +++ b/ports/cortex_m4/iar/readme_threadx.txt @@ -1,6 +1,6 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M4 - - Using the IAR Tools + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using IAR EWARM Tools 1. Building the ThreadX run-time Library @@ -25,12 +25,12 @@ Workbench, and select the "Make" button. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.out is a binary ELF file that can be downloaded and executed on the IAR Windows-based -Cortex-M4 simulator. +Cortex-M simulator. 3. System Initialization -The entry point in ThreadX for the Cortex-M4 using IAR tools is at label +The entry point in ThreadX for the Cortex-M using IAR tools is at label __iar_program_start. This is defined within the IAR compiler's startup code. In addition, this is where all static and global preset C variable initialization processing takes place. @@ -52,7 +52,7 @@ other RAM sections in memory. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M4 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. @@ -60,7 +60,7 @@ Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -82,7 +82,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -140,7 +140,7 @@ The distribution version of ThreadX is built without any compiler optimizations. This makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. Of course, this costs some performance. To make it run faster, you can change the ThreadX library -project to enable various compiler optimizations. +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING @@ -149,7 +149,7 @@ defined. 6. Interrupt Handling -The Cortex-M4 vectors start at the label __vector_table and is defined in cstartup_M.s. +The Cortex-M vectors start at the label __vector_table and is defined in cstartup_M.s. The application may modify the vector area according to its needs. @@ -172,23 +172,14 @@ ISRs written in assembly language will take the form: PUBLIC your_assembly_isr your_assembly_isr: - PUSH {lr} + PUSH {r0, lr} ; ISR processing goes here, including any needed function calls. - POP {lr} + POP {r0, lr} BX lr -7. IAR Thread-safe Library Support - -Thread-safe support for the IAR tools is easily enabled by building the ThreadX library -and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file -should have the following line added (if not already in place): - -initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application - - 7. IAR Thread-safe Library Support Thread-safe support for the IAR tools is easily enabled by building the ThreadX library @@ -203,7 +194,7 @@ The project options "General Options -> Library Configuration" should also have 8. VFP Support -ThreadX for Cortex-M4 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread context - no additional setup by the application. @@ -214,16 +205,10 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M4 using IAR's ARM tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using IAR's ARM tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m4/iar/src/tx_thread_context_restore.s b/ports/cortex_m4/iar/src/tx_thread_context_restore.s index 850fefa9..02aeae3d 100644 --- a/ports/cortex_m4/iar/src/tx_thread_context_restore.s +++ b/ports/cortex_m4/iar/src/tx_thread_context_restore.s @@ -1,89 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_execution_isr_exit -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function restores the interrupt context if it is processing a */ -;/* nested interrupt. If not, it returns to the interrupt thread if no */ -;/* preemption is necessary. Otherwise, if preemption is necessary or */ -;/* if no thread was running, the function returns to the scheduler. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* [_tx_execution_isr_exit] Execution profiling ISR exit */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs Interrupt Service Routines */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_restore(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M4/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { PUBLIC _tx_thread_context_restore _tx_thread_context_restore: -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR exit function to indicate an ISR is complete. */ -; - PUSH {r0, lr} ; Save return address - BL _tx_execution_isr_exit ; Call the ISR exit function - POP {r0, lr} ; Save return address +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address #endif -; - POP {lr} + BX lr -; -;} +// } END diff --git a/ports/cortex_m4/iar/src/tx_thread_context_save.s b/ports/cortex_m4/iar/src/tx_thread_context_save.s index 46cc01d0..a2a6f84c 100644 --- a/ports/cortex_m4/iar/src/tx_thread_context_save.s +++ b/ports/cortex_m4/iar/src/tx_thread_context_save.s @@ -1,87 +1,80 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_execution_isr_enter -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_save Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function saves the context of an executing thread in the */ -;/* beginning of interrupt processing. The function also ensures that */ -;/* the system stack is used upon return to the calling ISR. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* None */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M4/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_enter] Execution profiling ISR enter */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { PUBLIC _tx_thread_context_save _tx_thread_context_save: -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR enter function to indicate an ISR is starting. */ -; - PUSH {r0, lr} ; Save return address - BL _tx_execution_isr_enter ; Call the ISR enter function - POP {r0, lr} ; Recover return address + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address #endif -; -; /* Context is already saved - just return! */ -; + + /* Context is already saved - just return. */ + BX lr -;} +// } END diff --git a/ports/cortex_m4/iar/src/tx_thread_interrupt_control.s b/ports/cortex_m4/iar/src/tx_thread_interrupt_control.s index c903f17b..04ca281a 100644 --- a/ports/cortex_m4/iar/src/tx_thread_interrupt_control.s +++ b/ports/cortex_m4/iar/src/tx_thread_interrupt_control.s @@ -1,74 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_control Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_control(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M4/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { PUBLIC _tx_thread_interrupt_control _tx_thread_interrupt_control: - MRS r1, PRIMASK ; Pickup current interrupt lockout - MSR PRIMASK, r0 ; Apply the new interrupt lockout - MOV r0, r1 ; Transfer old to return register - BX lr ; Return to caller -; -;} +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } END diff --git a/ports/cortex_m4/iar/src/tx_thread_interrupt_disable.s b/ports/cortex_m4/iar/src/tx_thread_interrupt_disable.s index 5577555c..d33d2b15 100644 --- a/ports/cortex_m4/iar/src/tx_thread_interrupt_disable.s +++ b/ports/cortex_m4/iar/src/tx_thread_interrupt_disable.s @@ -1,76 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_disable(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M4/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { PUBLIC _tx_thread_interrupt_disable _tx_thread_interrupt_disable: -; -; /* Return current interrupt lockout posture. */ -; + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_USE_BASEPRI + MSR BASEPRI, r1 +#else MRS r0, PRIMASK CPSID i +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m4/iar/src/tx_thread_interrupt_restore.s b/ports/cortex_m4/iar/src/tx_thread_interrupt_restore.s index 10baa764..2ef3fb36 100644 --- a/ports/cortex_m4/iar/src/tx_thread_interrupt_restore.s +++ b/ports/cortex_m4/iar/src/tx_thread_interrupt_restore.s @@ -1,75 +1,75 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_interrupt_restore(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M4/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { PUBLIC _tx_thread_interrupt_restore _tx_thread_interrupt_restore: -; -; /* Restore previous interrupt lockout posture. */ -; + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else MSR PRIMASK, r0 +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m4/iar/src/tx_thread_schedule.s b/ports/cortex_m4/iar/src/tx_thread_schedule.s index 45008ba3..1d48c61e 100644 --- a/ports/cortex_m4/iar/src/tx_thread_schedule.s +++ b/ports/cortex_m4/iar/src/tx_thread_schedule.s @@ -1,302 +1,279 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_timer_time_slice - EXTERN _tx_thread_system_stack_ptr + EXTERN _tx_thread_preempt_disable EXTERN _tx_execution_thread_enter EXTERN _tx_execution_thread_exit - EXTERN _tx_thread_preempt_disable #ifdef TX_LOW_POWER EXTERN tx_low_power_enter EXTERN tx_low_power_exit #endif -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M4/IAR */ -;/* 6.1.5 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* _tx_thread_context_restore Restore thread's context */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* 03-02-2021 Scott Larson Modified comment(s), add */ -;/* low power code, */ -;/* resulting in version 6.1.5 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_schedule(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M4/IAR */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { PUBLIC _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 -; -; /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -; + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + #ifdef __ARMVFP__ - MRS r0, CONTROL ; Pickup current CONTROL register - BIC r0, r0, #4 ; Clear the FPCA bit - MSR CONTROL, r0 ; Setup new CONTROL register + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register #endif -; -; /* Enable interrupts */ -; + + /* Enable interrupts */ CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR - DSB ; Complete all memory accesses - ISB ; Flush pipeline -; -; /* Wait here for the PendSV to take place. */ -; + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 PendSV handler. */ -; + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + PUBLIC PendSV_Handler PUBLIC __tx_PendSVHandler PendSV_Handler: __tx_PendSVHandler: -; -; /* Get current thread value and new thread pointer. */ -; + + /* Get current thread value and new thread pointer. */ + __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, lr} ; Recover LR - CPSIE i ; Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers #ifdef __ARMVFP__ - TST LR, #0x10 ; Determine if the VFP extended frame is present + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} ; Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save: #endif - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack -; -; /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -; - LDR r5, [r4] ; Pickup current time-slice - STR r12, [r1, #8] ; Save the thread stack pointer - 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. */ -; - STR r3, [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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack -#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 r3 + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 #endif -; -; /* Restore the thread context and PSP. */ -; - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR #ifdef __ARMVFP__ - TST LR, #0x10 ; Determine if the VFP extended frame is present - BNE _skip_vfp_restore ; If not, skip VFP restore - VLDMIA r12!, {s16-s31} ; Yes, restore additional VFP registers + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore: #endif - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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. */ -; + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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! */ -; + 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: - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread -;} -; + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + #ifdef __ARMVFP__ PUBLIC tx_thread_fpu_enable tx_thread_fpu_enable: -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller - PUBLIC tx_thread_fpu_disable tx_thread_fpu_disable: -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller #endif - END diff --git a/ports/cortex_m4/iar/src/tx_thread_stack_build.s b/ports/cortex_m4/iar/src/tx_thread_stack_build.s index 493ee69d..0a2ee915 100644 --- a/ports/cortex_m4/iar/src/tx_thread_stack_build.s +++ b/ports/cortex_m4/iar/src/tx_thread_stack_build.s @@ -1,134 +1,132 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_stack_build Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M4/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { PUBLIC _tx_thread_stack_build _tx_thread_stack_build: -; -; -; /* Build a fake interrupt frame. The form of the fake interrupt stack -; on the Cortex-M should look like the following after it is built: -; -; Stack Top: -; LR Interrupted LR (LR at time of PENDSV) -; r4 Initial value for r4 -; r5 Initial value for r5 -; r6 Initial value for r6 -; r7 Initial value for r7 -; r8 Initial value for r8 -; r9 Initial value for r9 -; r10 Initial value for r10 -; r11 Initial value for r11 -; 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 - BIC r2, r2, #0x7 ; Align frame for 8-byte alignment - SUB r2, r2, #68 ; Subtract frame size - LDR r3, =0xFFFFFFFD ; Build initial LR value - STR r3, [r2, #0] ; Save on the stack -; -; /* Actually build the stack frame. */ -; - MOV r3, #0 ; Build initial register value - STR r3, [r2, #4] ; Store initial r4 - STR r3, [r2, #8] ; Store initial r5 - STR r3, [r2, #12] ; Store initial r6 - STR r3, [r2, #16] ; Store initial r7 - STR r3, [r2, #20] ; Store initial r8 - STR r3, [r2, #24] ; Store initial r9 - STR r3, [r2, #28] ; Store initial r10 - STR r3, [r2, #32] ; Store initial r11 -; -; /* 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 - MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value - STR r3, [r2, #56] ; Store initial lr - STR r1, [r2, #60] ; Store initial pc - MOV 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 -;} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 diff --git a/ports/cortex_m4/iar/src/tx_thread_system_return.s b/ports/cortex_m4/iar/src/tx_thread_system_return.s index 4ea6aa72..b95770d5 100644 --- a/ports/cortex_m4/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m4/iar/src/tx_thread_system_return.s @@ -1,87 +1,92 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_system_return Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_system_return(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M4/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { PUBLIC _tx_thread_system_return -_tx_thread_system_return??rA: _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. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 + + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif _isr_context: - BX lr ; Return to caller -;} + BX lr // Return to caller +// } END diff --git a/ports/cortex_m4/iar/src/tx_timer_interrupt.s b/ports/cortex_m4/iar/src/tx_timer_interrupt.s index dabf7e1c..f99d1755 100644 --- a/ports/cortex_m4/iar/src/tx_timer_interrupt.s +++ b/ports/cortex_m4/iar/src/tx_timer_interrupt.s @@ -1,26 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_timer_time_slice EXTERN _tx_timer_system_clock EXTERN _tx_timer_current_ptr @@ -33,224 +32,221 @@ EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_thread_preempt_disable -; -; + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M4/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* expiration functions are called. */ -;/* */ -;/* 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_timer_interrupt(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M4/IAR */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { PUBLIC _tx_timer_interrupt _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++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock - LDR r0, [r1, #0] ; Pickup system clock - ADD r0, r0, #1 ; Increment system clock - STR r0, [r1, #0] ; Store new system clock -; -; /* Test for time-slice expiration. */ -; if (_tx_timer_time_slice) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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--; -; - SUB 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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++; -; - ADD r0, r0, #4 ; Move to next timer -; -; /* Check for wrap-around. */ -; if (_tx_timer_current_ptr == _tx_timer_list_end) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired: -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + +__tx_something_expired: + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for - ; the 8-byte stack alignment -; -; } -; + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB ; Complete all memory access - BX lr ; Return to caller -; -;} + DSB // Complete all memory access + BX lr // Return to caller +// } END diff --git a/ports/cortex_m4/keil/inc/tx_port.h b/ports/cortex_m4/keil/inc/tx_port.h index e1c5ac2e..300a2a6c 100644 --- a/ports/cortex_m4/keil/inc/tx_port.h +++ b/ports/cortex_m4/keil/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M4/Keil */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,7 +156,7 @@ typedef unsigned short USHORT; #ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -144,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -162,7 +199,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 @@ -176,13 +213,24 @@ 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -196,11 +244,11 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -208,18 +256,28 @@ ULONG _tx_misra_time_stamp_get(VOID); tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - - -#ifndef TX_MISRA_ENABLE - -register unsigned int _ipsr __asm("ipsr"); +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __TARGET_FPU_VFP +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,35 +286,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -#ifdef TX_SOURCE_CODE +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ -register ULONG _control __asm("control"); +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ -#endif -#endif /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -266,78 +360,76 @@ register ULONG _control __asm("control"); #ifndef TX_MISRA_ENABLE -void _tx_vfp_access(void); - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_vfp_access(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -362,16 +454,38 @@ void _tx_vfp_access(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -380,35 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -#ifdef TX_DISABLE_INLINE +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -416,37 +684,11 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); - -#define _tx_thread_system_return _tx_thread_system_return_inline +#endif /* TX_DISABLE_INLINE */ -static void _tx_thread_system_return_inline(void) -{ -unsigned int was_masked; - - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (_ipsr == 0) - { - was_masked = __disable_irq(); - __enable_irq(); - if (was_masked != 0) - __disable_irq(); - } -} -#endif - - -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. 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); @@ -456,8 +698,8 @@ void tx_thread_fpu_disable(void); /* 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-M4/Keil Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4/Keil Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -468,7 +710,3 @@ extern CHAR _tx_version_id[]; #endif - - - - diff --git a/ports/cortex_m7/ac5/inc/tx_port.h b/ports/cortex_m7/ac5/inc/tx_port.h index 21483048..c08585c0 100644 --- a/ports/cortex_m7/ac5/inc/tx_port.h +++ b/ports/cortex_m7/ac5/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M7/AC5 */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,7 +156,7 @@ typedef unsigned short USHORT; #ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -144,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -162,7 +199,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 @@ -176,13 +213,24 @@ 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -196,11 +244,11 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -208,18 +256,28 @@ ULONG _tx_misra_time_stamp_get(VOID); tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - - -#ifndef TX_MISRA_ENABLE - -register unsigned int _ipsr __asm("ipsr"); +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __TARGET_FPU_VFP +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,35 +286,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -#ifdef TX_SOURCE_CODE +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ -register ULONG _control __asm("control"); +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ -#endif -#endif /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -266,78 +360,76 @@ register ULONG _control __asm("control"); #ifndef TX_MISRA_ENABLE -void _tx_vfp_access(void); - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_vfp_access(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -362,16 +454,38 @@ void _tx_vfp_access(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -380,35 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -#ifdef TX_DISABLE_INLINE +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -416,37 +684,11 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); - -#define _tx_thread_system_return _tx_thread_system_return_inline +#endif /* TX_DISABLE_INLINE */ -static void _tx_thread_system_return_inline(void) -{ -unsigned int was_masked; - - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (_ipsr == 0) - { - was_masked = __disable_irq(); - __enable_irq(); - if (was_masked != 0) - __disable_irq(); - } -} -#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-M. 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); @@ -456,8 +698,8 @@ void tx_thread_fpu_disable(void); /* 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-M7/AC5 Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/AC5 Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -468,7 +710,3 @@ extern CHAR _tx_version_id[]; #endif - - - - diff --git a/ports/cortex_m7/ac5/readme_threadx.txt b/ports/cortex_m7/ac5/readme_threadx.txt index 24dd565c..b7b7cee9 100644 --- a/ports/cortex_m7/ac5/readme_threadx.txt +++ b/ports/cortex_m7/ac5/readme_threadx.txt @@ -1,12 +1,11 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M7 + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using ARM Compiler 5 (AC5) - Thumb & 32-bit Mode - Using ARM Compiler 5 (AC5) - 1. Building the ThreadX run-time Library -First make sure you are in the "example_build" directory. Also, make sure that +Navigate to the "example_build" directory. Ensure that you have setup your path and other environment variables necessary for the AC5 compiler. At this point you may run the build_threadx.bat batch file. This will build the ThreadX run-time environment in the "example_build" directory. @@ -19,21 +18,21 @@ application in order to use ThreadX. 2. Demonstration System -The ThreadX demonstration is designed to execute under the ARM DS Cortex-M7 +The ThreadX demonstration is designed to execute under the ARM DS Cortex-M simulator. Building the demonstration is easy; simply execute the build_threadx_sample.bat -batch file while inside the "example_build" directory. +batch file while inside the "example_build" directory. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.axf -is a binary file that can be downloaded and executed on the ARM DS Cortex-M7 +is a binary file that can be downloaded and executed on the ARM DS Cortex-M simulator. 3. System Initialization -The entry point in ThreadX for the Cortex-M7 using AC5 tools is at label +The entry point in ThreadX for the Cortex-M using AC5 tools is at label __main. This is defined within the AC5 compiler's startup code. In addition, this is where all static and global pre-set C variable initialization processing takes place. @@ -51,7 +50,7 @@ parameter to your application definition function, tx_application_define. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M7 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. @@ -59,7 +58,7 @@ Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -81,7 +80,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -138,8 +137,8 @@ FPU Stack Frame (only interrupted thread with FPU enabled): The distribution version of ThreadX is built without any compiler optimizations. This makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. Of course, this costs some -performance. To make it run faster, you can change the ThreadX_Library.Uv2 -project to debugging and enable all compiler optimizations. +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING @@ -148,14 +147,14 @@ defined. 6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M7 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: 6.1 Vector Area -The Cortex-M7 vectors start at the label __tx_vectors. The application may modify +The Cortex-M vectors start at the label __tx_vectors. The application may modify the vector area according to its needs. @@ -188,7 +187,7 @@ your_assembly_isr 7. FPU Support -ThreadX for Cortex-M7 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread context - no additional setup by the application. @@ -199,17 +198,10 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - tx_thread_schedule.s Fix compilation error - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M7 using AC5 tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using AC5 tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m7/ac5/src/tx_thread_context_restore.s b/ports/cortex_m7/ac5/src/tx_thread_context_restore.s index d63c29c8..b14f539c 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_context_restore.s +++ b/ports/cortex_m7/ac5/src/tx_thread_context_restore.s @@ -1,91 +1,83 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_exit - ENDIF -; -; +#endif + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function restores the interrupt context if it is processing a */ -;/* nested interrupt. If not, it returns to the interrupt thread if no */ -;/* preemption is necessary. Otherwise, if preemption is necessary or */ -;/* if no thread was running, the function returns to the scheduler. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* _tx_thread_schedule Thread scheduling routine */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs Interrupt Service Routines */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_restore(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M7/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { EXPORT _tx_thread_context_restore _tx_thread_context_restore - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR exit function to indicate an ISR is complete. */ -; - PUSH {r0,lr} ; Save ISR lr - BL _tx_execution_isr_exit ; Call the ISR exit function - POP {r0,lr} ; Restore ISR lr - ENDIF -; - POP {lr} + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -;} +// } ALIGN LTORG END diff --git a/ports/cortex_m7/ac5/src/tx_thread_context_save.s b/ports/cortex_m7/ac5/src/tx_thread_context_save.s index 55747b13..9600e9fb 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_context_save.s +++ b/ports/cortex_m7/ac5/src/tx_thread_context_save.s @@ -1,91 +1,85 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_isr_enter - ENDIF -; -; +#endif + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_save Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function saves the context of an executing thread in the */ -;/* beginning of interrupt processing. The function also ensures that */ -;/* the system stack is used upon return to the calling ISR. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* None */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M7/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { EXPORT _tx_thread_context_save _tx_thread_context_save - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR enter function to indicate an ISR is executing. */ -; - PUSH {r0, lr} ; Save ISR lr - BL _tx_execution_isr_enter ; Call the ISR enter function - POP {r0, lr} ; Recover ISR lr - ENDIF -; -; /* Return to interrupt processing. */ -; - BX lr ; Return to interrupt processing caller -;} + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + + BX lr +// } ALIGN LTORG END diff --git a/ports/cortex_m7/ac5/src/tx_thread_interrupt_control.s b/ports/cortex_m7/ac5/src/tx_thread_interrupt_control.s index 059053b5..4aec6856 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_interrupt_control.s +++ b/ports/cortex_m7/ac5/src/tx_thread_interrupt_control.s @@ -1,76 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_control Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_control(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M7/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { EXPORT _tx_thread_interrupt_control _tx_thread_interrupt_control -; -; /* Pickup current interrupt lockout posture. */ -; - MRS r1, PRIMASK - MSR PRIMASK, r0 - MOV r0, r1 - BX lr -; -;} +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } END diff --git a/ports/cortex_m7/ac5/src/tx_thread_interrupt_disable.s b/ports/cortex_m7/ac5/src/tx_thread_interrupt_disable.s index 0030e9a4..1e620791 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_interrupt_disable.s +++ b/ports/cortex_m7/ac5/src/tx_thread_interrupt_disable.s @@ -1,75 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_disable Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_disable(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M7/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { EXPORT _tx_thread_interrupt_disable _tx_thread_interrupt_disable -; -; /* Return current interrupt lockout posture. */ -; + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else MRS r0, PRIMASK CPSID i +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m7/ac5/src/tx_thread_interrupt_restore.s b/ports/cortex_m7/ac5/src/tx_thread_interrupt_restore.s index 8bb8fea2..c3e8e9a7 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_interrupt_restore.s +++ b/ports/cortex_m7/ac5/src/tx_thread_interrupt_restore.s @@ -1,74 +1,75 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_interrupt_restore(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M7/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { EXPORT _tx_thread_interrupt_restore _tx_thread_interrupt_restore -; -; /* Restore previous interrupt lockout posture. */ -; + + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else MSR PRIMASK, r0 +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m7/ac5/src/tx_thread_schedule.s b/ports/cortex_m7/ac5/src/tx_thread_schedule.s index 92ef04c9..a7bfb59e 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_schedule.s +++ b/ports/cortex_m7/ac5/src/tx_thread_schedule.s @@ -1,307 +1,285 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IMPORT _tx_thread_current_ptr IMPORT _tx_thread_execute_ptr IMPORT _tx_timer_time_slice IMPORT _tx_thread_system_stack_ptr IMPORT _tx_thread_preempt_disable - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) IMPORT _tx_execution_thread_enter IMPORT _tx_execution_thread_exit - ENDIF - IF :DEF:TX_LOW_POWER - IMPORT tx_low_power_enter - IMPORT tx_low_power_exit - ENDIF -; -; - AREA ||.text||, CODE, READONLY +#endif + + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M7/AC5 */ -;/* 6.1.5 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* _tx_thread_context_restore Restore thread's context */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* 03-02-2021 Scott Larson Modified comment(s), add */ -;/* low power code, */ -;/* resulting in version 6.1.5 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_schedule(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M7/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { EXPORT _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 -; -; /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -; - IF {TARGET_FPU_VFP} = {TRUE} - MRS r0, CONTROL ; Pickup current CONTROL register - BIC r0, r0, #4 ; Clear the FPCA bit - MSR CONTROL, r0 ; Setup new CONTROL register - ENDIF -; -; /* Enable the interrupts */ -; + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __TARGET_FPU_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register +#endif + + /* Enable interrupts */ CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR - DSB ; Complete all memory accesses - ISB ; Flush pipeline -; -; /* Wait here for the PendSV to take place. */ -; + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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. */ -; + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + EXPORT __tx_PendSVHandler EXPORT PendSV_Handler __tx_PendSVHandler PendSV_Handler -; -; /* Get current thread value and new thread pointer. */ -; + + /* Get current thread value and new thread pointer. */ + __tx_ts_handler - IF :DEF: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, lr} ; Recover LR - CPSIE i ; Enable interrupts - ENDIF - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers - IF {TARGET_FPU_VFP} = {TRUE} - TST LR, #0x10 ; Determine if the VFP extended frame is present +#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 + 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 + CPSIE i // Enable interrupts +#endif + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __TARGET_FPU_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} ; Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save - ENDIF - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack -; -; /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -; - LDR r5, [r4] ; Pickup current time-slice - STR r12, [r1, #8] ; Save the thread stack pointer - 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. */ -; - STR r3, [r4] ; Clear time-slice -; -; /* Executing thread is now completely preserved!!! */ -; +#endif + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack + + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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. */ -; + + /* 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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 + LDR r7, [r1, #4] // Pickup the current thread run count + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD r7, r7, #1 // Increment the thread run count + STR r7, [r1, #4] // Store the new run count - IF :DEF: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 r3 - ENDIF -; -; /* Restore the thread context and PSP. */ -; - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR - IF {TARGET_FPU_VFP} = {TRUE} - TST LR, #0x10 ; Determine if the VFP extended frame is present - BNE _skip_vfp_restore ; If not, skip VFP restore - VLDMIA r12!, {s16-s31} ; Yes, restore additional VFP registers + /* Setup global time-slice with thread's current time-slice. */ + + STR r5, [r4] // Setup global time-slice + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 +#endif + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __TARGET_FPU_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore - ENDIF - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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. */ -; +#endif + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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! - IF :DEF:TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode - POP {r0-r3} - ENDIF +#ifdef TX_LOW_POWER + BL tx_low_power_enter // Possibly enter low power mode +#endif - IF :DEF:TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed - ENDIF +#ifdef TX_ENABLE_WFI + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed +#endif - IF :DEF:TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode - POP {r0-r3} - ENDIF +#ifdef TX_LOW_POWER + BL tx_low_power_exit // Exit low power mode +#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! */ - 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 - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV - IF {TARGET_FPU_VFP} = {TRUE} + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __TARGET_FPU_VFP EXPORT tx_thread_fpu_enable tx_thread_fpu_enable -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller - EXPORT tx_thread_fpu_disable tx_thread_fpu_disable -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller EXPORT _tx_vfp_access _tx_vfp_access - VMOV.F32 s0, s0 ; Simply access the VFP - BX lr ; Return to caller + VMOV.F32 s0, s0 // Simply access the VFP + BX lr // Return to caller - ENDIF +#endif ALIGN LTORG diff --git a/ports/cortex_m7/ac5/src/tx_thread_stack_build.s b/ports/cortex_m7/ac5/src/tx_thread_stack_build.s index 73fcccf2..6b0a449f 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_stack_build.s +++ b/ports/cortex_m7/ac5/src/tx_thread_stack_build.s @@ -1,133 +1,131 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_stack_build Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M7/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { EXPORT _tx_thread_stack_build _tx_thread_stack_build -; -; -; /* Build a fake interrupt frame. The form of the fake interrupt stack -; on the Cortex-M7 should look like the following after it is built: -; -; Stack Top: -; LR Interrupted LR (LR at time of PENDSV) -; r4 Initial value for r4 -; r5 Initial value for r5 -; r6 Initial value for r6 -; r7 Initial value for r7 -; r8 Initial value for r8 -; r9 Initial value for r9 -; r10 Initial value for r10 -; r11 Initial value for r11 -; 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 - BIC r2, r2, #0x7 ; Align frame for 8-byte alignment - SUB r2, r2, #68 ; Subtract frame size - LDR r3, =0xFFFFFFFD ; Build initial LR value - STR r3, [r2, #0] ; Save on the stack -; -; /* Actually build the stack frame. */ -; - MOV r3, #0 ; Build initial register value - STR r3, [r2, #4] ; Store initial r4 - STR r3, [r2, #8] ; Store initial r5 - STR r3, [r2, #12] ; Store initial r6 - STR r3, [r2, #16] ; Store initial r7 - STR r3, [r2, #20] ; Store initial r8 - STR r3, [r2, #24] ; Store initial r9 - STR r3, [r2, #28] ; Store initial r10 - STR r3, [r2, #32] ; Store initial r11 -; -; /* 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 - MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value - STR r3, [r2, #56] ; Store initial lr - STR r1, [r2, #60] ; Store initial pc - MOV 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 -;} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 diff --git a/ports/cortex_m7/ac5/src/tx_thread_system_return.s b/ports/cortex_m7/ac5/src/tx_thread_system_return.s index 917abbc8..26c3d402 100644 --- a/ports/cortex_m7/ac5/src/tx_thread_system_return.s +++ b/ports/cortex_m7/ac5/src/tx_thread_system_return.s @@ -1,85 +1,91 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_system_return Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_system_return(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M7/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { EXPORT _tx_thread_system_return _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. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 + + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif _isr_context - BX lr ; Return to caller -;} + BX lr // Return to caller +// } END diff --git a/ports/cortex_m7/ac5/src/tx_timer_interrupt.s b/ports/cortex_m7/ac5/src/tx_timer_interrupt.s index d18bbd08..38fec7e4 100644 --- a/ports/cortex_m7/ac5/src/tx_timer_interrupt.s +++ b/ports/cortex_m7/ac5/src/tx_timer_interrupt.s @@ -1,26 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IMPORT _tx_timer_time_slice IMPORT _tx_timer_system_clock IMPORT _tx_timer_current_ptr @@ -33,227 +32,223 @@ IMPORT _tx_thread_preempt_disable IMPORT _tx_thread_current_ptr IMPORT _tx_thread_execute_ptr -; -; + AREA ||.text||, CODE, READONLY PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M7/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_timer_interrupt(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M7/AC5 */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { EXPORT _tx_timer_interrupt _tx_timer_interrupt -; -; /* Upon entry to this routine, it is assumed that context save has already -; been called, and therefore the compiler scratch registers are available -; for use. */ -; -; /* Increment the system clock. */ -; _tx_timer_system_clock++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock - LDR r0, [r1, #0] ; Pickup system clock - ADD r0, r0, #1 ; Increment system clock - STR r0, [r1, #0] ; Store new system clock -; -; /* Test for time-slice expiration. */ -; if (_tx_timer_time_slice) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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--; -; - SUB 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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++; -; - ADD r0, r0, #4 ; Move to next timer -; -; /* Check for wrap-around. */ -; if (_tx_timer_current_ptr == _tx_timer_list_end) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + +__tx_something_expired + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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 -; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for -; -; } -; + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired - DSB ; Complete all memory access - BX lr ; Return to caller -; -;} + DSB // Complete all memory access + BX lr // Return to caller +// } ALIGN LTORG END diff --git a/ports/cortex_m7/ac6/inc/tx_port.h b/ports/cortex_m7/ac6/inc/tx_port.h index 349eea9c..c66a2ace 100644 --- a/ports/cortex_m7/ac6/inc/tx_port.h +++ b/ports/cortex_m7/ac6/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M7/AC6 */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -74,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -131,46 +154,83 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#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 logic. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#endif /* 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -184,11 +244,11 @@ typedef unsigned short USHORT; #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -196,11 +256,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); -#ifdef TX_ENABLE_FPU_SUPPORT +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -209,26 +286,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) { - ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } - -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) { - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); } +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); -#endif +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -236,23 +336,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -261,77 +360,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((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 = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -356,126 +454,242 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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++; -/* This 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 +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - #endif -#ifndef TX_DISABLE_INLINE -/* Define AC6 specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; -unsigned int primask_value; + int_posture = __get_interrupt_posture(); - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) -{ - - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); -} - -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) -{ - -unsigned int primask_value; - - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); -} - -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) -{ - - __asm__ volatile (" CPSIE i": : : "memory" ); -} - - __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_ipsr_value() == 0) { - interrupt_save = __get_primask_value(); + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ #define _tx_thread_system_return _tx_thread_system_return_inline -#else +#else /* TX_DISABLE_INLINE is defined */ -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* 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-M. 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); @@ -484,16 +698,15 @@ void tx_thread_fpu_disable(void); /* 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-M7/AC6 Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/AC6 Version 6.1.7 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - - #endif - - - +#endif diff --git a/ports/cortex_m7/ac6/readme_threadx.txt b/ports/cortex_m7/ac6/readme_threadx.txt index 5519194e..d98c90cb 100644 --- a/ports/cortex_m7/ac6/readme_threadx.txt +++ b/ports/cortex_m7/ac6/readme_threadx.txt @@ -1,41 +1,39 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M7 + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using ARM Compiler 6 (AC6) - Using the AC6 Tools -1. Import the ThreadX Projects +1. Building the ThreadX run-time Library In order to build the ThreadX library and the ThreadX demonstration, first import the 'tx' and 'sample_threadx' projects (located in the "example_build" directory) into your DS workspace. - -2. Building the ThreadX run-time Library - Building the ThreadX library is easy; simply right-click the Eclipse project "tx" and then select the "Build Project" button. You should now observe the compilation and assembly of the ThreadX library. This project build produces the ThreadX library file tx.a. -3. Demonstration System +2. Demonstration System The ThreadX demonstration is designed to execute under the DS debugger on the -MPS2_Cortex_M7 Bare Metal simulator. +MPS2_Cortex_Mx Bare Metal simulator. Building the demonstration is easy; simply right-click the Eclipse project "sample_threadx" and then select the "Build Project" button. You should now observe the compilation and assembly of the ThreadX demonstration. This project build produces the ThreadX library file sample_threadx.axf. Next, expand the demo ThreadX project folder -in the Project Explorer window, right-click on the 'cortex-m7_tx.launch' file, click -'Debug As', and then click 'cortex-m7_tx' from the submenu. This will cause the +in the Project Explorer window, right-click on the 'cortex-mx_tx.launch' file, click +'Debug As', and then click 'cortex-mx_tx' from the submenu. This will cause the debugger to load the sample_threadx.axf ELF file and run to main. You are now ready to execute the ThreadX demonstration. -4. System Initialization +3. System Initialization -The entry point in ThreadX for the Cortex-M7 using gnu tools uses the standard GNU -Cortex-M7 reset sequence. From the reset vector the C runtime will be initialized. +The entry point in ThreadX for the Cortex-M using AC6 tools uses the standard GNU +Cortex-M reset sequence. From the reset vector the C runtime will be initialized. The ThreadX tx_initialize_low_level.S file is responsible for setting up various system data structures, the vector area, and a periodic timer interrupt @@ -46,20 +44,19 @@ address for use by the application, which is supplied as the sole input parameter to your application definition function, tx_application_define. -5. Register Usage and Stack Frames +4. Register Usage and Stack Frames The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M7 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. - Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -81,7 +78,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -133,34 +130,34 @@ FPU Stack Frame (only interrupted thread with FPU enabled): 0xC4 fpscr -6. Improving Performance +5. Improving Performance -The distribution version of ThreadX is built without any compiler optimizations. -This makes it easy to debug because you can trace or set breakpoints inside of -ThreadX itself. Of course, this costs some performance. To make it run faster, -you can change the build_threadx.bat file to remove the -g option and enable -all compiler optimizations. +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING defined. -7. Interrupt Handling +6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M7 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: -7.1 Vector Area +6.1 Vector Area -The Cortex-M7 vectors start at the label __tx_vectors or similar. The application may modify +The Cortex-M vectors start at the label __tx_vectors or similar. The application may modify the vector area according to its needs. There is code in tx_initialize_low_level() that will configure the vector base register. -7.2 Managed Interrupts +6.2 Managed Interrupts A ThreadX managed interrupt is defined below. By following these conventions, the application ISR is then allowed access to various ThreadX services from the ISR. @@ -182,36 +179,30 @@ __tx_IntHandler: ; } -Note: the Cortex-M7 requires exception handlers to be thumb labels, this implies bit 0 set. +Note: the Cortex-M requires exception handlers to be thumb labels, this implies bit 0 set. To accomplish this, the declaration of the label has to be preceded by the assembler directive .thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to be inserted in the correct location in the interrupt vector table. This table is typically located in either your runtime startup file or in the tx_initialize_low_level.S file. -8. FPU Support +7. FPU Support -ThreadX for Cortex-M7 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread context - no additional setup by the application. -9. Revision History +8. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX 6.1 version for Cortex-M7 using AC6 tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using AC6 tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m7/ac6/src/tx_thread_context_restore.S b/ports/cortex_m7/ac6/src/tx_thread_context_restore.S index e512d16f..bb4ec403 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_context_restore.S +++ b/ports/cortex_m7/ac6/src/tx_thread_context_restore.S @@ -1,86 +1,81 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr - .global _tx_thread_system_stack_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_schedule - .global _tx_thread_preempt_disable -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_restore Cortex-M7/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function restores the interrupt context if it is processing a */ -@/* nested interrupt. If not, it returns to the interrupt thread if no */ -@/* preemption is necessary. Otherwise, if preemption is necessary or */ -@/* if no thread was running, the function returns to the scheduler. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* _tx_thread_schedule Thread scheduling routine */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs Interrupt Service Routines */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_restore(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M7/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { .global _tx_thread_context_restore .thumb_func _tx_thread_context_restore: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -@} +// } diff --git a/ports/cortex_m7/ac6/src/tx_thread_context_save.S b/ports/cortex_m7/ac6/src/tx_thread_context_save.S index 00f1f550..efe70556 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_context_save.S +++ b/ports/cortex_m7/ac6/src/tx_thread_context_save.S @@ -1,80 +1,83 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_system_state - .global _tx_thread_current_ptr -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_save Cortex-M7/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function saves the context of an executing thread in the */ -@/* beginning of interrupt processing. The function also ensures that */ -@/* the system stack is used upon return to the calling ISR. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* None */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_save(VOID) -@{ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_enter +#endif +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M7/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { .global _tx_thread_context_save .thumb_func _tx_thread_context_save: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr -@} +// } diff --git a/ports/cortex_m7/ac6/src/tx_thread_interrupt_control.S b/ports/cortex_m7/ac6/src/tx_thread_interrupt_control.S index d146da48..0843f69e 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_interrupt_control.S +++ b/ports/cortex_m7/ac6/src/tx_thread_interrupt_control.S @@ -1,80 +1,79 @@ -@/**************************************************************************/ -@/* */ -@/* 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. */ -@/* */ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_interrupt_control Cortex-M7/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* UINT _tx_thread_interrupt_control(UINT new_posture) -{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M7/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { .global _tx_thread_interrupt_control .thumb_func _tx_thread_interrupt_control: - -@/* Pickup current interrupt lockout posture. */ - - MRS r1, PRIMASK @ Pickup current interrupt lockout - -@/* Apply the new interrupt posture. */ - - MSR PRIMASK, r0 @ Apply the new interrupt lockout - MOV r0, r1 @ Transfer old to return register - BX lr @ Return to caller - -@/* } */ +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } diff --git a/ports/cortex_m7/ac6/src/tx_thread_interrupt_disable.S b/ports/cortex_m7/ac6/src/tx_thread_interrupt_disable.S new file mode 100644 index 00000000..3f36a36a --- /dev/null +++ b/ports/cortex_m7/ac6/src/tx_thread_interrupt_disable.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M7/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { + .global _tx_thread_interrupt_disable + .thumb_func +_tx_thread_interrupt_disable: + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else + MRS r0, PRIMASK + CPSID i +#endif + BX lr +// } diff --git a/ports/cortex_m7/ac6/src/tx_thread_interrupt_restore.S b/ports/cortex_m7/ac6/src/tx_thread_interrupt_restore.S new file mode 100644 index 00000000..924fa21d --- /dev/null +++ b/ports/cortex_m7/ac6/src/tx_thread_interrupt_restore.S @@ -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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M7/AC6 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { + .global _tx_thread_interrupt_restore + .thumb_func +_tx_thread_interrupt_restore: + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else + MSR PRIMASK, r0 +#endif + BX lr +// } diff --git a/ports/cortex_m7/ac6/src/tx_thread_schedule.S b/ports/cortex_m7/ac6/src/tx_thread_schedule.S index 302eb176..86f9a7a8 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_schedule.S +++ b/ports/cortex_m7/ac6/src/tx_thread_schedule.S @@ -1,303 +1,286 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_current_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_system_stack_ptr +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_thread_current_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit +#endif #ifdef TX_LOW_POWER .global tx_low_power_enter .global tx_low_power_exit #endif - -@ -@ .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_schedule Cortex-M7/AC6 */ -@/* 6.1.5 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* _tx_thread_context_restore Restore thread's context */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -@/* 03-02-2021 Scott Larson Modified comment(s), add */ -@/* low power code, */ -@/* resulting in version 6.1.5 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_schedule(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M7/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { .global _tx_thread_schedule .thumb_func _tx_thread_schedule: -@ -@ /* This function should only ever be called on Cortex-M7 -@ from the first schedule request. Subsequent scheduling occurs -@ from the PendSV handling routines below. */ -@ -@ /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -@ - MOV 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 -@ -@ /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -@ -#ifdef TX_ENABLE_FPU_SUPPORT - MRS r0, CONTROL @ Pickup current CONTROL register - BIC r0, r0, #4 @ Clear the FPCA bit - MSR CONTROL, r0 @ Setup new CONTROL register + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __ARM_PCS_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register #endif -@ -@ /* Enable interrupts */ -@ + + /* Enable interrupts */ CPSIE i -@ -@ /* Enter the scheduler for the first time. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ Set PENDSVBIT in ICSR - DSB @ Complete all memory accesses - ISB @ Flush pipeline -@ -@ /* Wait here for the PendSV to take place. */ -@ + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 switch-out switch-in handler... Note that this handler is -@ common for both PendSV and SVCall. */ -@ + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + .global PendSV_Handler .global __tx_PendSVHandler + .syntax unified .thumb_func PendSV_Handler: .thumb_func __tx_PendSVHandler: -@ -@ /* Get current thread value and new thread pointer. */ -@ + + /* Get current thread value and new thread pointer. */ + __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, lr} @ Recover LR - CPSIE i @ Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - MOV 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 r12, PSP @ Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} @ Save its remaining registers -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} @ Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save: #endif - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - STMDB r12!, {LR} @ Save LR on the stack -@ -@ /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -@ - LDR r5, [r4] @ Pickup current time-slice - STR r12, [r1, #8] @ Save the thread stack pointer - 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. */ -@ - STR r3, [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 - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - LDR r5, [r1, #24] @ Pickup thread's current time-slice - ADD 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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack -#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 r3 + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 #endif -@ -@ /* Restore the thread context and PSP. */ -@ - LDR r12, [r1, #8] @ Pickup thread's stack pointer - LDMIA r12!, {LR} @ Pickup LR -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present - BNE _skip_vfp_restore @ If not, skip VFP restore - VLDMIA r12!, {s16-s31} @ Yes, restore additional VFP registers + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore: #endif - LDMIA r12!, {r4-r11} @ Recover thread's registers - MSR PSP, r12 @ 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. */ -@ + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter @ Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB @ Ensure no outstanding memory transactions - WFI @ Wait for interrupt - ISB @ Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit @ Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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: - MOV r7, #0x08000000 @ Build clear PendSV value - MOV r8, #0xE000E000 @ Build base NVIC address - STR r7, [r8, #0xD04] @ Clear any PendSV -@ -@ /* Re-enable interrupts and restore new thread. */ -@ - CPSIE i @ Enable interrupts - B __tx_ts_restore @ Restore the thread + CPSIE i // Enable interrupts + B __tx_ts_wait // Loop to continue waiting -#ifdef TX_ENABLE_FPU_SUPPORT + /* 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: + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __ARM_PCS_VFP .global tx_thread_fpu_enable .thumb_func tx_thread_fpu_enable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller - .global tx_thread_fpu_disable .thumb_func tx_thread_fpu_disable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller #endif diff --git a/ports/cortex_m7/ac6/src/tx_thread_stack_build.S b/ports/cortex_m7/ac6/src/tx_thread_stack_build.S index c218041e..52c2c207 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_stack_build.S +++ b/ports/cortex_m7/ac6/src/tx_thread_stack_build.S @@ -1,135 +1,133 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_stack_build Cortex-M7/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M7/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { .global _tx_thread_stack_build .thumb_func _tx_thread_stack_build: -@ -@ -@ /* Build a fake interrupt frame. The form of the fake interrupt stack -@ on the Cortex-M7 should look like the following after it is built: -@ -@ Stack Top: -@ LR Interrupted LR (LR at time of PENDSV) -@ r4 Initial value for r4 -@ r5 Initial value for r5 -@ r6 Initial value for r6 -@ r7 Initial value for r7 -@ r8 Initial value for r8 -@ r9 Initial value for r9 -@ r10 Initial value for r10 -@ r11 Initial value for r11 -@ 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 - BIC r2, r2, #0x7 @ Align frame - SUB r2, r2, #68 @ Subtract frame size - LDR r3, =0xFFFFFFFD @ Build initial LR value - STR r3, [r2, #0] @ Save on the stack -@ -@ /* Actually build the stack frame. */ -@ - MOV r3, #0 @ Build initial register value - STR r3, [r2, #4] @ Store initial r4 - STR r3, [r2, #8] @ Store initial r5 - STR r3, [r2, #12] @ Store initial r6 - STR r3, [r2, #16] @ Store initial r7 - STR r3, [r2, #20] @ Store initial r8 - STR r3, [r2, #24] @ Store initial r9 - STR r3, [r2, #28] @ Store initial r10 - STR r3, [r2, #32] @ Store initial r11 -@ -@ /* 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 - MOV r3, #0xFFFFFFFF @ Poison EXC_RETURN value - STR r3, [r2, #56] @ Store initial lr - STR r1, [r2, #60] @ Store initial pc - MOV 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 -@} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 +// } diff --git a/ports/cortex_m7/ac6/src/tx_thread_system_return.S b/ports/cortex_m7/ac6/src/tx_thread_system_return.S index 27b67633..c1b3b9e8 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m7/ac6/src/tx_thread_system_return.S @@ -1,88 +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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_system_return Cortex-M7/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* VOID _tx_thread_system_return(VOID) -@{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M7/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { .thumb_func .global _tx_thread_system_return _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. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ 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 -@/* } */ + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif +_isr_context: + BX lr // Return to caller +// } diff --git a/ports/cortex_m7/ac6/src/tx_timer_interrupt.S b/ports/cortex_m7/ac6/src/tx_timer_interrupt.S index 7f34283d..c8ab5724 100644 --- a/ports/cortex_m7/ac6/src/tx_timer_interrupt.S +++ b/ports/cortex_m7/ac6/src/tx_timer_interrupt.S @@ -1,257 +1,250 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_timer_time_slice - .global _tx_timer_system_clock - .global _tx_timer_current_ptr - .global _tx_timer_list_start - .global _tx_timer_list_end - .global _tx_timer_expired_time_slice - .global _tx_timer_expired - .global _tx_thread_time_slice - .global _tx_timer_expiration_process -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_timer_time_slice + .global _tx_timer_system_clock + .global _tx_timer_current_ptr + .global _tx_timer_list_start + .global _tx_timer_list_end + .global _tx_timer_expired_time_slice + .global _tx_timer_expired + .global _tx_thread_time_slice + .global _tx_timer_expiration_process + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_timer_interrupt Cortex-M7/AC6 */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_timer_interrupt(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M7/AC6 */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { .global _tx_timer_interrupt .thumb_func _tx_timer_interrupt: -@ -@ /* Upon entry to this routine, it is assumed that context save has already -@ been called, and therefore the compiler scratch registers are available -@ for use. */ -@ -@ /* Increment the system clock. */ -@ _tx_timer_system_clock++; -@ - LDR r1, =_tx_timer_system_clock @ Pickup address of system clock - LDR r0, [r1, #0] @ Pickup system clock - ADD r0, r0, #1 @ Increment system clock - STR r0, [r1, #0] @ Store new system clock -@ -@ /* Test for time-slice expiration. */ -@ if (_tx_timer_time_slice) -@ { -@ - LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice - LDR r2, [r3, #0] @ Pickup time-slice - CMP r2, #0 @ Is it non-active? - BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing -@ -@ /* Decrement the time_slice. */ -@ _tx_timer_time_slice--; -@ - SUB 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) -@ - CMP r2, #0 @ Has it expired? - BNE __tx_timer_no_time_slice @ No, skip expiration processing -@ -@ /* Set the time-slice expired flag. */ -@ _tx_timer_expired_time_slice = TX_TRUE; -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag - MOV r0, #1 @ Build expired value - STR r0, [r3, #0] @ Set time-slice expiration flag -@ -@ } -@ + + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) -@ { -@ - LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address - LDR r0, [r1, #0] @ Pickup current timer - LDR r2, [r0, #0] @ Pickup timer list entry - CMP r2, #0 @ Is there anything in the list? - BEQ __tx_timer_no_timer @ No, just increment the timer -@ -@ /* Set expiration flag. */ -@ _tx_timer_expired = TX_TRUE; -@ - LDR r3, =_tx_timer_expired @ Pickup expiration flag address - MOV r2, #1 @ Build expired value - STR r2, [r3, #0] @ Set expired flag - B __tx_timer_done @ Finished timer processing -@ -@ } -@ else -@ { + + /* Test for timer expiration. */ + // if (*_tx_timer_current_ptr) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; -@ - ADD r0, r0, #4 @ Move to next timer -@ -@ /* Check for wrap-around. */ -@ if (_tx_timer_current_ptr == _tx_timer_list_end) -@ - LDR r3, =_tx_timer_list_end @ Pickup addr of 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; -@ - LDR r3, =_tx_timer_list_start @ Pickup addr of timer list start - LDR r0, [r3, #0] @ Set current pointer to list start -@ + + /* No timer expired, increment the timer pointer. */ + // _tx_timer_current_ptr++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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 -@ } -@ + + 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)) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of expired flag - LDR r2, [r3, #0] @ Pickup time-slice expired flag - CMP r2, #0 @ Did a time-slice expire? - BNE __tx_something_expired @ If non-zero, time-slice expired - LDR r1, =_tx_timer_expired @ Pickup addr of other expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Did a timer expire? - BEQ __tx_timer_nothing_expired @ No, nothing expired -@ + + /* See if anything has expired. */ + // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + __tx_something_expired: -@ -@ - STMDB sp!, {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) -@ { -@ - LDR r1, =_tx_timer_expired @ Pickup addr of expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Check for timer expiration - BEQ __tx_timer_dont_activate @ If not set, skip timer activation -@ -@ /* Process timer expiration. */ -@ _tx_timer_expiration_process(); -@ - BL _tx_timer_expiration_process @ Call the timer expiration handling routine -@ -@ } + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of time-slice expired - LDR r2, [r3, #0] @ Pickup the actual flag - CMP r2, #0 @ See if the flag is set - BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing -@ -@ /* Time slice interrupted thread. */ -@ _tx_thread_time_slice(); -@ - BL _tx_thread_time_slice @ Call time-slice processing - LDR r0, =_tx_thread_preempt_disable @ Build address of preempt disable flag - LDR r1, [r0] @ Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice @ Yes, skip the PendSV logic - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r1, [r0] @ Pickup the current thread pointer - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - 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 + + /* Did time slice expire? */ + // if (_tx_timer_expired_time_slice) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -@ - LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for - @ the 8-byte stack alignment -@ -@ } -@ + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB @ Complete all memory access - BX lr @ Return to caller -@ -@} + DSB // Complete all memory access + BX lr // Return to caller +// } diff --git a/ports/cortex_m7/gnu/inc/tx_port.h b/ports/cortex_m7/gnu/inc/tx_port.h index cc552c1e..8693a41e 100644 --- a/ports/cortex_m7/gnu/inc/tx_port.h +++ b/ports/cortex_m7/gnu/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M7/GNU */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,16 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -/* 09-30-2020 William E. Lamie Modified comment(s), */ -/* resulting in version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -64,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -76,6 +74,28 @@ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -86,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -113,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -133,46 +154,83 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#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 logic. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#endif /* 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 -#define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ +#else +#define TX_THREAD_EXTENSION_2 +#endif + + +#define TX_THREAD_EXTENSION_3 + /* Define the port extensions of the remaining ThreadX objects. */ @@ -186,11 +244,11 @@ typedef unsigned short USHORT; #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -198,11 +256,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); -#ifdef TX_ENABLE_FPU_SUPPORT +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -211,26 +286,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) { - ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } - -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) { - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); } +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); -#endif +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -238,23 +336,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -263,77 +360,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((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 = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -358,126 +454,242 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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++; -/* This 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 +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - #endif -#ifndef TX_DISABLE_INLINE -/* Define GNU specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; -unsigned int primask_value; + int_posture = __get_interrupt_posture(); - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) -{ - - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); -} - -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) -{ - -unsigned int primask_value; - - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); -} - -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) -{ - - __asm__ volatile (" CPSIE i": : : "memory" ); -} - - __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_ipsr_value() == 0) { - interrupt_save = __get_primask_value(); + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ #define _tx_thread_system_return _tx_thread_system_return_inline -#else +#else /* TX_DISABLE_INLINE is defined */ -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* 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-M. 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); @@ -486,16 +698,15 @@ void tx_thread_fpu_disable(void); /* 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-M7/GNU Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/GNU Version 6.1.7 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - - #endif - - - +#endif diff --git a/ports/cortex_m7/gnu/readme_threadx.txt b/ports/cortex_m7/gnu/readme_threadx.txt index 7f5ace0c..d9063d65 100644 --- a/ports/cortex_m7/gnu/readme_threadx.txt +++ b/ports/cortex_m7/gnu/readme_threadx.txt @@ -1,12 +1,13 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M7 - + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) Using the GNU Tools + 1. Building the ThreadX run-time Library -First make sure you are in the "example_build" directory. Also, make sure that +Navigate to the "example_build" directory. Ensure that you have setup your path and other environment variables necessary for the ARM -gnu (GNU) compiler. At this point you may run the build_threadx.bat batch file. +GNU compiler. At this point you may run the build_threadx.bat batch file. This will build the ThreadX run-time environment in the "example_build" directory. @@ -16,13 +17,13 @@ run-time library file: tx.a. This file must be linked with your application in order to use ThreadX. -2. Demonstration System for Cortex-M7 +2. Demonstration System -The ThreadX demonstration is designed to execute on Cortex-M7 evaluation boards +The ThreadX demonstration is designed to execute on Cortex-M evaluation boards or on a dedicated simulator. Building the demonstration is easy, simply execute the build_threadx_sample.bat -batch file while inside the "example_build" directory. +batch file while inside the "example_build" directory. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.out is a binary @@ -31,8 +32,8 @@ file that can be downloaded and executed on the a simulator, or downloaded to a 3. System Initialization -The entry point in ThreadX for the Cortex-M7 using gnu tools uses the standard GNU -Cortex-M7 reset sequence. From the reset vector the C runtime will be initialized. +The entry point in ThreadX for the Cortex-M using gnu tools uses the standard GNU +Cortex-M reset sequence. From the reset vector the C runtime will be initialized. The ThreadX tx_initialize_low_level.S file is responsible for setting up various system data structures, the vector area, and a periodic timer interrupt @@ -47,16 +48,15 @@ parameter to your application definition function, tx_application_define. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M7 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. - Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -78,7 +78,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -145,14 +145,14 @@ defined. 6. Interrupt Handling -ThreadX provides complete and high-performance interrupt handling for Cortex-M7 +ThreadX provides complete and high-performance interrupt handling for Cortex-M targets. There are a certain set of requirements that are defined in the following sub-sections: 6.1 Vector Area -The Cortex-M7 vectors start at the label __tx_vectors or similar. The application may modify +The Cortex-M vectors start at the label __tx_vectors or similar. The application may modify the vector area according to its needs. There is code in tx_initialize_low_level() that will configure the vector base register. @@ -179,7 +179,7 @@ __tx_IntHandler: ; } -Note: the Cortex-M7 requires exception handlers to be thumb labels, this implies bit 0 set. +Note: the Cortex-M requires exception handlers to be thumb labels, this implies bit 0 set. To accomplish this, the declaration of the label has to be preceded by the assembler directive .thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to be inserted in the correct location in the interrupt vector table. This table is typically @@ -188,7 +188,7 @@ located in either your runtime startup file or in the tx_initialize_low_level.S 7. FPU Support -ThreadX for Cortex-M7 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread context - no additional setup by the application. @@ -199,21 +199,10 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 ThreadX update of Cortex-M7/GNU port. The following files were - changed/added for port specific version 6.1: - - *.S Modified comments and whitespace. - -05/19/2020 Initial ThreadX 6.0 version for Cortex-M7 using GNU tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using GNU tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m7/gnu/src/tx_thread_context_restore.S b/ports/cortex_m7/gnu/src/tx_thread_context_restore.S index 2cc089dd..d3f50e9f 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_context_restore.S +++ b/ports/cortex_m7/gnu/src/tx_thread_context_restore.S @@ -1,79 +1,81 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_exit +#endif + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_restore Cortex-M7/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function restores the interrupt context if it is processing a */ -@/* nested interrupt. If not, it returns to the interrupt thread if no */ -@/* preemption is necessary. Otherwise, if preemption is necessary or */ -@/* if no thread was running, the function returns to the scheduler. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* _tx_thread_schedule Thread scheduling routine */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs Interrupt Service Routines */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_restore(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M7/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { .global _tx_thread_context_restore .thumb_func _tx_thread_context_restore: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address +#endif + BX lr -@} +// } diff --git a/ports/cortex_m7/gnu/src/tx_thread_context_save.S b/ports/cortex_m7/gnu/src/tx_thread_context_save.S index 98330daa..934fbe56 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_context_save.S +++ b/ports/cortex_m7/gnu/src/tx_thread_context_save.S @@ -1,78 +1,80 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_context_save Cortex-M7/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, Microsoft Corporation */ -@/* */ -@/* DESCRIPTION */ -@/* */ -@/* This function is only needed for legacy applications and it should */ -@/* not be called in any new development on a Cortex-M. */ -@/* This function saves the context of an executing thread in the */ -@/* beginning of interrupt processing. The function also ensures that */ -@/* the system stack is used upon return to the calling ISR. */ -@/* */ -@/* INPUT */ -@/* */ -@/* None */ -@/* */ -@/* OUTPUT */ -@/* */ -@/* None */ -@/* */ -@/* CALLS */ -@/* */ -@/* None */ -@/* */ -@/* CALLED BY */ -@/* */ -@/* ISRs */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_context_save(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M7/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_enter] Execution profiling ISR enter */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { .global _tx_thread_context_save .thumb_func _tx_thread_context_save: -@ -@ /* Not needed for this port - just return! */ + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address +#endif + + /* Context is already saved - just return. */ + BX lr -@} +// } diff --git a/ports/cortex_m7/gnu/src/tx_thread_interrupt_control.S b/ports/cortex_m7/gnu/src/tx_thread_interrupt_control.S index ba269498..2ea849dc 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_interrupt_control.S +++ b/ports/cortex_m7/gnu/src/tx_thread_interrupt_control.S @@ -1,83 +1,79 @@ -@/**************************************************************************/ -@/* */ -@/* 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. */ -@/* */ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_interrupt_control Cortex-M7/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 Scott Larson Modified comment(s), and */ -@/* cleaned up whitespace, */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* UINT _tx_thread_interrupt_control(UINT new_posture) -{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M7/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { .global _tx_thread_interrupt_control .thumb_func _tx_thread_interrupt_control: - -@/* Pickup current interrupt lockout posture. */ - - MRS r1, PRIMASK @ Pickup current interrupt lockout - -@/* Apply the new interrupt posture. */ - - MSR PRIMASK, r0 @ Apply the new interrupt lockout - MOV r0, r1 @ Transfer old to return register - BX lr @ Return to caller - -@/* } */ +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } diff --git a/ports/cortex_m7/gnu/src/tx_thread_interrupt_disable.S b/ports/cortex_m7/gnu/src/tx_thread_interrupt_disable.S new file mode 100644 index 00000000..16935d55 --- /dev/null +++ b/ports/cortex_m7/gnu/src/tx_thread_interrupt_disable.S @@ -0,0 +1,79 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M7/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { + .global _tx_thread_interrupt_disable + .thumb_func +_tx_thread_interrupt_disable: + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_BASEPRI + MSR BASEPRI, r1 +#else + MRS r0, PRIMASK + CPSID i +#endif + BX lr +// } diff --git a/ports/cortex_m7/gnu/src/tx_thread_interrupt_restore.S b/ports/cortex_m7/gnu/src/tx_thread_interrupt_restore.S new file mode 100644 index 00000000..27f8c5bd --- /dev/null +++ b/ports/cortex_m7/gnu/src/tx_thread_interrupt_restore.S @@ -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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .text 32 + .align 4 + .syntax unified +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M7/GNU */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { + .global _tx_thread_interrupt_restore + .thumb_func +_tx_thread_interrupt_restore: + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else + MSR PRIMASK, r0 +#endif + BX lr +// } diff --git a/ports/cortex_m7/gnu/src/tx_thread_schedule.S b/ports/cortex_m7/gnu/src/tx_thread_schedule.S index 83363d36..4b5c490f 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_schedule.S +++ b/ports/cortex_m7/gnu/src/tx_thread_schedule.S @@ -1,306 +1,284 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_thread_current_ptr - .global _tx_thread_execute_ptr - .global _tx_timer_time_slice - .global _tx_thread_system_stack_ptr - .global _tx_execution_thread_enter - .global _tx_execution_thread_exit +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_thread_current_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice + .global _tx_execution_thread_enter + .global _tx_execution_thread_exit #ifdef TX_LOW_POWER .global tx_low_power_enter .global tx_low_power_exit #endif -@ -@ .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_schedule Cortex-M7/GNU */ -@/* 6.1.5 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* _tx_thread_context_restore Restore thread's context */ -@/* */ -@/* RELEASE HISTORY */ -@/* */ -@/* DATE NAME DESCRIPTION */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* 03-02-2021 Scott Larson Modified comment(s), add */ -@/* low power code, */ -@/* resulting in version 6.1.5 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_schedule(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M7/GNU */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { .global _tx_thread_schedule .thumb_func _tx_thread_schedule: -@ -@ /* This function should only ever be called on Cortex-M7 -@ from the first schedule request. Subsequent scheduling occurs -@ from the PendSV handling routines below. */ -@ -@ /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -@ - MOV 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 -@ -@ /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -@ -#ifdef TX_ENABLE_FPU_SUPPORT - MRS r0, CONTROL @ Pickup current CONTROL register - BIC r0, r0, #4 @ Clear the FPCA bit - MSR CONTROL, r0 @ Setup new CONTROL register + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + +#ifdef __ARM_PCS_VFP + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register #endif -@ -@ /* Enable interrupts */ -@ + + /* Enable interrupts */ CPSIE i -@ -@ /* Enter the scheduler for the first time. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ Set PENDSVBIT in ICSR - DSB @ Complete all memory accesses - ISB @ Flush pipeline -@ -@ /* Wait here for the PendSV to take place. */ -@ + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 switch-out switch-in handler... Note that this handler is -@ common for both PendSV and SVCall. */ -@ + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + .global PendSV_Handler .global __tx_PendSVHandler + .syntax unified .thumb_func PendSV_Handler: .thumb_func __tx_PendSVHandler: -@ -@ /* Get current thread value and new thread pointer. */ -@ + + /* Get current thread value and new thread pointer. */ + __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, lr} @ Recover LR - CPSIE i @ Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - MOV 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 r12, PSP @ Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} @ Save its remaining registers -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} @ Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save: #endif - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - STMDB r12!, {LR} @ Save LR on the stack -@ -@ /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -@ - LDR r5, [r4] @ Pickup current time-slice - STR r12, [r1, #8] @ Save the thread stack pointer - 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. */ -@ - STR r3, [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 - LDR r4, =_tx_timer_time_slice @ Build address of time-slice variable - LDR r5, [r1, #24] @ Pickup thread's current time-slice - ADD 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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack -#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 r3 + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 #endif -@ -@ /* Restore the thread context and PSP. */ -@ - LDR r12, [r1, #8] @ Pickup thread's stack pointer - LDMIA r12!, {LR} @ Pickup LR -#ifdef TX_ENABLE_FPU_SUPPORT - TST LR, #0x10 @ Determine if the VFP extended frame is present - BNE _skip_vfp_restore @ If not, skip VFP restore - VLDMIA r12!, {s16-s31} @ Yes, restore additional VFP registers + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR +#ifdef __ARM_PCS_VFP + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore: #endif - LDMIA r12!, {r4-r11} @ Recover thread's registers - MSR PSP, r12 @ 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. */ -@ + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter @ Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB @ Ensure no outstanding memory transactions - WFI @ Wait for interrupt - ISB @ Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit @ Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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: - MOV r7, #0x08000000 @ Build clear PendSV value - MOV r8, #0xE000E000 @ Build base NVIC address - STR r7, [r8, #0xD04] @ Clear any PendSV -@ -@ /* Re-enable interrupts and restore new thread. */ -@ - CPSIE i @ Enable interrupts - B __tx_ts_restore @ Restore the thread + CPSIE i // Enable interrupts + B __tx_ts_wait // Loop to continue waiting -#ifdef TX_ENABLE_FPU_SUPPORT + /* 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: + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + +#ifdef __ARM_PCS_VFP .global tx_thread_fpu_enable .thumb_func tx_thread_fpu_enable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller - .global tx_thread_fpu_disable .thumb_func tx_thread_fpu_disable: -@ -@ /* Automatic VPF logic is supported, this function is present only for -@ backward compatibility purposes and therefore simply returns. */ -@ - BX LR @ Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller #endif diff --git a/ports/cortex_m7/gnu/src/tx_thread_stack_build.S b/ports/cortex_m7/gnu/src/tx_thread_stack_build.S index a163ab91..7c2cb83a 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_stack_build.S +++ b/ports/cortex_m7/gnu/src/tx_thread_stack_build.S @@ -1,141 +1,133 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_stack_build Cortex-M7/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified Comment(s), setting */ -@/* R10 to top of stack is not */ -@/* needed. Removed references */ -@/* to stack frame, clean up */ -@/* whitespace, resulting */ -@/* in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M7/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { .global _tx_thread_stack_build .thumb_func _tx_thread_stack_build: -@ -@ -@ /* Build a fake interrupt frame. The form of the fake interrupt stack -@ on the Cortex-M7 should look like the following after it is built: -@ -@ Stack Top: -@ LR Interrupted LR (LR at time of PENDSV) -@ r4 Initial value for r4 -@ r5 Initial value for r5 -@ r6 Initial value for r6 -@ r7 Initial value for r7 -@ r8 Initial value for r8 -@ r9 Initial value for r9 -@ r10 Initial value for r10 -@ r11 Initial value for r11 -@ 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 - BIC r2, r2, #0x7 @ Align frame - SUB r2, r2, #68 @ Subtract frame size - LDR r3, =0xFFFFFFFD @ Build initial LR value - STR r3, [r2, #0] @ Save on the stack -@ -@ /* Actually build the stack frame. */ -@ - MOV r3, #0 @ Build initial register value - STR r3, [r2, #4] @ Store initial r4 - STR r3, [r2, #8] @ Store initial r5 - STR r3, [r2, #12] @ Store initial r6 - STR r3, [r2, #16] @ Store initial r7 - STR r3, [r2, #20] @ Store initial r8 - STR r3, [r2, #24] @ Store initial r9 - STR r3, [r2, #28] @ Store initial r10 - STR r3, [r2, #32] @ Store initial r11 -@ -@ /* 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 - MOV r3, #0xFFFFFFFF @ Poison EXC_RETURN value - STR r3, [r2, #56] @ Store initial lr - STR r1, [r2, #60] @ Store initial pc - MOV 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 -@} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 +// } diff --git a/ports/cortex_m7/gnu/src/tx_thread_system_return.S b/ports/cortex_m7/gnu/src/tx_thread_system_return.S index 965f4482..307af29e 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m7/gnu/src/tx_thread_system_return.S @@ -1,90 +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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .text 32 .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_thread_system_return Cortex-M7/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@/* VOID _tx_thread_system_return(VOID) -@{ */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M7/GNU */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { .thumb_func .global _tx_thread_system_return _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. */ -@ - MOV r0, #0x10000000 @ Load PENDSVSET bit - MOV r1, #0xE000E000 @ Load NVIC base - STR r0, [r1, #0xD04] @ 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 -@/* } */ + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif +_isr_context: + BX lr // Return to caller +// } diff --git a/ports/cortex_m7/gnu/src/tx_timer_interrupt.S b/ports/cortex_m7/gnu/src/tx_timer_interrupt.S index 5e1a1570..7cf4d4f3 100644 --- a/ports/cortex_m7/gnu/src/tx_timer_interrupt.S +++ b/ports/cortex_m7/gnu/src/tx_timer_interrupt.S @@ -1,259 +1,250 @@ -@/**************************************************************************/ -@/* */ -@/* 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 */ -@/** */ -@/**************************************************************************/ -@/**************************************************************************/ -@ -@ - .global _tx_timer_time_slice - .global _tx_timer_system_clock - .global _tx_timer_current_ptr - .global _tx_timer_list_start - .global _tx_timer_list_end - .global _tx_timer_expired_time_slice - .global _tx_timer_expired - .global _tx_thread_time_slice - .global _tx_timer_expiration_process -@ -@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_timer_time_slice + .global _tx_timer_system_clock + .global _tx_timer_current_ptr + .global _tx_timer_list_start + .global _tx_timer_list_end + .global _tx_timer_expired_time_slice + .global _tx_timer_expired + .global _tx_thread_time_slice + .global _tx_timer_expiration_process + .text .align 4 .syntax unified -@/**************************************************************************/ -@/* */ -@/* FUNCTION RELEASE */ -@/* */ -@/* _tx_timer_interrupt Cortex-M7/GNU */ -@/* 6.1 */ -@/* AUTHOR */ -@/* */ -@/* William E. Lamie, 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 */ -@/* */ -@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ -@/* 09-30-2020 William E. Lamie Modified comment(s), */ -@/* resulting in version 6.1 */ -@/* */ -@/**************************************************************************/ -@VOID _tx_timer_interrupt(VOID) -@{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M7/GNU */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { .global _tx_timer_interrupt .thumb_func _tx_timer_interrupt: -@ -@ /* Upon entry to this routine, it is assumed that context save has already -@ been called, and therefore the compiler scratch registers are available -@ for use. */ -@ -@ /* Increment the system clock. */ -@ _tx_timer_system_clock++; -@ - LDR r1, =_tx_timer_system_clock @ Pickup address of system clock - LDR r0, [r1, #0] @ Pickup system clock - ADD r0, r0, #1 @ Increment system clock - STR r0, [r1, #0] @ Store new system clock -@ -@ /* Test for time-slice expiration. */ -@ if (_tx_timer_time_slice) -@ { -@ - LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice - LDR r2, [r3, #0] @ Pickup time-slice - CMP r2, #0 @ Is it non-active? - BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing -@ -@ /* Decrement the time_slice. */ -@ _tx_timer_time_slice--; -@ - SUB 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) -@ - CMP r2, #0 @ Has it expired? - BNE __tx_timer_no_time_slice @ No, skip expiration processing -@ -@ /* Set the time-slice expired flag. */ -@ _tx_timer_expired_time_slice = TX_TRUE; -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag - MOV r0, #1 @ Build expired value - STR r0, [r3, #0] @ Set time-slice expiration flag -@ -@ } -@ + + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) -@ { -@ - LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address - LDR r0, [r1, #0] @ Pickup current timer - LDR r2, [r0, #0] @ Pickup timer list entry - CMP r2, #0 @ Is there anything in the list? - BEQ __tx_timer_no_timer @ No, just increment the timer -@ -@ /* Set expiration flag. */ -@ _tx_timer_expired = TX_TRUE; -@ - LDR r3, =_tx_timer_expired @ Pickup expiration flag address - MOV r2, #1 @ Build expired value - STR r2, [r3, #0] @ Set expired flag - B __tx_timer_done @ Finished timer processing -@ -@ } -@ else -@ { + + /* Test for timer expiration. */ + // if (*_tx_timer_current_ptr) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; -@ - ADD r0, r0, #4 @ Move to next timer -@ -@ /* Check for wrap-around. */ -@ if (_tx_timer_current_ptr == _tx_timer_list_end) -@ - LDR r3, =_tx_timer_list_end @ Pickup addr of 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; -@ - LDR r3, =_tx_timer_list_start @ Pickup addr of timer list start - LDR r0, [r3, #0] @ Set current pointer to list start -@ + + /* No timer expired, increment the timer pointer. */ + // _tx_timer_current_ptr++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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 -@ } -@ + + 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)) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of expired flag - LDR r2, [r3, #0] @ Pickup time-slice expired flag - CMP r2, #0 @ Did a time-slice expire? - BNE __tx_something_expired @ If non-zero, time-slice expired - LDR r1, =_tx_timer_expired @ Pickup addr of other expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Did a timer expire? - BEQ __tx_timer_nothing_expired @ No, nothing expired -@ + + /* See if anything has expired. */ + // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + __tx_something_expired: -@ -@ - STMDB sp!, {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) -@ { -@ - LDR r1, =_tx_timer_expired @ Pickup addr of expired flag - LDR r0, [r1, #0] @ Pickup timer expired flag - CMP r0, #0 @ Check for timer expiration - BEQ __tx_timer_dont_activate @ If not set, skip timer activation -@ -@ /* Process timer expiration. */ -@ _tx_timer_expiration_process(); -@ - BL _tx_timer_expiration_process @ Call the timer expiration handling routine -@ -@ } + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) -@ { -@ - LDR r3, =_tx_timer_expired_time_slice @ Pickup addr of time-slice expired - LDR r2, [r3, #0] @ Pickup the actual flag - CMP r2, #0 @ See if the flag is set - BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing -@ -@ /* Time slice interrupted thread. */ -@ _tx_thread_time_slice(); -@ - BL _tx_thread_time_slice @ Call time-slice processing - LDR r0, =_tx_thread_preempt_disable @ Build address of preempt disable flag - LDR r1, [r0] @ Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice @ Yes, skip the PendSV logic - LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address - LDR r1, [r0] @ Pickup the current thread pointer - LDR r2, =_tx_thread_execute_ptr @ Build execute thread pointer address - 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 + + /* Did time slice expire? */ + // if (_tx_timer_expired_time_slice) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -@ - LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for - @ the 8-byte stack alignment -@ -@ } -@ + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB @ Complete all memory access - BX lr @ Return to caller -@ -@} + DSB // Complete all memory access + BX lr // Return to caller +// } diff --git a/ports/cortex_m7/iar/inc/tx_port.h b/ports/cortex_m7/iar/inc/tx_port.h index c86f6c0f..f51679c9 100644 --- a/ports/cortex_m7/iar/inc/tx_port.h +++ b/ports/cortex_m7/iar/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M7/IAR */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,14 +43,14 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ /* */ /**************************************************************************/ @@ -62,7 +62,7 @@ #ifdef TX_INCLUDE_USER_DEFINE_FILE -/* Yes, include the user defines in tx_user.h. The defines in this file may +/* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" @@ -73,11 +73,29 @@ #include #include -#include + +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #include #endif +#endif /* __ICCARM__ */ +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -88,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -115,19 +134,19 @@ typedef unsigned short USHORT; #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 -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 source constants would be: #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) @@ -137,7 +156,7 @@ typedef unsigned short USHORT; #ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE -#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif #else ULONG _tx_misra_time_stamp_get(VOID); @@ -148,6 +167,20 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif +#ifdef __ghs__ +/* Define constants for Green Hills EventAnalyzer. */ + +/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps + represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */ + +#define TX_EL_TICKS_PER_SECOND 1000000 + +/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply + simulate the time-stamp source with a counter. */ + +#define read_tbu() _tx_el_time_base_upper +#define read_tbl() ++_tx_el_time_base_lower +#endif /* __ghs__ */ /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ @@ -166,7 +199,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 @@ -180,24 +213,26 @@ 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 -#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT -#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#elif defined(__ghs__) +#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \ + int Errno; /* errno. */ \ + char * strtok_saved_pos; /* strtok() position. */ #else -#define TX_THREAD_EXTENSION_2 -#endif -#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -#define TX_THREAD_EXTENSION_3 -#else -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; +#define TX_THREAD_EXTENSION_2 #endif +#define TX_THREAD_EXTENSION_3 + + + /* Define the port extensions of the remaining ThreadX objects. */ #define TX_BLOCK_POOL_EXTENSION @@ -209,11 +244,11 @@ ULONG _tx_misra_time_stamp_get(VOID); #define TX_TIMER_EXTENSION -/* 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 -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -223,27 +258,26 @@ ULONG _tx_misra_time_stamp_get(VOID); #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #if (__VER__ < 8000000) -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); #else void *_tx_iar_create_per_thread_tls_area(void); void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); void __iar_Initlocks(void); -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); -#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); #endif #else -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __ARMVFP__ +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -252,28 +286,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#endif +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -283,76 +360,76 @@ void _tx_misra_vfp_touch(void); #ifndef TX_MISRA_ENABLE -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((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 = _tx_vfp_state & ((ULONG) 0x4); \ - __asm volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -377,16 +454,38 @@ void _tx_misra_vfp_touch(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) -#else + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -395,41 +494,189 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #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 -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m))); - +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); #endif -/* Define ThreadX interrupt lockout and restore macros for protection on - access of critical kernel information. The restore interrupt macro must - restore the interrupt posture of the running thread prior to the value - present prior to the disable macro. In most cases, the save area macro - is used to define a local function save area for the disable and restore - macros. */ -/* The embedded assembler blocks are design so as to be inlinable by the - armlink linker inlining. This requires them to consist of either a - single 32-bit instruction, or either one or two 16-bit instructions - followed by a "BX lr". Note that to reduce the critical region size, the - 16-bit "CPSID i" instruction is preceeded by a 16-bit NOP */ +/* Define the interrupt disable/restore macros for each compiler. */ -#ifdef TX_DISABLE_INLINE +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif + +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); + //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} + +__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} + +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} + +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (_ipsr == 0) + { +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } +} + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ + +#define _tx_thread_system_return _tx_thread_system_return_inline + + +#else /* TX_DISABLE_INLINE is defined */ UINT _tx_thread_interrupt_disable(VOID); VOID _tx_thread_interrupt_restore(UINT previous_posture); @@ -437,56 +684,22 @@ VOID _tx_thread_interrupt_restore(UIN #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); - #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); - -#else - -#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save; -#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();}; -#define TX_RESTORE {__set_interrupt_state(interrupt_save);}; - -#define _tx_thread_system_return _tx_thread_system_return_inline - -static void _tx_thread_system_return_inline(void) -{ -__istate_t interrupt_save; - - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_IPSR() == 0) - { - interrupt_save = __get_interrupt_state(); - __enable_interrupt(); - __set_interrupt_state(interrupt_save); - } -} - -#endif +#endif /* TX_DISABLE_INLINE */ -/* 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-M. 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); -/* Define the interrupt lockout macros for each ThreadX object. */ - -#define TX_BLOCK_POOL_DISABLE TX_DISABLE -#define TX_BYTE_POOL_DISABLE TX_DISABLE -#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE -#define TX_MUTEX_DISABLE TX_DISABLE -#define TX_QUEUE_DISABLE TX_DISABLE -#define TX_SEMAPHORE_DISABLE TX_DISABLE - - /* 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-M7/IAR Version 6.1.6 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/IAR Version 6.1.7 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -497,6 +710,3 @@ extern CHAR _tx_version_id[]; #endif - - - diff --git a/ports/cortex_m7/iar/readme_threadx.txt b/ports/cortex_m7/iar/readme_threadx.txt index 9d178cfa..28b54e03 100644 --- a/ports/cortex_m7/iar/readme_threadx.txt +++ b/ports/cortex_m7/iar/readme_threadx.txt @@ -1,6 +1,6 @@ - Microsoft's Azure RTOS ThreadX for Cortex-M7 - - Using the IAR Tools + Microsoft's Azure RTOS ThreadX for ARMv7-M + (Cortex-M3, Cortex-M4, Cortex-M7) + Using IAR EWARM Tools 1. Building the ThreadX run-time Library @@ -25,12 +25,12 @@ Workbench, and select the "Make" button. You should observe the compilation of sample_threadx.c (which is the demonstration application) and linking with tx.a. The resulting file sample_threadx.out is a binary ELF file that can be downloaded and executed on the IAR Windows-based -Cortex-M7 simulator. +Cortex-M simulator. 3. System Initialization -The entry point in ThreadX for the Cortex-M7 using IAR tools is at label +The entry point in ThreadX for the Cortex-M using IAR tools is at label __iar_program_start. This is defined within the IAR compiler's startup code. In addition, this is where all static and global preset C variable initialization processing takes place. @@ -52,7 +52,7 @@ other RAM sections in memory. The following defines the saved context stack frames for context switches that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M7 version of +All suspended threads have the same stack frame in the Cortex-M version of ThreadX. The top of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the associated thread control block TX_THREAD. @@ -60,7 +60,7 @@ Non-FPU Stack Frame: Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 r4 Software stacked GP registers 0x08 r5 0x0C r6 @@ -82,7 +82,7 @@ FPU Stack Frame (only interrupted thread with FPU enabled): Stack Offset Stack Contents - 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x00 lr Interrupted lr (lr at time of PENDSV) 0x04 s16 Software stacked FPU registers 0x08 s17 0x0C s18 @@ -140,7 +140,7 @@ The distribution version of ThreadX is built without any compiler optimizations. This makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. Of course, this costs some performance. To make it run faster, you can change the ThreadX library -project to enable various compiler optimizations. +project to enable various compiler optimizations. In addition, you can eliminate the ThreadX basic API error checking by compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING @@ -149,7 +149,7 @@ defined. 6. Interrupt Handling -The Cortex-M7 vectors start at the label __vector_table and is defined in cstartup_M.s. +The Cortex-M vectors start at the label __vector_table and is defined in cstartup_M.s. The application may modify the vector area according to its needs. @@ -194,28 +194,21 @@ The project options "General Options -> Library Configuration" should also have 8. VFP Support -ThreadX for Cortex-M7 supports automatic ("lazy") VFP support, which means that applications threads +ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread context - no additional setup by the application. - 9. Revision History For generic code revision information, please refer to the readme_threadx_generic.txt file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: -04-02-2021 Release 6.1.6 changes: - tx_port.h Updated macro definition - -03-02-2021 The following files were changed/added for version 6.1.5: - tx_thread_schedule.s Added low power feature - -09-30-2020 Initial ThreadX version 6.1 for Cortex-M7 using IAR's ARM tools. +06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using IAR's ARM tools. -Copyright(c) 1996-2020 Microsoft Corporation +Copyright(c) 1996-2021 Microsoft Corporation https://azure.com/rtos diff --git a/ports/cortex_m7/iar/src/tx_thread_context_restore.s b/ports/cortex_m7/iar/src/tx_thread_context_restore.s index e269a807..ce482b46 100644 --- a/ports/cortex_m7/iar/src/tx_thread_context_restore.s +++ b/ports/cortex_m7/iar/src/tx_thread_context_restore.s @@ -1,96 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - EXTERN _tx_thread_system_state - EXTERN _tx_thread_current_ptr - EXTERN _tx_thread_system_stack_ptr - EXTERN _tx_thread_execute_ptr - EXTERN _tx_timer_time_slice - EXTERN _tx_thread_schedule - EXTERN _tx_thread_preempt_disable +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_execution_isr_exit -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function restores the interrupt context if it is processing a */ -;/* nested interrupt. If not, it returns to the interrupt thread if no */ -;/* preemption is necessary. Otherwise, if preemption is necessary or */ -;/* if no thread was running, the function returns to the scheduler. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* _tx_thread_schedule Thread scheduling routine */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs Interrupt Service Routines */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_restore(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore Cortex-M7/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_exit] Execution profiling ISR exit */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs Interrupt Service Routines */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { PUBLIC _tx_thread_context_restore _tx_thread_context_restore: -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR exit function to indicate an ISR is complete. */ -; - PUSH {r0,lr} ; Save ISR lr - BL _tx_execution_isr_exit ; Call the ISR exit function - POP {r0,lr} ; Restore ISR lr +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR exit function to indicate an ISR is complete. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_exit // Call the ISR exit function + POP {r0, lr} // Recover return address #endif -; - POP {lr} + BX lr -; -;} +// } END diff --git a/ports/cortex_m7/iar/src/tx_thread_context_save.s b/ports/cortex_m7/iar/src/tx_thread_context_save.s index 75a20061..f0f0dd33 100644 --- a/ports/cortex_m7/iar/src/tx_thread_context_save.s +++ b/ports/cortex_m7/iar/src/tx_thread_context_save.s @@ -1,89 +1,80 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; - EXTERN _tx_thread_system_state - EXTERN _tx_thread_current_ptr +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_execution_isr_enter -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_save Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is only needed for legacy applications and it should */ -;/* not be called in any new development on a Cortex-M. */ -;/* This function saves the context of an executing thread in the */ -;/* beginning of interrupt processing. The function also ensures that */ -;/* the system stack is used upon return to the calling ISR. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* None */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save Cortex-M7/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is only needed for legacy applications and it should */ +/* not be called in any new development on a Cortex-M. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* [_tx_execution_isr_enter] Execution profiling ISR enter */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { PUBLIC _tx_thread_context_save _tx_thread_context_save: -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR enter function to indicate an ISR is starting. */ -; - PUSH {r0, lr} ; Save return address - BL _tx_execution_isr_enter ; Call the ISR enter function - POP {r0, lr} ; Recover return address + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the ISR enter function to indicate an ISR is starting. */ + PUSH {r0, lr} // Save return address + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r0, lr} // Recover return address #endif -; -; /* Context is already saved - just return! */ -; + + /* Context is already saved - just return. */ + BX lr -;} +// } END diff --git a/ports/cortex_m7/iar/src/tx_thread_interrupt_control.s b/ports/cortex_m7/iar/src/tx_thread_interrupt_control.s index b8f727e3..506ef09a 100644 --- a/ports/cortex_m7/iar/src/tx_thread_interrupt_control.s +++ b/ports/cortex_m7/iar/src/tx_thread_interrupt_control.s @@ -1,77 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_control Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_control(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control Cortex-M7/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { PUBLIC _tx_thread_interrupt_control _tx_thread_interrupt_control: -; -; /* Pickup current interrupt lockout posture. */ -; - MRS r1, PRIMASK - MSR PRIMASK, r0 - MOV r0, r1 - BX lr -; -;} +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Pickup current interrupt posture + MSR BASEPRI, r0 // Apply the new interrupt posture + MOV r0, r1 // Transfer old to return register +#else + MRS r1, PRIMASK // Pickup current interrupt lockout + MSR PRIMASK, r0 // Apply the new interrupt lockout + MOV r0, r1 // Transfer old to return register +#endif + BX lr // Return to caller +// } END diff --git a/ports/cortex_m7/iar/src/tx_thread_interrupt_disable.s b/ports/cortex_m7/iar/src/tx_thread_interrupt_disable.s index bea68745..518879c2 100644 --- a/ports/cortex_m7/iar/src/tx_thread_interrupt_disable.s +++ b/ports/cortex_m7/iar/src/tx_thread_interrupt_disable.s @@ -1,76 +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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;UINT _tx_thread_interrupt_disable(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable Cortex-M7/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts and returning */ +/* the previous interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(VOID) +// { PUBLIC _tx_thread_interrupt_disable _tx_thread_interrupt_disable: -; -; /* Return current interrupt lockout posture. */ -; + /* Return current interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MRS r0, BASEPRI + LDR r1, =TX_PORT_USE_BASEPRI + MSR BASEPRI, r1 +#else MRS r0, PRIMASK CPSID i +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m7/iar/src/tx_thread_interrupt_restore.s b/ports/cortex_m7/iar/src/tx_thread_interrupt_restore.s index 64ffcce0..27037596 100644 --- a/ports/cortex_m7/iar/src/tx_thread_interrupt_restore.s +++ b/ports/cortex_m7/iar/src/tx_thread_interrupt_restore.s @@ -1,75 +1,75 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_restore Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_interrupt_restore(UINT new_posture) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore Cortex-M7/IAR */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring the previous */ +/* interrupt lockout posture. */ +/* */ +/* INPUT */ +/* */ +/* previous_posture Previous interrupt posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_interrupt_restore(UINT previous_posture) +// { PUBLIC _tx_thread_interrupt_restore _tx_thread_interrupt_restore: -; -; /* Restore previous interrupt lockout posture. */ -; + /* Restore previous interrupt lockout posture. */ +#ifdef TX_PORT_USE_BASEPRI + MSR BASEPRI, r0 +#else MSR PRIMASK, r0 +#endif BX lr -; -;} +// } END diff --git a/ports/cortex_m7/iar/src/tx_thread_schedule.s b/ports/cortex_m7/iar/src/tx_thread_schedule.s index 15f8316c..b23be3d4 100644 --- a/ports/cortex_m7/iar/src/tx_thread_schedule.s +++ b/ports/cortex_m7/iar/src/tx_thread_schedule.s @@ -1,302 +1,279 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_timer_time_slice - EXTERN _tx_thread_system_stack_ptr + EXTERN _tx_thread_preempt_disable EXTERN _tx_execution_thread_enter EXTERN _tx_execution_thread_exit - EXTERN _tx_thread_preempt_disable #ifdef TX_LOW_POWER EXTERN tx_low_power_enter EXTERN tx_low_power_exit #endif -; -; SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_schedule Cortex-M7/IAR */ -;/* 6.1.5 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* _tx_thread_context_restore Restore thread's context */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ -;/* 03-02-2021 Scott Larson Modified comment(s), add */ -;/* low power code, */ -;/* resulting in version 6.1.5 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_schedule(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule Cortex-M7/IAR */ +/* 6.1.7 */ +/* 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 */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { PUBLIC _tx_thread_schedule _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 routines below. */ -; -; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */ -; - MOV 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 -; -; /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ -; + + /* 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. */ + + MOV 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 + + /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */ + #ifdef __ARMVFP__ - MRS r0, CONTROL ; Pickup current CONTROL register - BIC r0, r0, #4 ; Clear the FPCA bit - MSR CONTROL, r0 ; Setup new CONTROL register + MRS r0, CONTROL // Pickup current CONTROL register + BIC r0, r0, #4 // Clear the FPCA bit + MSR CONTROL, r0 // Setup new CONTROL register #endif -; -; /* Enable interrupts */ -; + + /* Enable interrupts */ CPSIE i -; -; /* Enter the scheduler for the first time. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR - DSB ; Complete all memory accesses - ISB ; Flush pipeline -; -; /* Wait here for the PendSV to take place. */ -; + + /* Enter the scheduler for the first time. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 PendSV handler. */ -; + B __tx_wait_here // Wait for the PendSV to happen +// } + + /* Generic context switching PendSV handler. */ + PUBLIC PendSV_Handler PUBLIC __tx_PendSVHandler PendSV_Handler: __tx_PendSVHandler: -; -; /* Get current thread value and new thread pointer. */ -; + + /* Get current thread value and new thread pointer. */ + __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, lr} ; Recover LR - CPSIE i ; Enable interrupts +#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 + 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 + CPSIE i // Enable interrupts #endif - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - MOV 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 r12, PSP ; Pickup PSP pointer (thread's stack pointer) - STMDB r12!, {r4-r11} ; Save its remaining registers + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + MOV 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 r12, PSP // Pickup PSP pointer (thread's stack pointer) + STMDB r12!, {r4-r11} // Save its remaining registers #ifdef __ARMVFP__ - TST LR, #0x10 ; Determine if the VFP extended frame is present + TST LR, #0x10 // Determine if the VFP extended frame is present BNE _skip_vfp_save - VSTMDB r12!,{s16-s31} ; Yes, save additional VFP registers + VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers _skip_vfp_save: #endif - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - STMDB r12!, {LR} ; Save LR on the stack -; -; /* Determine if time-slice is active. If it isn't, skip time handling processing. */ -; - LDR r5, [r4] ; Pickup current time-slice - STR r12, [r1, #8] ; Save the thread stack pointer - 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. */ -; - STR r3, [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 - MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable - LDR r5, [r1, #24] ; Pickup thread's current time-slice - ADD 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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + STMDB r12!, {LR} // Save LR on the stack -#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 r3 + /* Determine if time-slice is active. If it isn't, skip time handling processing. */ + + LDR r5, [r4] // Pickup current time-slice + STR r12, [r1, #8] // Save the thread stack pointer + 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. */ + + STR r3, [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 + LDR r4, =_tx_timer_time_slice // Build address of time-slice variable + LDR r5, [r1, #24] // Pickup thread's current time-slice + ADD 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 + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + /* Call the thread entry function to indicate the thread is executing. */ + PUSH {r0, r1} // Save r0 and r1 + BL _tx_execution_thread_enter // Call the thread execution enter function + POP {r0, r1} // Recover r0 and r1 #endif -; -; /* Restore the thread context and PSP. */ -; - LDR r12, [r1, #8] ; Pickup thread's stack pointer - LDMIA r12!, {LR} ; Pickup LR + + /* Restore the thread context and PSP. */ + + LDR r12, [r1, #8] // Pickup thread's stack pointer + LDMIA r12!, {LR} // Pickup LR #ifdef __ARMVFP__ - TST LR, #0x10 ; Determine if the VFP extended frame is present - BNE _skip_vfp_restore ; If not, skip VFP restore - VLDMIA r12!, {s16-s31} ; Yes, restore additional VFP registers + TST LR, #0x10 // Determine if the VFP extended frame is present + BNE _skip_vfp_restore // If not, skip VFP restore + VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers _skip_vfp_restore: #endif - LDMIA r12!, {r4-r11} ; Recover thread's registers - MSR PSP, r12 ; 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. */ -; + LDMIA r12!, {r4-r11} // Recover thread's registers + MSR PSP, r12 // 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! + 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_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_enter ; Possibly enter low power mode - POP {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode #endif #ifdef TX_ENABLE_WFI - DSB ; Ensure no outstanding memory transactions - WFI ; Wait for interrupt - ISB ; Ensure pipeline is flushed + DSB // Ensure no outstanding memory transactions + WFI // Wait for interrupt + ISB // Ensure pipeline is flushed #endif #ifdef TX_LOW_POWER - PUSH {r0-r3} - BL tx_low_power_exit ; Exit low power mode - POP {r0-r3} + BL tx_low_power_exit // Exit low power mode #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! */ -; + 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: - MOV r7, #0x08000000 ; Build clear PendSV value - MOV r8, #0xE000E000 ; Build base NVIC address - STR r7, [r8, #0xD04] ; Clear any PendSV -; -; /* Re-enable interrupts and restore new thread. */ -; - CPSIE i ; Enable interrupts - B __tx_ts_restore ; Restore the thread -;} -; + MOV r7, #0x08000000 // Build clear PendSV value + MOV r8, #0xE000E000 // Build base NVIC address + STR r7, [r8, #0xD04] // Clear any PendSV + + /* Re-enable interrupts and restore new thread. */ + + CPSIE i // Enable interrupts + B __tx_ts_restore // Restore the thread +// } + #ifdef __ARMVFP__ PUBLIC tx_thread_fpu_enable tx_thread_fpu_enable: -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller - PUBLIC tx_thread_fpu_disable tx_thread_fpu_disable: -; -; /* Automatic VPF logic is supported, this function is present only for -; backward compatibility purposes and therefore simply returns. */ -; - BX LR ; Return to caller + + /* Automatic VPF logic is supported, this function is present only for + backward compatibility purposes and therefore simply returns. */ + + BX LR // Return to caller #endif - END diff --git a/ports/cortex_m7/iar/src/tx_thread_stack_build.s b/ports/cortex_m7/iar/src/tx_thread_stack_build.s index 919b0da7..ee9e07e3 100644 --- a/ports/cortex_m7/iar/src/tx_thread_stack_build.s +++ b/ports/cortex_m7/iar/src/tx_thread_stack_build.s @@ -1,134 +1,132 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_stack_build Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build Cortex-M7/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { PUBLIC _tx_thread_stack_build _tx_thread_stack_build: -; -; -; /* Build a fake interrupt frame. The form of the fake interrupt stack -; on the Cortex-M7 should look like the following after it is built: -; -; Stack Top: -; LR Interrupted LR (LR at time of PENDSV) -; r4 Initial value for r4 -; r5 Initial value for r5 -; r6 Initial value for r6 -; r7 Initial value for r7 -; r8 Initial value for r8 -; r9 Initial value for r9 -; r10 Initial value for r10 -; r11 Initial value for r11 -; 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 - BIC r2, r2, #0x7 ; Align frame for 8-byte alignment - SUB r2, r2, #68 ; Subtract frame size - LDR r3, =0xFFFFFFFD ; Build initial LR value - STR r3, [r2, #0] ; Save on the stack -; -; /* Actually build the stack frame. */ -; - MOV r3, #0 ; Build initial register value - STR r3, [r2, #4] ; Store initial r4 - STR r3, [r2, #8] ; Store initial r5 - STR r3, [r2, #12] ; Store initial r6 - STR r3, [r2, #16] ; Store initial r7 - STR r3, [r2, #20] ; Store initial r8 - STR r3, [r2, #24] ; Store initial r9 - STR r3, [r2, #28] ; Store initial r10 - STR r3, [r2, #32] ; Store initial r11 -; -; /* 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 - MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value - STR r3, [r2, #56] ; Store initial lr - STR r1, [r2, #60] ; Store initial pc - MOV 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 -;} + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-M should look like the following after it is built: + + Stack Top: + LR Interrupted LR (LR at time of PENDSV) + r4 Initial value for r4 + r5 Initial value for r5 + r6 Initial value for r6 + r7 Initial value for r7 + r8 Initial value for r8 + r9 Initial value for r9 + r10 Initial value for r10 + r11 Initial value for r11 + 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 + BIC r2, r2, #0x7 // Align frame for 8-byte alignment + SUB r2, r2, #68 // Subtract frame size + LDR r3, =0xFFFFFFFD // Build initial LR value + STR r3, [r2, #0] // Save on the stack + + /* Actually build the stack frame. */ + + MOV r3, #0 // Build initial register value + STR r3, [r2, #4] // Store initial r4 + STR r3, [r2, #8] // Store initial r5 + STR r3, [r2, #12] // Store initial r6 + STR r3, [r2, #16] // Store initial r7 + STR r3, [r2, #20] // Store initial r8 + STR r3, [r2, #24] // Store initial r9 + STR r3, [r2, #28] // Store initial r10 + STR r3, [r2, #32] // Store initial r11 + + /* 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 + MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value + STR r3, [r2, #56] // Store initial lr + STR r1, [r2, #60] // Store initial pc + MOV 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 diff --git a/ports/cortex_m7/iar/src/tx_thread_system_return.s b/ports/cortex_m7/iar/src/tx_thread_system_return.s index 81be6e32..571f9b21 100644 --- a/ports/cortex_m7/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m7/iar/src/tx_thread_system_return.s @@ -1,87 +1,92 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_system_return Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_system_return(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return Cortex-M7/IAR */ +/* 6.1.7 */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { PUBLIC _tx_thread_system_return -_tx_thread_system_return??rA: _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. */ -; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 + + /* Return to real scheduler via PendSV. Note that this routine is often + replaced with in-line assembly in tx_port.h to improved performance. */ + + MOV r0, #0x10000000 // Load PENDSVSET bit + MOV r1, #0xE000E000 // Load NVIC base + STR r0, [r1, #0xD04] // 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 +#ifdef TX_PORT_USE_BASEPRI + MRS r1, BASEPRI // Thread context returning, pickup BASEPRI + MOV r0, #0 + MSR BASEPRI, r0 // Enable interrupts + MSR BASEPRI, r1 // Restore original interrupt posture +#else + MRS r1, PRIMASK // Thread context returning, pickup PRIMASK + CPSIE i // Enable interrupts + MSR PRIMASK, r1 // Restore original interrupt posture +#endif _isr_context: - BX lr ; Return to caller -;} + BX lr // Return to caller +// } END diff --git a/ports/cortex_m7/iar/src/tx_timer_interrupt.s b/ports/cortex_m7/iar/src/tx_timer_interrupt.s index 2f5594d5..7c899085 100644 --- a/ports/cortex_m7/iar/src/tx_timer_interrupt.s +++ b/ports/cortex_m7/iar/src/tx_timer_interrupt.s @@ -1,26 +1,25 @@ -;/**************************************************************************/ -;/* */ -;/* 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 */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -; +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + EXTERN _tx_timer_time_slice EXTERN _tx_timer_system_clock EXTERN _tx_timer_current_ptr @@ -33,224 +32,221 @@ EXTERN _tx_thread_current_ptr EXTERN _tx_thread_execute_ptr EXTERN _tx_thread_preempt_disable -; -; + SECTION `.text`:CODE:NOROOT(2) THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_timer_interrupt Cortex-M7/IAR */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, 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 */ -;/* the expiration functions are called. */ -;/* */ -;/* 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 William E. Lamie Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_timer_interrupt(VOID) -;{ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt Cortex-M7/IAR */ +/* 6.1.7 */ +/* 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 */ +/* expiration functions are called. */ +/* */ +/* 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 */ +/* */ +/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { PUBLIC _tx_timer_interrupt _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++; -; - MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock - LDR r0, [r1, #0] ; Pickup system clock - ADD r0, r0, #1 ; Increment system clock - STR r0, [r1, #0] ; Store new system clock -; -; /* Test for time-slice expiration. */ -; if (_tx_timer_time_slice) -; { -; - MOV32 r3, _tx_timer_time_slice ; Pickup address of 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--; -; - SUB 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; -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag - MOV 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) -; { -; - MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address - 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; -; - MOV32 r3, _tx_timer_expired ; Pickup expiration flag address - MOV 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++; -; - ADD r0, r0, #4 ; Move to next timer -; -; /* Check for wrap-around. */ -; if (_tx_timer_current_ptr == _tx_timer_list_end) -; - MOV32 r3, _tx_timer_list_end ; Pickup addr of 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; -; - MOV32 r3, _tx_timer_list_start ; Pickup addr of 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)) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag - 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 - MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag - LDR r0, [r1, #0] ; Pickup timer expired flag - CBZ r0, __tx_timer_nothing_expired ; Did a timer expire? - ; No, nothing expired -; -__tx_something_expired: -; -; - STMDB sp!, {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) -; { -; - MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag - 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) -; { -; - MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired - 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 - MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag - LDR r1, [r0] ; Is the preempt disable flag set? - CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic - MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup the current thread pointer - MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address - LDR r3, [r2] ; Pickup the execute thread pointer - MOV32 r0, 0xE000ED04 ; Build address of control register - MOV32 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 + /* 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++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for time-slice expiration. */ + // if (_tx_timer_time_slice) + // { + + LDR r3, =_tx_timer_time_slice // Pickup address of 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--; + + SUB 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? + // No, skip expiration processing + + /* Set the time-slice expired flag. */ + // _tx_timer_expired_time_slice = TX_TRUE; + + LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag + MOV 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) + // { + + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address + 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; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV 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++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of 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; + + LDR r3, =_tx_timer_list_start // Pickup addr of 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)) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag + 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 + LDR r1, =_tx_timer_expired // Pickup addr of other expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CBZ r0, __tx_timer_nothing_expired // Did a timer expire? + // No, nothing expired + +__tx_something_expired: + + STMDB sp!, {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) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + 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) + // { + + LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired + 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 + LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r1, [r0] // Is the preempt disable flag set? + CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r1, [r0] // Pickup the current thread pointer + LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address + 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: -; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for - ; the 8-byte stack alignment -; -; } -; + + LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for + // the 8-byte stack alignment + + // } + __tx_timer_nothing_expired: - DSB ; Complete all memory access - BX lr ; Return to caller -; -;} + DSB // Complete all memory access + BX lr // Return to caller +// } END diff --git a/ports/rxv2/ccrx/inc/tx_port.h b/ports/rxv2/ccrx/inc/tx_port.h index 332a7711..d364f986 100644 --- a/ports/rxv2/ccrx/inc/tx_port.h +++ b/ports/rxv2/ccrx/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h RXv2/CCRX */ -/* 6.1.3 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Express Logic, Inc. */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -48,6 +48,8 @@ /* DATE NAME DESCRIPTION */ /* */ /* 12-31-2020 William E. Lamie Initial Version 6.1.3 */ +/* 06-02-2021 William E. Lamie Modified comments, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -271,7 +273,7 @@ extern volatile ULONG _tx_thread_system_state; #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv2/CCRX Version 6.1.3 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv2/CCRX Version 6.1.7 *"; #else extern CHAR _tx_version_id[]; #endif diff --git a/ports/rxv2/ccrx/readme_threadx.txt b/ports/rxv2/ccrx/readme_threadx.txt index c1544d5b..1b00bc72 100644 --- a/ports/rxv2/ccrx/readme_threadx.txt +++ b/ports/rxv2/ccrx/readme_threadx.txt @@ -121,25 +121,17 @@ of the EPK for generic usage details. To add the EPK to your RXv2 release make the following modifications: * Enable the following define for both the Threadx library and the application -TX_ENABLE_EXECUTION_CHANGE_NOTIFY - -* in tx_port.h, change around line 183 -change #define TX_THREAD_EXTENSION_3 -into #include "tx_execution_profile.h" +TX_EXECUTION_PROFILE_ENABLE * Setup CMT1 as a free running 16 bit timer. -* In tx_execution_profile.h, change following around line 74: +* In tx_execution_profile.h, change following around line 52: #ifdef TX_EXECUTION_64BIT_TIME typedef unsigned long long EXECUTION_TIME; -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; #define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF #else typedef unsigned long EXECUTION_TIME; -#define TX_THREAD_EXTENSION_3 unsigned long tx_thread_execution_time_total; \ - unsigned long tx_thread_execution_time_last_start; #define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF #endif @@ -161,6 +153,9 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +xx-xx-xxxx Release 6.1.7 changes: + readme_threadx.txt Updated instructions on how to use execution profile. + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition diff --git a/ports/rxv2/gnu/inc/tx_port.h b/ports/rxv2/gnu/inc/tx_port.h index 912cf314..97747171 100644 --- a/ports/rxv2/gnu/inc/tx_port.h +++ b/ports/rxv2/gnu/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h RXv2/GNURX */ -/* 6.1.3 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Express Logic, Inc. */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -48,6 +48,8 @@ /* DATE NAME DESCRIPTION */ /* */ /* 12-31-2020 William E. Lamie Initial Version 6.1.3 */ +/* 06-02-2021 William E. Lamie Modified comments, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -221,8 +223,8 @@ VOID _tx_thread_interrupt_restore(UIN #else -#define TX_INTERRUPT_SAVE_AREA UCHAR interrupt_save; -#define TX_DISABLE {interrupt_save = ((UCHAR)__builtin_rx_mvfc(0u) && 0x8u); __builtin_rx_clrpsw(8u);}; +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE {interrupt_save = ((UINT)__builtin_rx_mvfc(0u) && 0x8u); __builtin_rx_clrpsw(8u);}; #define TX_RESTORE {if(interrupt_save != 0u) {__builtin_rx_setpsw(8u);}}; #define _tx_thread_system_return _tx_thread_system_return_inline @@ -255,7 +257,7 @@ static void _tx_thread_system_return_inline(void) #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv2/GNURX Version 6.1.3 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv2/GNURX Version 6.1.7 *"; #else extern CHAR _tx_version_id[]; #endif diff --git a/ports/rxv2/gnu/readme_threadx.txt b/ports/rxv2/gnu/readme_threadx.txt index d548a556..b722acb0 100644 --- a/ports/rxv2/gnu/readme_threadx.txt +++ b/ports/rxv2/gnu/readme_threadx.txt @@ -121,25 +121,17 @@ of the EPK for generic usage details. To add the EPK to your RXv2 release make the following modifications: * Enable the following define for both the Threadx library and the application -TX_ENABLE_EXECUTION_CHANGE_NOTIFY - -* in tx_port.h, change around line 183 -change #define TX_THREAD_EXTENSION_3 -into #include "tx_execution_profile.h" +TX_EXECUTION_PROFILE_ENABLE * Setup CMT1 as a free running 16 bit timer. -* In tx_execution_profile.h, change following around line 74: +* In tx_execution_profile.h, change following around line 52: #ifdef TX_EXECUTION_64BIT_TIME typedef unsigned long long EXECUTION_TIME; -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; #define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF #else typedef unsigned long EXECUTION_TIME; -#define TX_THREAD_EXTENSION_3 unsigned long tx_thread_execution_time_total; \ - unsigned long tx_thread_execution_time_last_start; #define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF #endif @@ -157,6 +149,11 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +06-02-2021 Release 6.1.7 changes: + tx_port.h Fix TX_RESTORE issue + readme_threadx.txt Updated instructions on how to use execution profile. + + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition diff --git a/ports/rxv2/iar/inc/tx_port.h b/ports/rxv2/iar/inc/tx_port.h index a63370c9..9000dfbf 100644 --- a/ports/rxv2/iar/inc/tx_port.h +++ b/ports/rxv2/iar/inc/tx_port.h @@ -26,11 +26,11 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h RXv2/IAR */ -/* 6.1.3 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Express Logic, Inc. */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -48,6 +48,8 @@ /* DATE NAME DESCRIPTION */ /* */ /* 12-31-2020 William E. Lamie Initial Version 6.1.3 */ +/* 06-02-2021 William E. Lamie Modified comments, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -263,7 +265,7 @@ extern volatile ULONG _tx_thread_system_state; #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv2/IAR Version 6.1.3 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv2/IAR Version 6.1.7 *"; #else extern CHAR _tx_version_id[]; #endif diff --git a/ports/rxv2/iar/readme_threadx.txt b/ports/rxv2/iar/readme_threadx.txt index b672d4ff..a31fb8da 100644 --- a/ports/rxv2/iar/readme_threadx.txt +++ b/ports/rxv2/iar/readme_threadx.txt @@ -118,25 +118,17 @@ of the EPK for generic usage details. To add the EPK to your RXv2 release make the following modifications: * Enable the following define for both the Threadx library and the application -TX_ENABLE_EXECUTION_CHANGE_NOTIFY - -* in tx_port.h, change around line 183 -change #define TX_THREAD_EXTENSION_3 -into #include "tx_execution_profile.h" +TX_EXECUTION_PROFILE_ENABLE * Setup CMT1 as a free running 16 bit timer. -* In tx_execution_profile.h, change following around line 74: +* In tx_execution_profile.h, change following around line 52: #ifdef TX_EXECUTION_64BIT_TIME typedef unsigned long long EXECUTION_TIME; -#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ - unsigned long long tx_thread_execution_time_last_start; #define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF #else typedef unsigned long EXECUTION_TIME; -#define TX_THREAD_EXTENSION_3 unsigned long tx_thread_execution_time_total; \ - unsigned long tx_thread_execution_time_last_start; #define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF #endif @@ -154,6 +146,9 @@ For generic code revision information, please refer to the readme_threadx_generi file, which is included in your distribution. The following details the revision information associated with this specific port of ThreadX: +xx-xx-xxxx Release 6.1.7 changes: + readme_threadx.txt Updated instructions on how to use execution profile. + 04-02-2021 Release 6.1.6 changes: tx_port.h Updated macro definition diff --git a/ports/rxv3/ccrx/inc/tx_port.h b/ports/rxv3/ccrx/inc/tx_port.h new file mode 100644 index 00000000..8c749308 --- /dev/null +++ b/ports/rxv3/ccrx/inc/tx_port.h @@ -0,0 +1,281 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port.h RXv3/CCRX */ +/* 6.1.7 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make the ThreadX */ +/* real-time kernel function identically on a variety of different */ +/* processor architectures. For example, the size or number of bits */ +/* in an "int" data type vary between microprocessor architectures and */ +/* even C compilers for the same microprocessor. ThreadX does not */ +/* directly use native C data types. Instead, ThreadX creates its */ +/* own special types that can be mapped to actual data types by this */ +/* file to guarantee consistency in the interface and functionality. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ + +#ifndef TX_PORT_H +#define TX_PORT_H + +/* Determine if the optional ThreadX user define file should be used. */ + +#ifdef TX_INCLUDE_USER_DEFINE_FILE + + +/* Yes, include the user defines in tx_user.h. The defines in this file may + alternately be defined on the command line. */ + +#include "tx_user.h" +#endif + +/* Define ThreadX basic types for this port. */ + +#define VOID void +typedef char CHAR; +typedef unsigned char UCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long ULONG; +typedef short SHORT; +typedef unsigned short USHORT; + + +/* Define the priority levels for ThreadX. Legal values range + from 32 to 1024 and MUST be evenly divisible by 32. */ + +#ifndef TX_MAX_PRIORITIES +#define TX_MAX_PRIORITIES 32 +#endif + + +/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during + thread creation is less than this value, the thread create call will return an error. */ + +#ifndef TX_MINIMUM_STACK +#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */ +#endif + + +/* Define the system timer thread's default stack size and priority. These are only applicable + if TX_TIMER_PROCESS_IN_ISR is not defined. */ + +#ifndef TX_TIMER_THREAD_STACK_SIZE +#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ +#endif + +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#endif + +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time +#endif +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the port specific options for the _tx_build_options variable. This variable indicates + how the ThreadX library was built. */ + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#define TX_INLINE_INITIALIZATION + + +/* 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 + logic. */ + +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif + + +/* 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 + existing ThreadX kernel awareness modules. */ + +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_2 +#define TX_THREAD_EXTENSION_3 + + +/* Define the port extensions of the remaining ThreadX objects. */ + +#define TX_BLOCK_POOL_EXTENSION +#define TX_BYTE_POOL_EXTENSION +#define TX_EVENT_FLAGS_GROUP_EXTENSION +#define TX_MUTEX_EXTENSION +#define TX_QUEUE_EXTENSION +#define TX_SEMAPHORE_EXTENSION +#define TX_TIMER_EXTENSION + + +/* 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 +#define TX_THREAD_USER_EXTENSION +#endif + + +/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, + tx_thread_shell_entry, and tx_thread_terminate. */ + + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + + +/* Define the ThreadX object creation extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) +#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) +#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) +#define TX_TIMER_CREATE_EXTENSION(timer_ptr) + + +/* Define the ThreadX object deletion extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) +#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) +#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) +#define TX_TIMER_DELETE_EXTENSION(timer_ptr) + + +/* Define ThreadX interrupt lockout and restore macros for protection on + access of critical kernel information. The restore interrupt macro must + restore the interrupt posture of the running thread prior to the value + present prior to the disable macro. In most cases, the save area macro + is used to define a local function save area for the disable and restore + macros. */ + +/* UINT _tx_thread_interrupt_control(UINT new_posture); */ + +#pragma inline_asm _tx_thread_interrupt_disable +static UINT _tx_thread_interrupt_disable(void){ + MVFC PSW,R1 ; + CLRPSW I ; +} + + +#pragma inline_asm _tx_thread_interrupt_restore +static void _tx_thread_interrupt_restore(UINT old_posture){ + MVFC PSW, R2 ; + BTST #16,r1 ; + BMC #16,r2 ; + MVTC r2,PSW ; +} + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); + + +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); + + +#define _tx_thread_system_return _tx_thread_system_return_inline + +static void _tx_thread_system_return_inline(void) +{ + UINT interrupt_save; + + interrupt_save = _tx_thread_interrupt_disable(); + + *((volatile UCHAR *)(0x872E0u)) = 1u; + + _tx_thread_interrupt_restore(interrupt_save); +} + + +#ifndef TX_THREAD_GET_SYSTEM_STATE + +#pragma inline_asm _get_psw +static UINT _get_psw(void){ + MVFC PSW,R1 ; +} + +extern volatile ULONG _tx_thread_system_state; +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | ((~_get_psw()) & (1u << 17u))) +#endif + + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + +/* 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 RXv3/CCRX Version 6.1.7 *"; +#else +extern CHAR _tx_version_id[]; +#endif + + +#endif + diff --git a/ports/rxv3/ccrx/readme_threadx.txt b/ports/rxv3/ccrx/readme_threadx.txt new file mode 100644 index 00000000..3f7c4c08 --- /dev/null +++ b/ports/rxv3/ccrx/readme_threadx.txt @@ -0,0 +1,162 @@ + Microsoft's Azure RTOS ThreadX for Renesas RXv3 + + Using the CC-RX Tools + +1. Building the ThreadX run-time Library + +Please see the Samples repository on GitHub for the Azure RTOS demonstrations +for the RXv3. + + +2. Demonstration System + +Please see the Samples repository on GitHub for the Azure RTOS demonstrations +for the RXv3 + + +3. System Initialization + +The system entry point using Renesas tools is at the label _PowerON_Reset_PC. +Use the resetprg.c file that comes with your release. Most notable is that Threadx +applications run in supervisor mode and do not use user mode. Hence switching to +user mode has been commented out. + +The vector area is set up using either intprg.c or in the file tx_initialize_low_level.src. +The file tx_initialize_low_level.src is responsible for setting up various system data +structures, interrupt vectors, and a periodic timer. This is the ideal place add +application specific hardware initialization code. + +ThreadX utilizes CMT0 as a periodic timer interrupt source. The CMT0 interrupt is +typically setup for 10ms periodic interrupts and the interrupt priority level is set to +level 7. You may change any of the timer parameters to suit your needs. + +In addition, _tx_initialize_low_level determines the first available address for use by +the application, which is supplied as the sole input parameter to your application +definition function, tx_application_define(). The mechanism is implemented by creating the +FREEMEM section, this section should be linked last in the RAM area. tx_initialize_low_level +will pick up the starting label of this section and put it in the global variable: +_tx_initialize_unused_memory + + +4. Context Switch, Register Usage and Stack Frames + +The RXv3 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17, +to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT +should not be manipulated in any way by the application. The port will setup the +interrupt within _tx_initialize_low_level and the compiler will automatically install +the necessary interrupt vector. As such no additional initialization is necessary by the +application. + +The following defines the saved context stack frame used by the ThreadX port. The +state of the CPU registers at the time of a context switch is saved on the running +thread's stack The top of the suspended thread's stack is pointed to by +tx_thread_stack_ptr in the associated thread control block TX_THREAD. + + Offset Interrupted Stack Frame + + 0x00 1 + 0x04 ACC0 + 0x08 ACC1 + 0x0C R6 + 0x10 R7 + 0x14 R8 + 0x18 R9 + 0x1C R10 + 0x20 R11 + 0x24 R12 + 0x28 R13 + 0x2C FPSW + 0x30 R14 + 0x34 R15 + 0x38 R3 + 0x3C R4 + 0x40 R5 + 0x44 R1 + 0x48 R2 + 0x4C PC - return address + 0x50 PSW + +Note: By default ccrx does not save the state of the accumulator registers ACC0 and ACC1 +when entering an ISR. This means that if the ISR uses any of the DSP instructions the +content of those registers could be corrupted. Saving and restoring of the acummulators +can be enabled by adding the -save_acc command line option. + + +5. Improving Performance + +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make ThreadX run faster, you can change the ThreadX Library +project to disable debug information and enable the desired optimizations. + +In addition, you can eliminate the ThreadX basic API error checking by +compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING +defined before tx_api.h is included. + + +6. Timer Processing + +Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done +from within the callback of a periodic timer with a period of 100Hz. In the sample projects +a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source. + + +7. Interrupt Handling + +Interrupt handling is unaffected by the ThreadX port as such user interrupts can be +written according to the toolchain's documentation. It is recommended not to use interrupt +priority 15 as this is the priority of the context switch interrupt. However using interrupt +priority 15 won't cause any negative side effectd but doing so may may slightly reduce +performance. Please refer to the toolchain documentation for additional details on how to +define interupt service routines. + + +8. Execution Profiling + +The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists +of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation +of the EPK for generic usage details. + +To add the EPK to your RXv3 release make the following modifications: + +* Enable the following define for both the Threadx library and the application +TX_EXECUTION_PROFILE_ENABLE + +* Setup CMT1 as a free running 16 bit timer. + +* In tx_execution_profile.h, change following around line 52: + +#ifdef TX_EXECUTION_64BIT_TIME +typedef unsigned long long EXECUTION_TIME; +#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF +#else +typedef unsigned long EXECUTION_TIME; +#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF +#endif + +/* Define basic constants for the execution profile kit. */ + +#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A) + +Rebuild the Threadx library and the application. +Refer to the EPK documentation how to interpret the results. + + +9. Revision History + +For generic code revision information, please refer to the readme_threadx_generic.txt +file, which is included in your distribution. The following details the revision +information associated with this specific port of ThreadX: + +For generic code revision information, please refer to the readme_threadx_generic.txt +file, which is included in your distribution. The following details the revision +information associated with this specific port of ThreadX: + +06-02-2021 Initial ThreadX release for the RXv3 using CC-RXX tools, version 6.1.7 + + +Copyright(c) 1996-2021 Microsoft Corporation + + +https://azure.com/rtos diff --git a/ports/cortex_m33/ac5/src/tx_thread_context_restore.s b/ports/rxv3/ccrx/src/tx_initialize_low_level.src similarity index 60% rename from ports/cortex_m33/ac5/src/tx_thread_context_restore.s rename to ports/rxv3/ccrx/src/tx_initialize_low_level.src index 87b18f05..b1b63bad 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_context_restore.s +++ b/ports/rxv3/ccrx/src/tx_initialize_low_level.src @@ -12,81 +12,90 @@ ; ;/**************************************************************************/ ;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ ;/** */ -;/** ThreadX Component */ -;/** */ -;/** Thread */ +;/** Initialize */ ;/** */ ;/**************************************************************************/ ;/**************************************************************************/ ; -; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY - IMPORT _tx_execution_isr_exit - ENDIF -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M33/AC5 */ -;/* 6.1 */ -;/* AUTHOR */ -;/* */ -;/* Scott Larson, Microsoft Corporation */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function restores the interrupt context if it is processing a */ -;/* nested interrupt. If not, it returns to the interrupt thread if no */ -;/* preemption is necessary. Otherwise, if preemption is necessary or */ -;/* if no thread was running, the function returns to the scheduler. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* _tx_thread_schedule Thread scheduling routine */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* ISRs Interrupt Service Routines */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 09-30-2020 Scott Larson Initial Version 6.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_thread_context_restore(VOID) -;{ - EXPORT _tx_thread_context_restore -_tx_thread_context_restore FUNCTION - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the ISR exit function to indicate an ISR is complete. */ -; - PUSH {r0, lr} ; Save return address - BL _tx_execution_isr_exit ; Call the ISR exit function - POP {r0, lr} ; Recover Save return address - ENDIF -; -; /* Return to interrupt processing. */ -; - BX lr -;} - ENDFUNC - ALIGN - LTORG - END + + .GLB __tx_initialize_unused_memory + + IPR03 .EQU 87303H + IEN03 .EQU 87203H + + .SECTION P,CODE +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_initialize_low_level RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ + + .GLB __tx_initialize_low_level +__tx_initialize_low_level: +; +; /* Save the first available memory address. */ +; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start; +; + MOV.L #free_mem_start, R1 ; Pickup unused memory address + MOV.L #__tx_initialize_unused_memory,R2 + MOV.L R1,[R2] ; Save first free memory address + +; /* Set priority of SWINT to 1. */ + MOV.L #IPR03, r1 + MOV.L #1, r2 + MOV.B r2, [r1] + +; /* Enable SWINT. */ + MOV.L #IEN03,r1 + MOV.B [r1], r2 + OR #(1 << 3), r2 + MOV.B r2, [r1] + + RTS + + .SECTION FREEMEM ,DATA, ALIGN=4 +free_mem_start: + .BLKL 8 ; this section is last in the link map so we can access the end of RAM memory + + .END diff --git a/ports/rxv3/ccrx/src/tx_thread_context_restore.src b/ports/rxv3/ccrx/src/tx_thread_context_restore.src new file mode 100644 index 00000000..ccbe3796 --- /dev/null +++ b/ports/rxv3/ccrx/src/tx_thread_context_restore.src @@ -0,0 +1,207 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; +; + .GLB __tx_thread_system_state + .GLB __tx_thread_current_ptr + .GLB __tx_thread_system_stack_ptr + .GLB __tx_thread_execute_ptr + .GLB __tx_timer_time_slice + .GLB __tx_thread_schedule + .GLB __tx_thread_preempt_disable +; + .SECTION P,CODE +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_restore RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the interrupt context if it is processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_restore(VOID) +;{ + .GLB __tx_thread_context_restore +__tx_thread_context_restore: +; +; /* Lockout interrupts. */ + + CLRPSW I ; disable interrupts + +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { + + MOV.L #__tx_thread_system_state, R1 + MOV.L [R1], R2 + SUB #1, R2 + MOV.L R2,[R1] + BEQ __tx_thread_not_nested_restore + +; +; /* Interrupts are nested. */ +; +; /* Recover the saved registers from the interrupt stack +; and return to the point of interrupt. */ +; +__tx_thread_nested_restore: + POPC FPSW ; restore FPU status + POPM R14-R15 ; restore R14-R15 + POPM R3-R5 ; restore R3-R5 + POPM R1-R2 ; restore R1-R2 + RTE ; return to point of interrupt, restore PSW including IPL +; } + +__tx_thread_not_nested_restore: +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { + + MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address + MOV.L [R1], R2 + CMP #0, R2 + BEQ __tx_thread_idle_system_restore + + MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag + MOV.L [R3], R3 + CMP #0, R3 + BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless + + MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr) + CMP [R3], R2 + BNE __tx_thread_preempt_restore ; jump to pre-empt restoring +; +__tx_thread_no_preempt_restore: + SETPSW U ; user stack + POPC FPSW ; restore FPU status + POPM R14-R15 ; restore R14-R15 + POPM R3-R5 ; restore R3-R5 + POPM R1-R2 ; restore R1-R2 + RTE ; return to point of interrupt, restore PSW including IPL + +; } +; else +; { + +__tx_thread_preempt_restore: + +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { + + MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address + MOV.L [R3],R4 ; Pickup actual time-slice + CMP #0, R4 + BEQ __tx_thread_dont_save_ts ; no time slice to save +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + MOV.L R4,24[R2] ; Save thread's time slice + MOV.L #0,R4 ; Clear value + MOV.L R4,[R3] ; Disable global time slice flag +; } +__tx_thread_dont_save_ts: +; +; /* Now store the remaining registers! */ + + SETPSW U ; user stack + PUSHM R6-R13 + + MVFACGU #0, A1, R4 ; Save accumulators. + MVFACHI #0, A1, R5 + MVFACLO #0, A1, R6 + PUSHM R4-R6 + MVFACGU #0, A0, R4 + MVFACHI #0, A0, R5 + MVFACLO #0, A0, R6 + PUSHM R4-R6 + + MOV.L #1, R3 ; indicate interrupt stack frame + PUSH.L R3 + +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; R1 -> _tx_thread_current_ptr +; R2 -> *_tx_thread_current_ptr + + MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block + MOV.L #0,R2 ; Build NULL value + MOV.L R2,[R1] ; Set current thread to NULL + +; /* Return to the scheduler. */ +; _tx_thread_schedule(); + +__tx_thread_idle_system_restore: + MVTC #0, PSW ; reset interrupt priority level to 0 + BRA __tx_thread_schedule ; jump to scheduler +; } +; +;} +; + .END + diff --git a/ports/rxv3/ccrx/src/tx_thread_context_save.src b/ports/rxv3/ccrx/src/tx_thread_context_save.src new file mode 100644 index 00000000..602addb8 --- /dev/null +++ b/ports/rxv3/ccrx/src/tx_thread_context_save.src @@ -0,0 +1,171 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; + .GLB __tx_thread_system_state + .GLB __tx_thread_current_ptr + .GLB __tx_thread_system_stack_ptr + + .SECTION P,CODE +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_save RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_save(VOID) +;{ + .GLB __tx_thread_context_save +__tx_thread_context_save: +; +; /* Upon entry to this routine, it is assumed that interrupts are locked +; out and the (interrupt) stack frame looks like the following: +; +; (lower address) SP -> [return address of this call] +; SP+4 -> Saved R1 +; SP+8 -> Saved R2 +; SP+12-> Interrupted PC +; SP+16-> Interrupted PSW +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + + MOV.L #__tx_thread_system_state, R1 ; pick up address of system state + MOV.L [R1], R2 ; pick up system state + CMP #0, R2 ; 0 -> no nesting + BEQ __tx_thread_not_nested_save +; +; /* Nested interrupt condition. */ +; + ADD #1, r2 ; _tx_thread_system_state++ + MOV.L r2, [r1] + +; +; /* Save the rest of the scratch registers on the interrupt stack and return to the +; calling ISR. */ + POP R1 ; recuperate return address from stack + PUSHM R3-R5 + PUSHM R14-R15 + PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom) + JMP R1 ; return address was preserved in R1 + +; +__tx_thread_not_nested_save: +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD #1, R2 ; _tx_thread_system_state++ + MOV.L R2, [R1] + + MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer + MOV.L [R2], R2 + CMP #0,R2 ; Is it NULL? + BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore +; +; /* Move stack frame over to the current threads stack. */ +; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */ +; + MVFC USP, R1 ; pick up user stack pointer + MOV.L 16[R0], R2 + MOV.L R2, [-R1] ; save PSW on thread stack + MOV.L 12[R0], R2 + MOV.L R2, [-R1] ; save PC on thread stack + MOV.L 8[R0], R2 + MOV.L R2, [-R1] ; save R2 on thread stack + MOV.L 4[R0], R2 + MOV.L R2, [-R1] ; save R1 on thread stack + MOV.L R5, [-R1] ; save R5 on thread stack + MOV.L R4, [-R1] ; save R4 on thread stack + MOV.L R3, [-R1] ; save R3 on thread stack + MOV.L R15, [-R1] ; save R15 on thread stack + MOV.L R14, [-R1] ; save R14 on thread stack + MVFC FPSW, R3 + MOV.L R3, [-R1] ; save FPSW on thread stack + + POP R2 ; pick up return address from interrupt stack + ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom + MVTC R1, USP ; set user/thread stack pointer + JMP R2 ; return to ISR + +; } +; else +; { +; +__tx_thread_idle_system_save: +; +; /* Interrupt occurred in the scheduling loop. */ +; + POP R1 ; pick up return address + ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers + JMP R1 ; return to caller +; +; } +;} + .END + diff --git a/ports/cortex_m23/ac5/src/tx_thread_interrupt_control.s b/ports/rxv3/ccrx/src/tx_thread_interrupt_control.src similarity index 72% rename from ports/cortex_m23/ac5/src/tx_thread_interrupt_control.s rename to ports/rxv3/ccrx/src/tx_thread_interrupt_control.src index 3065564b..6c18a6ce 100644 --- a/ports/cortex_m23/ac5/src/tx_thread_interrupt_control.s +++ b/ports/rxv3/ccrx/src/tx_thread_interrupt_control.src @@ -12,67 +12,85 @@ ; ;/**************************************************************************/ ;/**************************************************************************/ -;/** */ -;/** ThreadX Component */ +;/** */ +;/** ThreadX Component */ ;/** */ ;/** Thread */ ;/** */ ;/**************************************************************************/ ;/**************************************************************************/ ; +;#define TX_SOURCE_CODE ; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_control Cortex-M23/AC5 */ -;/* 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 */ -;/* */ -;/**************************************************************************/ +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + .SECTION P,CODE +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_control RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ ;UINT _tx_thread_interrupt_control(UINT new_posture) ;{ - EXPORT _tx_thread_interrupt_control -_tx_thread_interrupt_control FUNCTION + +.GLB __tx_thread_interrupt_control +__tx_thread_interrupt_control: ; ; /* Pickup current interrupt lockout posture. */ ; - MRS r1, PRIMASK - MSR PRIMASK, r0 - MOV r0, r1 - BX lr + + MVFC PSW, R2 ; Save PSW to R2 + MOV.L R2, R3 ; Make a copy of PSW in r3 + ; +; /* Apply the new interrupt posture. */ +; + + BTST #16, R1 ; test I bit of PSW of "new posture" + BMNE #16, R2 ; conditionally set I bit of intermediate posture + + MVTC R2, PSW ; save intermediate posture to PSW + + MOV.L R3,R1 ; Get original SR + RTS ; Return to caller ;} - ENDFUNC - END + .END + diff --git a/ports/rxv3/ccrx/src/tx_thread_schedule.src b/ports/rxv3/ccrx/src/tx_thread_schedule.src new file mode 100644 index 00000000..cecdaa20 --- /dev/null +++ b/ports/rxv3/ccrx/src/tx_thread_schedule.src @@ -0,0 +1,180 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; +; + .GLB __tx_thread_execute_ptr + .GLB __tx_thread_current_ptr + .GLB __tx_timer_time_slice +; + .SECTION P,CODE + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_schedule RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* _tx_thread_context_restore Restore thread's context */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_schedule(VOID) +;{ + .GLB __tx_thread_schedule +__tx_thread_schedule: +; +; /* Enable interrupts. */ +; + SETPSW I +; +; /* Wait for a thread to execute. */ +; do +; { + MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr +__tx_thread_schedule_loop: + MOV.L [R1],R2 ; Pickup next thread to execute + CMP #0,R2 ; Is it NULL? + BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking +; +; } +; while(_tx_thread_execute_ptr == TX_NULL); +; +; /* Yes! We have a thread to execute. Lockout interrupts and +; transfer control to it. */ +; + CLRPSW I ; disable interrupts +; +; /* Setup the current thread pointer. */ +; _tx_thread_current_ptr = _tx_thread_execute_ptr; +; + MOV.L #__tx_thread_current_ptr, R3 + MOV.L R2,[R3] ; Setup current thread pointer +; +; /* Increment the run count for this thread. */ +; _tx_thread_current_ptr -> tx_thread_run_count++; +; + MOV.L 4[R2],R3 ; Pickup run count + ADD #1,R3 ; Increment run counter + MOV.L R3,4[R2] ; Store it back in control block +; +; /* Setup time-slice, if present. */ +; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; +; + MOV.L 24[R2],R3 ; Pickup thread time-slice + MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice + MOV.L R3, [R4] ; Setup time-slice +; +; /* Switch to the thread's stack. */ +; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; + SETPSW U ; user stack mode + MOV.L 8[R2],R0 ; Pickup stack pointer +; +; /* Determine if an interrupt frame or a synchronous task suspension frame +; is present. */ +; + POP R1 ; Pickup stack type + CMP #1, R1 ; Is it an interrupt stack? + BNE __tx_thread_synch_return ; No, a synchronous return frame is present. + + POPM R1-R3 ; Restore accumulators. + MVTACLO R3, A0 + MVTACHI R2, A0 + MVTACGU R1, A0 + POPM R1-R3 + MVTACLO R3, A1 + MVTACHI R2, A1 + MVTACGU R1, A1 + + POPM R6-R13 ; Recover interrupt stack frame + POPC FPSW + POPM R14-R15 + POPM R3-R5 + POPM R1-R2 + RTE ; return to point of interrupt, this restores PC and PSW + +__tx_thread_synch_return: + POPC PSW + POPM R6-R13 ; Recover solicited stack frame + RTS +; +;} + + +.GLB __tx_thread_context_save +.GLB __tx_thread_context_restore + +; Software triggered interrupt used to perform context switches. +; The priority of this interrupt is set to the lowest priority within +; tx_initialize_low_level() and triggered by ThreadX when calling +; _tx_thread_system_return(). +.RVECTOR 27, _tx_software_interrupt_entry +.GLB _tx_software_interrupt_entry +_tx_software_interrupt_entry: + + PUSHM R1-R2 + + BSR __tx_thread_context_save + + BRA __tx_thread_context_restore + + .END diff --git a/ports/rxv3/ccrx/src/tx_thread_stack_build.src b/ports/rxv3/ccrx/src/tx_thread_stack_build.src new file mode 100644 index 00000000..a161b8a7 --- /dev/null +++ b/ports/rxv3/ccrx/src/tx_thread_stack_build.src @@ -0,0 +1,155 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; + .SECTION P,CODE +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_stack_build RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +;{ + .GLB __tx_thread_stack_build +__tx_thread_stack_build: +; +; +; /* Build an interrupt frame. The form of the fake interrupt stack +; on the Renesas RX should look like the following after it is built: +; +; Stack Top: 1 Interrupt stack frame type +; ACC0 +; ACC1 +; R6 +; R7 +; R8 +; R9 +; R10 +; R11 +; R12 +; R13 +; FPSW +; R14 +; R15 +; R3 +; R4 +; R5 +; R1 +; R2 +; PC +; PSW + +; +; Stack Bottom: (higher memory address) */ +; + MOV.L 16[R1],R3 ; Pickup end of stack area + BCLR #0, R3 ; mask for 4-byte alignment + BCLR #1, R3 +; +; /* Build the stack frame. */ +; + MOV.L #30000h, R4 + MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set) + MOV.L R2, [-R3] ; initial PC + MOV.L #0, R4 + MOV.L R4,[-R3] ; initial R2 ... + MOV.L R4,[-R3] ; initial R1 ... + MOV.L R4,[-R3] ; initial R5 ... + MOV.L R4,[-R3] ; initial R4 ... + MOV.L R4,[-R3] ; initial R3 ... + MOV.L R4,[-R3] ; initial R15 ... + MOV.L R4,[-R3] ; initial R14 ... + MVFC FPSW, r4 + MOV.L R4, [-R3] ; initial FPSW + MOV.L #0, R4 + MOV.L R4,[-R3] ; initial R13 ... + MOV.L R4,[-R3] ; initial R12 ... + MOV.L R4,[-R3] ; initial R11 ... + MOV.L R4,[-R3] ; initial R10 ... + MOV.L R4,[-R3] ; initial R9 ... + MOV.L R4,[-R3] ; initial R8 ... + MOV.L R4,[-R3] ; initial R7 ... + MOV.L R4,[-R3] ; initial R6 ... + + MOV.L R4,[-R3] ; Accumulator 1 + MOV.L R4,[-R3] + MOV.L R4,[-R3] + + MOV.L R4,[-R3] ; Accumulator 0 + MOV.L R4,[-R3] + MOV.L R4,[-R3] + + MOV.L #1, R4 + MOV.L R4,[-R3] ; indicate interrupt stack frame +; /* Setup stack pointer. */ +; thread_ptr -> tx_thread_stack_ptr = R1; + MOV.L R3, 8[R1] + ; store initial SP in thread control block + RTS + +;} + .END + diff --git a/ports/cortex_m23/ac5/src/tx_thread_system_return.s b/ports/rxv3/ccrx/src/tx_thread_system_return.src similarity index 59% rename from ports/cortex_m23/ac5/src/tx_thread_system_return.s rename to ports/rxv3/ccrx/src/tx_thread_system_return.src index d2a1bf52..002c8fff 100644 --- a/ports/cortex_m23/ac5/src/tx_thread_system_return.s +++ b/ports/rxv3/ccrx/src/tx_thread_system_return.src @@ -12,77 +12,116 @@ ; ;/**************************************************************************/ ;/**************************************************************************/ -;/** */ -;/** ThreadX Component */ +;/** */ +;/** ThreadX Component */ ;/** */ ;/** Thread */ ;/** */ ;/**************************************************************************/ ;/**************************************************************************/ ; +;#define TX_SOURCE_CODE ; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_system_return Cortex-M23/AC5 */ -;/* 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 */ -;/* */ -;/**************************************************************************/ +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; + .GLB __tx_thread_current_ptr + .GLB __tx_timer_time_slice + .GLB __tx_thread_schedule + + .SECTION P,CODE +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_system_return RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is target processor specific. It is used to transfer */ +;/* control from a thread back to the 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 */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ ;VOID _tx_thread_system_return(VOID) ;{ - EXPORT _tx_thread_system_return -_tx_thread_system_return FUNCTION + .GLB __tx_thread_system_return +__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. */ +; /* Save call save registers on the stack. */ ; - 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 - NOP ; To remove added padding warning + PUSHM R6-R13 + PUSHC PSW + MOV.L #0, R1 + PUSH.L R1 ; solicited stack frame +; +; /* Lockout interrupts. */ +; + CLRPSW I ; Lockout interrupts +; +; /* Save current stack in current Thread controle block. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = SP; + MOV.L #__tx_thread_current_ptr, R2 + MOV.L [R2], R3 + MOV.L R0, 8[R3] + + MOV.L #__tx_timer_time_slice, R4 + MOV.L [R4], R5 + +; /* Determine if the time-slice is active. */ +; if (_tx_timer_time_slice) +; { +; + CMP #0,R5 ; Is a time-slice present? + BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice +; +; /* Save time-slice for the thread and clear the current time-slice. */ + ; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; + MOV.L R5,24[R3] +; _tx_timer_time_slice = 0; +; + MOV.L R1, [R4] ; Disable the time-slice +; +; } +__tx_thread_dont_save_ts: +; +; /* Clear the current thread pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV.L R1, [R2] + BRA __tx_thread_schedule ;} - ENDFUNC - END + .END + diff --git a/ports/rxv3/ccrx/src/tx_timer_interrupt.src b/ports/rxv3/ccrx/src/tx_timer_interrupt.src new file mode 100644 index 00000000..35b6fc1a --- /dev/null +++ b/ports/rxv3/ccrx/src/tx_timer_interrupt.src @@ -0,0 +1,251 @@ +;/**************************************************************************/ +;/* */ +;/* 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 */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_timer.h" +;#include "tx_thread.h" +; +; +;Define Assembly language external references... +; + .GLB __tx_timer_time_slice + .GLB __tx_timer_system_clock + .GLB __tx_timer_current_ptr + .GLB __tx_timer_list_start + .GLB __tx_timer_list_end + .GLB __tx_timer_expired_time_slice + .GLB __tx_timer_expired + .GLB __tx_timer_expiration_process + .GLB __tx_thread_context_save + .GLB __tx_thread_time_slice + .GLB __tx_thread_context_restore +; + .SECTION P,CODE +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_timer_interrupt RXv3/CCRX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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_thread_context_save Save interrupted context */ +;/* _tx_timer_expiration_process Timer expiration processing */ +;/* _tx_thread_time_slice Time slice interrupted thread */ +;/* _tx_thread_context_restore Restore interrupted context */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* interrupt vector */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_timer_interrupt(VOID) +;{ + .GLB __tx_timer_interrupt +__tx_timer_interrupt: +; +; /* Upon entry to this routine, it is assumed that all interrupts are locked +; out and the stack looks like the following: +; SP+4 -> Interrupted PC +; SP+8-> Interrupted SR +; */ +; +; /* Increment the system clock. */ +; _tx_timer_system_clock++; +; + PUSHM R14-R15 + PUSHM R1-R5 + + MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock + MOV.L [R1], R2 ; Pickup system clock + ADD #1, R2 ; Increment system clock + MOV.L R2,[R1] ; Store new system clock +; +; /* Test for time-slice expiration. */ +; if (_tx_timer_time_slice) +; { +; + MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice + MOV.L [R1], R2 ; Pickup the current time slice + CMP #0, R2 ; Is a time slice active? + BEQ __tx_timer_no_time_slice ; No, skip timer slice processing +; +; /* Decrement the time_slice. */ +; _tx_timer_time_slice--; +; + SUB #1, R2 ; Decrement the time-slice + MOV.L R2, [R1] ; Store time-slice +; +; /* Check for expiration. */ +; if (__tx_timer_time_slice == 0) +; + CMP #0, R2 ; Has it expired? + BNE __tx_timer_no_time_slice ; No, time-slice has not expired +; +; /* Set the time-slice expired flag. */ +; _tx_timer_expired_time_slice = TX_TRUE; +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice + MOV.L #1, R2 ; Build expired value + MOV.L R2, [R1] ; Set expired time slice variable +; } +; +__tx_timer_no_time_slice: +; +; /* Test for timer expiration. */ +; if (*_tx_timer_current_ptr) +; { +; + MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr + MOV.L [R1], R2 ; Pickup current pointer + MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++ + CMP #0, R1 ; Is timer pointer NULL? + BEQ __tx_timer_no_timer ; Yes, no timer has expired + +; +; /* Set expiration flag. */ +; _tx_timer_expired = TX_TRUE; +; + MOV.L #__tx_timer_expired,R2 ; Build address of expired flag + MOV.L #1, R1 ; Build expired value + MOV.L R1, [R2] + BRA __tx_timer_done ; Finished with timer processing +; +; } +; else +; { +__tx_timer_no_timer: +; +; /* No timer expired, increment the timer pointer. */ +; _tx_timer_current_ptr++; +; +; /* R2 already contains __tx_timer_current_ptr++ */ +; +; /* Check for wrap-around. */ +; if (_tx_timer_current_ptr == _tx_timer_list_end) +; + MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr + MOV.L [R1], R1 ; Pickup actual timer list end + CMP R1, R2 ; Are we at list end? + BNE __tx_timer_skip_wrap ; No, don't move pointer to the + ; top of the list +; +; /* Wrap to beginning of list. */ +; _tx_timer_current_ptr = _tx_timer_list_start; +; + MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr + MOV.L [R2], R2 ; Pickup the start of the list +; } +; +__tx_timer_skip_wrap: + MOV.L #__tx_timer_current_ptr,R1 + MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr + +__tx_timer_done: +; +; /* See if anything has expired. */ +; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) +; { +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr + MOV.L [R1], R1 ; Pickup expired time slice + MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address + MOV.L [R2], R2 ; Pickup actual flag + OR R1, R2 ; Or flags together + BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired + +__tx_something_expired: +; /* Did a timer expire? */ +; if (_tx_timer_expired) +; { + MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address + MOV.L [R1], R1 ; Pickup expired flag + CMP #0,R1 ; Is the expired timer flag set? + BEQ __tx_timer_dont_activate ; No, skip timer activation +; +; /* Process timer expiration. */ +; _tx_timer_expiration_process(); +; + BSR __tx_timer_expiration_process ; Call the timer expiration handling routine +; +; } +__tx_timer_dont_activate: +; +; /* Did time slice expire? */ +; if (_tx_timer_expired_time_slice) +; { +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr + MOV.L [R1], R1 ; Pickup actual flag + CMP #0,R1 ; Has time-slice expired? + BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration +; +; /* Time slice interrupted thread. */ +; _tx_thread_time_slice(); + + BSR __tx_thread_time_slice ; Call time-slice processing +; } +; +__tx_timer_not_ts_expiration: + +__tx_timer_nothing_expired: + + POPM R1-R5 + POPM R14-R15 +; + RTS ; return to point of interrupt +; +;} + + .END + diff --git a/ports/rxv3/gnu/inc/tx_port.h b/ports/rxv3/gnu/inc/tx_port.h new file mode 100644 index 00000000..15938343 --- /dev/null +++ b/ports/rxv3/gnu/inc/tx_port.h @@ -0,0 +1,264 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port.h RXv3/GNURX */ +/* 6.1.7 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make the ThreadX */ +/* real-time kernel function identically on a variety of different */ +/* processor architectures. For example, the size or number of bits */ +/* in an "int" data type vary between microprocessor architectures and */ +/* even C compilers for the same microprocessor. ThreadX does not */ +/* directly use native C data types. Instead, ThreadX creates its */ +/* own special types that can be mapped to actual data types by this */ +/* file to guarantee consistency in the interface and functionality. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ + +#ifndef TX_PORT_H +#define TX_PORT_H + +#include +//#include + +/* Determine if the optional ThreadX user define file should be used. */ + +#ifdef TX_INCLUDE_USER_DEFINE_FILE + + +/* Yes, include the user defines in tx_user.h. The defines in this file may + alternately be defined on the command line. */ + +#include "tx_user.h" +#endif + +/* Define ThreadX basic types for this port. */ + +#define VOID void +typedef char CHAR; +typedef unsigned char UCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long ULONG; +typedef short SHORT; +typedef unsigned short USHORT; + + +/* Define the priority levels for ThreadX. Legal values range + from 32 to 1024 and MUST be evenly divisible by 32. */ + +#ifndef TX_MAX_PRIORITIES +#define TX_MAX_PRIORITIES 32 +#endif + + +/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during + thread creation is less than this value, the thread create call will return an error. */ + +#ifndef TX_MINIMUM_STACK +#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */ +#endif + + +/* Define the system timer thread's default stack size and priority. These are only applicable + if TX_TIMER_PROCESS_IN_ISR is not defined. */ + +#ifndef TX_TIMER_THREAD_STACK_SIZE +#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ +#endif + +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#endif + + +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time +#endif +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the port specific options for the _tx_build_options variable. This variable indicates + how the ThreadX library was built. */ + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#define TX_INLINE_INITIALIZATION + + +/* 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 + logic. */ + +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif + + +/* 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 + existing ThreadX kernel awareness modules. */ + +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_2 +#define TX_THREAD_EXTENSION_3 + + +/* Define the port extensions of the remaining ThreadX objects. */ + +#define TX_BLOCK_POOL_EXTENSION +#define TX_BYTE_POOL_EXTENSION +#define TX_EVENT_FLAGS_GROUP_EXTENSION +#define TX_MUTEX_EXTENSION +#define TX_QUEUE_EXTENSION +#define TX_SEMAPHORE_EXTENSION +#define TX_TIMER_EXTENSION + + +/* 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 +#define TX_THREAD_USER_EXTENSION +#endif + + +/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, + tx_thread_shell_entry, and tx_thread_terminate. */ + + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + + +/* Define the ThreadX object creation extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) +#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) +#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) +#define TX_TIMER_CREATE_EXTENSION(timer_ptr) + + +/* Define the ThreadX object deletion extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) +#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) +#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) +#define TX_TIMER_DELETE_EXTENSION(timer_ptr) + +/* Define ThreadX interrupt lockout and restore macros for protection on + access of critical kernel information. The restore interrupt macro must + restore the interrupt posture of the running thread prior to the value + present prior to the disable macro. In most cases, the save area macro + is used to define a local function save area for the disable and restore + macros. */ + +#ifdef TX_DISABLE_INLINE + +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); + +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); + +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); + +#else + +#define TX_INTERRUPT_SAVE_AREA UCHAR interrupt_save; +#define TX_DISABLE {interrupt_save = ((UCHAR)__builtin_rx_mvfc(0u) && 0x8u); __builtin_rx_clrpsw(8u);}; +#define TX_RESTORE {if(interrupt_save != 0u) {__builtin_rx_setpsw(8u);}}; + +#define _tx_thread_system_return _tx_thread_system_return_inline + +static void _tx_thread_system_return_inline(void) +{ + TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + + *((volatile UCHAR *)(0x872E0u)) = 1u; + + TX_RESTORE +} + +#endif + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + +/* 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 RXv3/GNURX Version 6.1.7 *"; +#else +extern CHAR _tx_version_id[]; +#endif + +#endif + diff --git a/ports/rxv3/gnu/readme_threadx.txt b/ports/rxv3/gnu/readme_threadx.txt new file mode 100644 index 00000000..b168d8b4 --- /dev/null +++ b/ports/rxv3/gnu/readme_threadx.txt @@ -0,0 +1,159 @@ + Microsoft's Azure RTOS ThreadX for Renesas RXv3 + + Using the GNU Tools + + +1. Building the ThreadX run-time Library + +Please see the Samples repository on GitHub for the Azure RTOS demonstrations +for the RXv3. + + +2. Demonstration System + + +Please see the Samples repository on GitHub for the Azure RTOS demonstrations +for the RXv3. + + +3. System Initialization + +The system entry point using the GNU tools is at the label _PowerON_Reset. + +The vector area is setup in the file tx_initialize_low_level.S. This file is also +responsible for setting up various system data structures, interrupt vectors, and +the periodic timer interrupt. This file is also an ideal place to add additional hardware +initialization code. + +The ThreadX demonstration for the RXv3 utilizes CMT0 as a periodic timer interrupt +source. The CMT0 interrupt is typically setup for 10ms periodic interrupts and the +interrupt priority level is set to level 7. You may change any of the timer +parameters as needed. Increasing the timer interrupt frequency increases the overhead +of the timer handling code on the system. + +In addition, _tx_initialize_low_level determines the first available address for use +by the application, which is supplied as the sole input parameter to your application +definition function, tx_application_define. The first available memory is determined +by the location of the '_end' label the is defined in the linker script. +'_end' should reference the first memory AFTER all other RAM +sections in your linker control file. + + +4. Context Switch, Register Usage and Stack Frames + +The RXv3 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17, +to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT +should not be manipulated in any way by the application. The port will setup the +interrupt within _tx_initialize_low_level and the compiler will automatically install +the necessary interrupt vector. As such no additional initialization is necessary by the +application. + +The following defines the saved context stack frame used by the ThreadX port. The +state of the CPU registers at the time of a context switch is saved on the running +thread's stack The top of the suspended thread's stack is pointed to by +tx_thread_stack_ptr in the associated thread control block TX_THREAD. + + Offset Interrupted Stack Frame + + 0x00 1 + 0x04 ACC0 + 0x08 ACC1 + 0x0C R6 + 0x10 R7 + 0x14 R8 + 0x18 R9 + 0x1C R10 + 0x20 R11 + 0x24 R12 + 0x28 R13 + 0x2C FPSW + 0x30 R14 + 0x34 R15 + 0x38 R3 + 0x3C R4 + 0x40 R5 + 0x44 R1 + 0x48 R2 + 0x4C PC - return address + 0x50 PSW + +Note: By default GNURX does not save the state of the accumulator registers ACC0 and ACC1 +when entering an ISR. This means that if the ISR uses any of the DSP instructions the +content of those registers could be corrupted. Saving and restoring of the acummulators +can be enabled by adding the -msave-acc-in-interrupts command line option. + + +5. Improving Performance + +The distribution version of ThreadX is built without any compiler optimizations. This +makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. +Of course, this costs some performance. To make ThreadX run faster, you can change the +ThreadX Library project to disable debug information and enable the desired optimizations. + +In addition, you can eliminate the ThreadX basic API error checking by compiling your +application code with the symbol TX_DISABLE_ERROR_CHECKING defined before tx_api.h +is included. + + +6. Timer Processing + +Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done +from within the callback of a periodic timer with a period of 100Hz. In the sample projects +a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source. + + +7. Interrupt Handling + +Interrupt handling is unaffected by the ThreadX port as such user interrupts can be +written according to the toolchain's documentation. It is recommended not to use interrupt +priority 15 as this is the priority of the context switch interrupt. However using interrupt +priority 15 won't cause any negative side effectd but doing so may may slightly reduce +performance. Please refer to the toolchain documentation for additional details on how to +define interupt service routines. + + +8. Execution Profiling + +The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists +of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation +of the EPK for generic usage details. + +To add the EPK to your RXv3 release make the following modifications: + +* Enable the following define for both the Threadx library and the application +TX_EXECUTION_PROFILE_ENABLE + +* Setup CMT1 as a free running 16 bit timer. + +* In tx_execution_profile.h, change following around line 52: + +#ifdef TX_EXECUTION_64BIT_TIME +typedef unsigned long long EXECUTION_TIME; +#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF +#else +typedef unsigned long EXECUTION_TIME; +#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF +#endif + +/* Define basic constants for the execution profile kit. */ + +#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A) + +Rebuild the Threadx library and the application. +Refer to the EPK documentation how to interpret the results. + + +9. Revision History + +For generic code revision information, please refer to the readme_threadx_generic.txt +file, which is included in your distribution. The following details the revision +information associated with this specific port of ThreadX: + +06-02-2021 Initial ThreadX release for the RXv3 using GNURX tools, version 6.1.7 + + +Copyright(c) 1996-2021 Microsoft Corporation + + +https://azure.com/rtos + diff --git a/ports/cortex_m33/ac5/src/tx_thread_context_save.s b/ports/rxv3/gnu/src/tx_initialize_low_level.S similarity index 74% rename from ports/cortex_m33/ac5/src/tx_thread_context_save.s rename to ports/rxv3/gnu/src/tx_initialize_low_level.S index b90e611b..c661dcd6 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_context_save.s +++ b/ports/rxv3/gnu/src/tx_initialize_low_level.S @@ -15,34 +15,32 @@ ;/** */ ;/** ThreadX Component */ ;/** */ -;/** Thread */ +;/** Initialize */ ;/** */ ;/**************************************************************************/ ;/**************************************************************************/ ; + + .text + ; - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY - IMPORT _tx_execution_isr_enter - ENDIF -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ -;/* _tx_thread_context_save Cortex-M33/AC5 */ -;/* 6.1 */ +;/* _tx_initialize_low_level RXv3/GNURX */ +;/* 6.1.7 */ ;/* AUTHOR */ ;/* */ -;/* Scott Larson, Microsoft Corporation */ +;/* William E. Lamie, Microsoft Corporation */ ;/* */ ;/* DESCRIPTION */ ;/* */ -;/* This function saves the context of an executing thread in the */ -;/* beginning of interrupt processing. The function also ensures that */ -;/* the system stack is used upon return to the calling ISR. */ +;/* 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 */ ;/* */ @@ -58,34 +56,38 @@ ;/* */ ;/* CALLED BY */ ;/* */ -;/* ISRs */ +;/* _tx_initialize_kernel_enter ThreadX entry function */ ;/* */ ;/* RELEASE HISTORY */ ;/* */ ;/* DATE NAME DESCRIPTION */ ;/* */ -;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ ;/* */ ;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ - EXPORT _tx_thread_context_save -_tx_thread_context_save FUNCTION - IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + .global __tx_initialize_low_level +__tx_initialize_low_level: + ; -; /* Call the ISR enter function to indicate an ISR is executing. */ +; /* Save the first available memory address. */ +; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start; ; - PUSH {r0, lr} ; Save return address - BL _tx_execution_isr_enter ; Call the ISR enter function - POP {r0, lr} ; Recover return address - ENDIF -; -; /* Return to interrupt processing. */ -; - BX lr -;} - ENDFUNC - ALIGN - LTORG - END - + MOV.L #_end, R1 ; Pickup unused memory address + MOV.L #__tx_initialize_unused_memory, R2 + MOV.L R1,[R2] ; Save first free memory address + +; /* Set priority of SWINT to 1. */ + MOV.L #0x87303, r1 + MOV.L #1, r2 + MOV.B r2, [r1] + +; /* Enable SWINT. */ + MOV.L #0x87203,r1 + MOV.B [r1], r2 + OR #(1 << 3), r2 + MOV.B r2, [r1] + + RTS + + + .end diff --git a/ports/rxv3/gnu/src/tx_thread_context_restore.S b/ports/rxv3/gnu/src/tx_thread_context_restore.S new file mode 100644 index 00000000..00648249 --- /dev/null +++ b/ports/rxv3/gnu/src/tx_thread_context_restore.S @@ -0,0 +1,207 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; +; + .global __tx_thread_system_state + .global __tx_thread_current_ptr + .global __tx_thread_system_stack_ptr + .global __tx_thread_execute_ptr + .global __tx_timer_time_slice + .global __tx_thread_schedule + .global __tx_thread_preempt_disable + + .text + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_restore RXv3/GNURX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the interrupt context if it is processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_restore(VOID) +;{ + .global __tx_thread_context_restore +__tx_thread_context_restore: +; +; /* Lockout interrupts. */ + + CLRPSW I ; disable interrupts + +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { + + MOV.L #__tx_thread_system_state, R1 + MOV.L [R1], R2 + SUB #1, R2 + MOV.L R2,[R1] + BEQ __tx_thread_not_nested_restore + +; +; /* Interrupts are nested. */ +; +; /* Recover the saved registers from the interrupt stack +; and return to the point of interrupt. */ +; +__tx_thread_nested_restore: + POPC FPSW ; restore FPU status + POPM R14-R15 ; restore R14-R15 + POPM R3-R5 ; restore R3-R5 + POPM R1-R2 ; restore R1-R2 + RTE ; return to point of interrupt, restore PSW including IPL +; } + +__tx_thread_not_nested_restore: +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { + + MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address + MOV.L [R1], R2 + CMP #0, R2 + BEQ __tx_thread_idle_system_restore + + MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag + MOV.L [R3], R3 + CMP #0, R3 + BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless + + MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr) + CMP [R3], R2 + BNE __tx_thread_preempt_restore ; jump to pre-empt restoring +; +__tx_thread_no_preempt_restore: + SETPSW U ; user stack + POPC FPSW ; restore FPU status + POPM R14-R15 ; restore R14-R15 + POPM R3-R5 ; restore R3-R5 + POPM R1-R2 ; restore R1-R2 + RTE ; return to point of interrupt, restore PSW including IPL + +; } +; else +; { + +__tx_thread_preempt_restore: + +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { + + MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address + MOV.L [R3],R4 ; Pickup actual time-slice + CMP #0, R4 + BEQ __tx_thread_dont_save_ts ; no time slice to save +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + MOV.L R4,24[R2] ; Save thread's time slice + MOV.L #0,R4 ; Clear value + MOV.L R4,[R3] ; Disable global time slice flag +; } +__tx_thread_dont_save_ts: +; +; /* Now store the remaining registers! */ + + SETPSW U ; user stack + PUSHM R6-R13 + + MVFACGU #0, A1, R4 ; Save accumulators. + MVFACHI #0, A1, R5 + MVFACLO #0, A1, R6 + PUSHM R4-R6 + MVFACGU #0, A0, R4 + MVFACHI #0, A0, R5 + MVFACLO #0, A0, R6 + PUSHM R4-R6 + + MOV.L #1, R3 ; indicate interrupt stack frame + PUSH.L R3 + +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; R1 -> _tx_thread_current_ptr +; R2 -> *_tx_thread_current_ptr + + MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block + MOV.L #0,R2 ; Build NULL value + MOV.L R2,[R1] ; Set current thread to NULL + +; /* Return to the scheduler. */ +; _tx_thread_schedule(); + +__tx_thread_idle_system_restore: + MVTC #0, PSW ; reset interrupt priority level to 0 + BRA __tx_thread_schedule ; jump to scheduler +; } +; +;} +; + .end diff --git a/ports/rxv3/gnu/src/tx_thread_context_save.S b/ports/rxv3/gnu/src/tx_thread_context_save.S new file mode 100644 index 00000000..8d8c67f7 --- /dev/null +++ b/ports/rxv3/gnu/src/tx_thread_context_save.S @@ -0,0 +1,171 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; + .global __tx_thread_system_state + .global __tx_thread_current_ptr + .global __tx_thread_system_stack_ptr + + .text +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_save RXv3/GNURX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_save(VOID) +;{ + .global __tx_thread_context_save +__tx_thread_context_save: +; +; /* Upon entry to this routine, it is assumed that interrupts are locked +; out and the (interrupt) stack frame looks like the following: +; +; (lower address) SP -> [return address of this call] +; SP+4 -> Saved R1 +; SP+8 -> Saved R2 +; SP+12-> Interrupted PC +; SP+16-> Interrupted PSW +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + + MOV.L #__tx_thread_system_state, R1 ; pick up address of system state + MOV.L [R1], R2 ; pick up system state + CMP #0, R2 ; 0 -> no nesting + BEQ __tx_thread_not_nested_save +; +; /* Nested interrupt condition. */ +; + ADD #1, r2 ; _tx_thread_system_state++ + MOV.L r2, [r1] + +; +; /* Save the rest of the scratch registers on the interrupt stack and return to the +; calling ISR. */ + POP R1 ; recuperate return address from stack + PUSHM R3-R5 + PUSHM R14-R15 + PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom) + JMP R1 ; return address was preserved in R1 + +; +__tx_thread_not_nested_save: +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD #1, R2 ; _tx_thread_system_state++ + MOV.L R2, [R1] + + MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer + MOV.L [R2], R2 + CMP #0,R2 ; Is it NULL? + BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore +; +; /* Move stack frame over to the current threads stack. */ +; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */ +; + MVFC USP, R1 ; pick up user stack pointer + MOV.L 16[R0], R2 + MOV.L R2, [-R1] ; save PSW on thread stack + MOV.L 12[R0], R2 + MOV.L R2, [-R1] ; save PC on thread stack + MOV.L 8[R0], R2 + MOV.L R2, [-R1] ; save R2 on thread stack + MOV.L 4[R0], R2 + MOV.L R2, [-R1] ; save R1 on thread stack + MOV.L R5, [-R1] ; save R5 on thread stack + MOV.L R4, [-R1] ; save R4 on thread stack + MOV.L R3, [-R1] ; save R3 on thread stack + MOV.L R15, [-R1] ; save R15 on thread stack + MOV.L R14, [-R1] ; save R14 on thread stack + MVFC FPSW, R3 + MOV.L R3, [-R1] ; save FPSW on thread stack + + POP R2 ; pick up return address from interrupt stack + ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom + MVTC R1, USP ; set user/thread stack pointer + JMP R2 ; return to ISR + +; } +; else +; { +; +__tx_thread_idle_system_save: +; +; /* Interrupt occurred in the scheduling loop. */ +; + POP R1 ; pick up return address + ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers + JMP R1 ; return to caller +; +; } +;} + .end + diff --git a/ports/cortex_m33/ac5/src/tx_thread_interrupt_control.s b/ports/rxv3/gnu/src/tx_thread_interrupt_control.S similarity index 82% rename from ports/cortex_m33/ac5/src/tx_thread_interrupt_control.s rename to ports/rxv3/gnu/src/tx_thread_interrupt_control.S index 93fa6d05..b66d34b0 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_interrupt_control.s +++ b/ports/rxv3/gnu/src/tx_thread_interrupt_control.S @@ -20,18 +20,25 @@ ;/**************************************************************************/ ;/**************************************************************************/ ; +;#define TX_SOURCE_CODE ; - AREA ||.text||, CODE, READONLY - PRESERVE8 +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + .text ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ -;/* _tx_thread_interrupt_control Cortex-M33/AC5 */ -;/* 6.1 */ +;/* _tx_thread_interrupt_control RXv3/GNURX */ +;/* 6.1.7 */ ;/* AUTHOR */ ;/* */ -;/* Scott Larson, Microsoft Corporation */ +;/* William E. Lamie, Microsoft Corporation */ ;/* */ ;/* DESCRIPTION */ ;/* */ @@ -58,21 +65,32 @@ ;/* */ ;/* DATE NAME DESCRIPTION */ ;/* */ -;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ ;/* */ ;/**************************************************************************/ ;UINT _tx_thread_interrupt_control(UINT new_posture) ;{ - EXPORT _tx_thread_interrupt_control -_tx_thread_interrupt_control FUNCTION + + .global __tx_thread_interrupt_control +__tx_thread_interrupt_control: ; ; /* Pickup current interrupt lockout posture. */ ; - MRS r1, PRIMASK - MSR PRIMASK, r0 - MOV r0, r1 - BX lr + + MVFC PSW, R2 ; Save PSW to R2 + MOV.L R2, R3 ; Make a copy of PSW in r3 + ; +; /* Apply the new interrupt posture. */ +; + + BTST #16, R1 ; test I bit of PSW of "new posture" + BMNE #16, R2 ; conditionally set I bit of intermediate posture + + MVTC R2, PSW ; save intermediate posture to PSW + + MOV.L R3,R1 ; Get original SR + RTS ; Return to caller ;} - ENDFUNC - END + .end + diff --git a/ports/rxv3/gnu/src/tx_thread_schedule.S b/ports/rxv3/gnu/src/tx_thread_schedule.S new file mode 100644 index 00000000..a0f62ff7 --- /dev/null +++ b/ports/rxv3/gnu/src/tx_thread_schedule.S @@ -0,0 +1,180 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; +; + .global __tx_thread_execute_ptr + .global __tx_thread_current_ptr + .global __tx_timer_time_slice +; + .text + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_schedule RXv3/GNURX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* _tx_thread_context_restore Restore thread's context */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_schedule(VOID) +;{ + .global __tx_thread_schedule +__tx_thread_schedule: +; +; /* Enable interrupts. */ +; + SETPSW I +; +; /* Wait for a thread to execute. */ +; do +; { + MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr +__tx_thread_schedule_loop: + MOV.L [R1],R2 ; Pickup next thread to execute + CMP #0,R2 ; Is it NULL? + BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking +; +; } +; while(_tx_thread_execute_ptr == TX_NULL); +; +; /* Yes! We have a thread to execute. Lockout interrupts and +; transfer control to it. */ +; + CLRPSW I ; disable interrupts +; +; /* Setup the current thread pointer. */ +; _tx_thread_current_ptr = _tx_thread_execute_ptr; +; + MOV.L #__tx_thread_current_ptr, R3 + MOV.L R2,[R3] ; Setup current thread pointer +; +; /* Increment the run count for this thread. */ +; _tx_thread_current_ptr -> tx_thread_run_count++; +; + MOV.L 4[R2],R3 ; Pickup run count + ADD #1,R3 ; Increment run counter + MOV.L R3,4[R2] ; Store it back in control block +; +; /* Setup time-slice, if present. */ +; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; +; + MOV.L 24[R2],R3 ; Pickup thread time-slice + MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice + MOV.L R3, [R4] ; Setup time-slice +; +; /* Switch to the thread's stack. */ +; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; + SETPSW U ; user stack mode + MOV.L 8[R2],R0 ; Pickup stack pointer +; +; /* Determine if an interrupt frame or a synchronous task suspension frame +; is present. */ +; + POP R1 ; Pickup stack type + CMP #1, R1 ; Is it an interrupt stack? + BNE __tx_thread_synch_return ; No, a synchronous return frame is present. + + POPM R1-R3 ; Restore accumulators. + MVTACLO R3, A0 + MVTACHI R2, A0 + MVTACGU R1, A0 + POPM R1-R3 + MVTACLO R3, A1 + MVTACHI R2, A1 + MVTACGU R1, A1 + + POPM R6-R13 ; Recover interrupt stack frame + POPC FPSW + POPM R14-R15 + POPM R3-R5 + POPM R1-R2 + RTE ; return to point of interrupt, this restores PC and PSW + +__tx_thread_synch_return: + POPC PSW + POPM R6-R13 ; Recover solicited stack frame + RTS +; +;} + + +.global __tx_thread_context_save +.global __tx_thread_context_restore + + +; Software triggered interrupt used to perform context switches. +; The priority of this interrupt is set to the lowest priority within +; tx_initialize_low_level() and triggered by ThreadX when calling +; _tx_thread_system_return(). +.global $tableentry$27$.rvectors +$tableentry$27$.rvectors: + + PUSHM R1-R2 + + BSR __tx_thread_context_save + + BRA __tx_thread_context_restore + + .end diff --git a/ports/cortex_m33/ac5/src/tx_thread_stack_build.s b/ports/rxv3/gnu/src/tx_thread_stack_build.S similarity index 54% rename from ports/cortex_m33/ac5/src/tx_thread_stack_build.s rename to ports/rxv3/gnu/src/tx_thread_stack_build.S index 15eee502..3da3affe 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_stack_build.s +++ b/ports/rxv3/gnu/src/tx_thread_stack_build.S @@ -21,17 +21,25 @@ ;/**************************************************************************/ ; ; - AREA ||.text||, CODE, READONLY - PRESERVE8 +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + .text ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ -;/* _tx_thread_stack_build Cortex-M33/AC5 */ -;/* 6.1 */ +;/* _tx_thread_stack_build RXv3/GNURX */ +;/* 6.1.7 */ ;/* AUTHOR */ ;/* */ -;/* Scott Larson, Microsoft Corporation */ +;/* William E. Lamie, Microsoft Corporation */ ;/* */ ;/* DESCRIPTION */ ;/* */ @@ -60,80 +68,88 @@ ;/* */ ;/* DATE NAME DESCRIPTION */ ;/* */ -;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) ;{ - EXPORT _tx_thread_stack_build -_tx_thread_stack_build FUNCTION + .global __tx_thread_stack_build +__tx_thread_stack_build: ; -; /* Build a fake interrupt frame. The form of the fake interrupt stack -; on the Cortex-M33 should look like the following after it is built: ; -; Stack Top: -; LR Interrupted LR (LR at time of PENDSV) -; r4 Initial value for r4 -; r5 Initial value for r5 -; r6 Initial value for r6 -; r7 Initial value for r7 -; r8 Initial value for r8 -; r9 Initial value for r9 -; r10 Initial value for r10 -; r11 Initial value for r11 -; 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 +; /* Build an interrupt frame. The form of the fake interrupt stack +; on the Renesas RX should look like the following after it is built: +; +; Stack Top: 1 Interrupt stack frame type +; ACC0 +; ACC1 +; R6 +; R7 +; R8 +; R9 +; R10 +; R11 +; R12 +; R13 +; FPSW +; R14 +; R15 +; R3 +; R4 +; R5 +; R1 +; R2 +; PC +; PSW + ; ; Stack Bottom: (higher memory address) */ ; - LDR r2, [r0, #16] ; Pickup end of stack area - BIC r2, r2, #0x7 ; Align frame for 8-byte alignment - SUB r2, r2, #68 ; Subtract frame size - IF :DEF: 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 + MOV.L 16[R1],R3 ; Pickup end of stack area + BCLR #0, R3 ; mask for 4-byte alignment + BCLR #1, R3 ; -; /* Actually build the stack frame. */ +; /* Build the stack frame. */ ; - MOV r3, #0 ; Build initial register value - STR r3, [r2, #4] ; Store initial r4 - STR r3, [r2, #8] ; Store initial r5 - STR r3, [r2, #12] ; Store initial r6 - STR r3, [r2, #16] ; Store initial r7 - STR r3, [r2, #20] ; Store initial r8 - STR r3, [r2, #24] ; Store initial r9 - STR r3, [r2, #28] ; Store initial r10 - STR r3, [r2, #32] ; Store initial r11 -; -; /* 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 - MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value - STR r3, [r2, #56] ; Store initial lr - STR r1, [r2, #60] ; Store initial pc - MOV 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 -;} - ENDFUNC - END + MOV.L #30000h, R4 + MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set) + MOV.L R2, [-R3] ; initial PC + MOV.L #0, R4 + MOV.L R4,[-R3] ; initial R2 ... + MOV.L R4,[-R3] ; initial R1 ... + MOV.L R4,[-R3] ; initial R5 ... + MOV.L R4,[-R3] ; initial R4 ... + MOV.L R4,[-R3] ; initial R3 ... + MOV.L R4,[-R3] ; initial R15 ... + MOV.L R4,[-R3] ; initial R14 ... + MVFC FPSW, r4 + MOV.L R4, [-R3] ; initial FPSW + MOV.L #0, R4 + MOV.L R4,[-R3] ; initial R13 ... + MOV.L R4,[-R3] ; initial R12 ... + MOV.L R4,[-R3] ; initial R11 ... + MOV.L R4,[-R3] ; initial R10 ... + MOV.L R4,[-R3] ; initial R9 ... + MOV.L R4,[-R3] ; initial R8 ... + MOV.L R4,[-R3] ; initial R7 ... + MOV.L R4,[-R3] ; initial R6 ... + + MOV.L R4,[-R3] ; Accumulator 1 + MOV.L R4,[-R3] + MOV.L R4,[-R3] + + MOV.L R4,[-R3] ; Accumulator 0 + MOV.L R4,[-R3] + MOV.L R4,[-R3] + + MOV.L #1, R4 + MOV.L R4,[-R3] ; indicate interrupt stack frame +; /* Setup stack pointer. */ +; thread_ptr -> tx_thread_stack_ptr = R1; + MOV.L R3, 8[R1] + ; store initial SP in thread control block + RTS + +;} + .end diff --git a/ports/cortex_m33/ac5/src/tx_thread_system_return.s b/ports/rxv3/gnu/src/tx_thread_system_return.S similarity index 67% rename from ports/cortex_m33/ac5/src/tx_thread_system_return.s rename to ports/rxv3/gnu/src/tx_thread_system_return.S index b29de463..979d7e25 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_system_return.s +++ b/ports/rxv3/gnu/src/tx_thread_system_return.S @@ -20,25 +20,37 @@ ;/**************************************************************************/ ;/**************************************************************************/ ; +;#define TX_SOURCE_CODE ; - AREA ||.text||, CODE, READONLY - PRESERVE8 +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; + .global __tx_thread_current_ptr + .global __tx_timer_time_slice + .global __tx_thread_schedule + + .text ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ -;/* _tx_thread_system_return Cortex-M33/AC5 */ -;/* 6.1 */ +;/* _tx_thread_system_return RXv3/GNURX */ +;/* 6.1.7 */ ;/* AUTHOR */ ;/* */ -;/* Scott Larson, Microsoft Corporation */ +;/* William E. Lamie, 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. */ +;/* control from a thread back to the system. Only a minimal context */ +;/* is saved since the compiler assumes temp registers are going to get */ +;/* slicked by a function call anyway. */ ;/* */ ;/* INPUT */ ;/* */ @@ -60,28 +72,56 @@ ;/* */ ;/* DATE NAME DESCRIPTION */ ;/* */ -;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_system_return(VOID) ;{ - EXPORT _tx_thread_system_return -_tx_thread_system_return FUNCTION + .GLB __tx_thread_system_return +__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. */ +; /* Save call save registers on the stack. */ ; - MOV r0, #0x10000000 ; Load PENDSVSET bit - MOV r1, #0xE000E000 ; Load NVIC base - STR r0, [r1, #0xD04] ; 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 + PUSHM R6-R13 + PUSHC PSW + MOV.L #0, R1 + PUSH.L R1 ; solicited stack frame +; +; /* Lockout interrupts. */ +; + CLRPSW I ; Lockout interrupts +; +; /* Save current stack in current Thread controle block. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = SP; + MOV.L #__tx_thread_current_ptr, R2 + MOV.L [R2], R3 + MOV.L R0, 8[R3] + + MOV.L #__tx_timer_time_slice, R4 + MOV.L [R4], R5 + +; /* Determine if the time-slice is active. */ +; if (_tx_timer_time_slice) +; { +; + CMP #0,R5 ; Is a time-slice present? + BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice +; +; /* Save time-slice for the thread and clear the current time-slice. */ + ; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; + MOV.L R5,24[R3] +; _tx_timer_time_slice = 0; +; + MOV.L R1, [R4] ; Disable the time-slice +; +; } +__tx_thread_dont_save_ts: +; +; /* Clear the current thread pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV.L R1, [R2] + BRA __tx_thread_schedule ;} - ENDFUNC - END + .end + diff --git a/ports/rxv3/gnu/src/tx_timer_interrupt.S b/ports/rxv3/gnu/src/tx_timer_interrupt.S new file mode 100644 index 00000000..1bbdf38c --- /dev/null +++ b/ports/rxv3/gnu/src/tx_timer_interrupt.S @@ -0,0 +1,251 @@ +;/**************************************************************************/ +;/* */ +;/* 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 */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_timer.h" +;#include "tx_thread.h" +; +; +;Define Assembly language external references... +; + .global __tx_timer_time_slice + .global __tx_timer_system_clock + .global __tx_timer_current_ptr + .global __tx_timer_list_start + .global __tx_timer_list_end + .global __tx_timer_expired_time_slice + .global __tx_timer_expired + .global __tx_timer_expiration_process + .global __tx_thread_context_save + .global __tx_thread_time_slice + .global __tx_thread_context_restore +; + .SECTION P,CODE +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_timer_interrupt RXv3/GNURX */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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_thread_context_save Save interrupted context */ +;/* _tx_timer_expiration_process Timer expiration processing */ +;/* _tx_thread_time_slice Time slice interrupted thread */ +;/* _tx_thread_context_restore Restore interrupted context */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* interrupt vector */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_timer_interrupt(VOID) +;{ + .global __tx_timer_interrupt +__tx_timer_interrupt: +; +; /* Upon entry to this routine, it is assumed that all interrupts are locked +; out and the stack looks like the following: +; SP+4 -> Interrupted PC +; SP+8-> Interrupted SR +; */ +; +; /* Increment the system clock. */ +; _tx_timer_system_clock++; +; + PUSHM R14-R15 + PUSHM R1-R5 + + MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock + MOV.L [R1], R2 ; Pickup system clock + ADD #1, R2 ; Increment system clock + MOV.L R2,[R1] ; Store new system clock +; +; /* Test for time-slice expiration. */ +; if (_tx_timer_time_slice) +; { +; + MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice + MOV.L [R1], R2 ; Pickup the current time slice + CMP #0, R2 ; Is a time slice active? + BEQ __tx_timer_no_time_slice ; No, skip timer slice processing +; +; /* Decrement the time_slice. */ +; _tx_timer_time_slice--; +; + SUB #1, R2 ; Decrement the time-slice + MOV.L R2, [R1] ; Store time-slice +; +; /* Check for expiration. */ +; if (__tx_timer_time_slice == 0) +; + CMP #0, R2 ; Has it expired? + BNE __tx_timer_no_time_slice ; No, time-slice has not expired +; +; /* Set the time-slice expired flag. */ +; _tx_timer_expired_time_slice = TX_TRUE; +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice + MOV.L #1, R2 ; Build expired value + MOV.L R2, [R1] ; Set expired time slice variable +; } +; +__tx_timer_no_time_slice: +; +; /* Test for timer expiration. */ +; if (*_tx_timer_current_ptr) +; { +; + MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr + MOV.L [R1], R2 ; Pickup current pointer + MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++ + CMP #0, R1 ; Is timer pointer NULL? + BEQ __tx_timer_no_timer ; Yes, no timer has expired + +; +; /* Set expiration flag. */ +; _tx_timer_expired = TX_TRUE; +; + MOV.L #__tx_timer_expired,R2 ; Build address of expired flag + MOV.L #1, R1 ; Build expired value + MOV.L R1, [R2] + BRA __tx_timer_done ; Finished with timer processing +; +; } +; else +; { +__tx_timer_no_timer: +; +; /* No timer expired, increment the timer pointer. */ +; _tx_timer_current_ptr++; +; +; /* R2 already contains __tx_timer_current_ptr++ */ +; +; /* Check for wrap-around. */ +; if (_tx_timer_current_ptr == _tx_timer_list_end) +; + MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr + MOV.L [R1], R1 ; Pickup actual timer list end + CMP R1, R2 ; Are we at list end? + BNE __tx_timer_skip_wrap ; No, don't move pointer to the + ; top of the list +; +; /* Wrap to beginning of list. */ +; _tx_timer_current_ptr = _tx_timer_list_start; +; + MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr + MOV.L [R2], R2 ; Pickup the start of the list +; } +; +__tx_timer_skip_wrap: + MOV.L #__tx_timer_current_ptr,R1 + MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr + +__tx_timer_done: +; +; /* See if anything has expired. */ +; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) +; { +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr + MOV.L [R1], R1 ; Pickup expired time slice + MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address + MOV.L [R2], R2 ; Pickup actual flag + OR R1, R2 ; Or flags together + BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired + +__tx_something_expired: +; /* Did a timer expire? */ +; if (_tx_timer_expired) +; { + MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address + MOV.L [R1], R1 ; Pickup expired flag + CMP #0,R1 ; Is the expired timer flag set? + BEQ __tx_timer_dont_activate ; No, skip timer activation +; +; /* Process timer expiration. */ +; _tx_timer_expiration_process(); +; + BSR __tx_timer_expiration_process ; Call the timer expiration handling routine +; +; } +__tx_timer_dont_activate: +; +; /* Did time slice expire? */ +; if (_tx_timer_expired_time_slice) +; { +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr + MOV.L [R1], R1 ; Pickup actual flag + CMP #0,R1 ; Has time-slice expired? + BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration +; +; /* Time slice interrupted thread. */ +; _tx_thread_time_slice(); + + BSR __tx_thread_time_slice ; Call time-slice processing +; } +; +__tx_timer_not_ts_expiration: + +__tx_timer_nothing_expired: + + POPM R1-R5 + POPM R14-R15 +; + RTS ; return to point of interrupt +; +;} + + .end + diff --git a/ports/cortex_m23/ac5/inc/tx_port.h b/ports/rxv3/iar/inc/tx_port.h similarity index 53% rename from ports/cortex_m23/ac5/inc/tx_port.h rename to ports/rxv3/iar/inc/tx_port.h index 7805b1eb..66b2ec27 100644 --- a/ports/cortex_m23/ac5/inc/tx_port.h +++ b/ports/rxv3/iar/inc/tx_port.h @@ -12,7 +12,7 @@ /**************************************************************************/ /**************************************************************************/ -/** */ +/** */ /** ThreadX Component */ /** */ /** Port Specific */ @@ -21,59 +21,54 @@ /**************************************************************************/ -/**************************************************************************/ +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port.h RXv3/IAR */ +/* 6.1.7 */ /* */ -/* PORT SPECIFIC C INFORMATION RELEASE */ -/* */ -/* tx_port.h Cortex-M23/AC5 */ -/* 6.1.6 */ -/* */ -/* AUTHOR */ -/* */ -/* Scott Larson, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This file contains data type definitions that make the ThreadX */ -/* real-time kernel function identically on a variety of different */ -/* processor architectures. For example, the size or number of bits */ -/* in an "int" data type vary between microprocessor architectures and */ -/* even C compilers for the same microprocessor. ThreadX does not */ -/* directly use native C data types. Instead, ThreadX creates its */ -/* own special types that can be mapped to actual data types by this */ -/* file to guarantee consistency in the interface and functionality. */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ -/* */ -/**************************************************************************/ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make the ThreadX */ +/* real-time kernel function identically on a variety of different */ +/* processor architectures. For example, the size or number of bits */ +/* in an "int" data type vary between microprocessor architectures and */ +/* even C compilers for the same microprocessor. ThreadX does not */ +/* directly use native C data types. Instead, ThreadX creates its */ +/* own special types that can be mapped to actual data types by this */ +/* file to guarantee consistency in the interface and functionality. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* */ +/**************************************************************************/ #ifndef TX_PORT_H #define TX_PORT_H +#include +#include + /* Determine if the optional ThreadX user define file should be used. */ + #ifdef TX_INCLUDE_USER_DEFINE_FILE + /* Yes, include the user defines in tx_user.h. The defines in this file may alternately be defined on the command line. */ #include "tx_user.h" #endif -/* Define compiler library include files. */ - -#include -#include -#include -#include "ARMCM23_TZ.h" /* For intrinsic functions. */ - -/* Define ThreadX basic types for this port. */ +/* Define ThreadX basic types for this port. */ #define VOID void typedef char CHAR; @@ -82,60 +77,9 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; -typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; -/* Function prototypes for this port. */ -struct TX_THREAD_STRUCT; -UINT _txe_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *thread_ptr, ULONG stack_size); -UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); -UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); -UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); - -/* This hardware has stack checking that we take advantage of - do NOT define. */ -#ifdef TX_ENABLE_STACK_CHECKING - #error "Do not define TX_ENABLE_STACK_CHECKING" -#endif - -/* If user does not want to terminate thread on stack overflow, - #define the TX_THREAD_NO_TERMINATE_STACK_ERROR symbol. - The thread will be rescheduled and continue to cause the exception. - It is suggested user code handle this by registering a notification with the - tx_thread_stack_error_notify function. */ -/*#define TX_THREAD_NO_TERMINATE_STACK_ERROR */ - -/* Define the system API mappings based on the error checking - selected by the user. Note: this section is only applicable to - application source code, hence the conditional that turns off this - stuff when the include file is processed by the ThreadX source. */ - -#ifndef TX_SOURCE_CODE - - -/* Determine if error checking is desired. If so, map API functions - to the appropriate error checking front-ends. Otherwise, map API - functions to the core functions that actually perform the work. - Note: error checking is enabled by default. */ - -#ifdef TX_DISABLE_ERROR_CHECKING - -/* Services without error checking. */ - -#define tx_thread_secure_stack_allocate _tx_thread_secure_stack_allocate -#define tx_thread_secure_stack_free _tx_thread_secure_stack_free - -#else - -/* Services with error checking. */ - -#define tx_thread_secure_stack_allocate _txe_thread_secure_stack_allocate -#define tx_thread_secure_stack_free _txe_thread_secure_stack_free - -#endif -#endif - - /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -149,7 +93,7 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); thread creation is less than this value, the thread create call will return an error. */ #ifndef TX_MINIMUM_STACK -#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */ +#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */ #endif @@ -161,34 +105,13 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); #endif #ifndef TX_TIMER_THREAD_PRIORITY -#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif -/* Define various constants for the ThreadX Cortex-M23 port. */ - -#define TX_INT_DISABLE 1 /* Disable interrupts */ -#define TX_INT_ENABLE 0 /* Enable interrupts */ - - -/* 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 - source constants would be: - -#define TX_TRACE_TIME_SOURCE *((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 ++_tx_trace_simulated_time #endif -#else -ULONG _tx_misra_time_stamp_get(VOID); -#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() -#endif - #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -197,18 +120,14 @@ ULONG _tx_misra_time_stamp_get(VOID); /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) +#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ -#ifdef TX_MISRA_ENABLE -#define TX_DISABLE_INLINE -#else #define TX_INLINE_INITIALIZATION -#endif /* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is @@ -217,25 +136,19 @@ ULONG _tx_misra_time_stamp_get(VOID); define is negated, thereby forcing the stack fill which is necessary for the stack checking logic. */ -#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif -#endif /* 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 existing ThreadX kernel awareness modules. */ -#define TX_THREAD_EXTENSION_0 -#define TX_THREAD_EXTENSION_1 -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -#define TX_THREAD_EXTENSION_2 VOID *tx_thread_secure_stack_context; -#else -#define TX_THREAD_EXTENSION_2 -#endif -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_2 +#define TX_THREAD_EXTENSION_3 /* Define the port extensions of the remaining ThreadX objects. */ @@ -253,7 +166,7 @@ ULONG _tx_misra_time_stamp_get(VOID); additional is needed for this port so it is defined as white space. */ #ifndef TX_THREAD_USER_EXTENSION -#define TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION #endif @@ -261,35 +174,8 @@ ULONG _tx_misra_time_stamp_get(VOID); tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) if(thread_ptr -> tx_thread_secure_stack_context){_tx_thread_secure_stack_free(thread_ptr);} -#else -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) -#endif - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -/* Define the size of the secure stack for the timer thread and use the extension to allocate the secure stack. */ -#define TX_TIMER_THREAD_SECURE_STACK_SIZE 256 -#define TX_TIMER_INITIALIZE_EXTENSION(status) _tx_thread_secure_stack_allocate(&_tx_timer_thread, TX_TIMER_THREAD_SECURE_STACK_SIZE); -#endif - - -#ifndef TX_MISRA_ENABLE - -//register unsigned int _ipsr __asm ("MRS %[result], ipsr" : [result] "=r" (_ipsr) : ); -inline static unsigned int _get_ipsr(void); -inline static unsigned int _get_ipsr(void) -{ - unsigned int _ipsr; - __asm("MRS %[result], ipsr" : [result] "=r" (_ipsr) : ); - return _ipsr; -} - -#endif - - +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) @@ -315,51 +201,6 @@ inline static unsigned int _get_ipsr(void) #define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) #define TX_TIMER_DELETE_EXTENSION(timer_ptr) - -/* 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()) -#else -ULONG _tx_misra_ipsr_get(VOID); -#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif - - -/* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h - for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always - zero after initialization for Cortex-M ports. */ - -#ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); -#endif - -#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE) -/* Initialize secure stacks for threads calling secure functions. */ -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 - 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 - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); - -#endif - - /* Define ThreadX interrupt lockout and restore macros for protection on access of critical kernel information. The restore interrupt macro must restore the interrupt posture of the running thread prior to the value @@ -380,42 +221,53 @@ VOID _tx_thread_interrupt_restore(UIN #else -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); +#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save; +#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();}; +#define TX_RESTORE {__set_interrupt_state(interrupt_save);}; #define _tx_thread_system_return _tx_thread_system_return_inline - static void _tx_thread_system_return_inline(void) { -unsigned int was_masked; + TX_INTERRUPT_SAVE_AREA + TX_DISABLE - /* Set PendSV to invoke ThreadX scheduler. */ - *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (_get_ipsr() == 0) - { - was_masked = __disable_irq(); - __enable_irq(); - if (was_masked != 0) - __disable_irq(); - } + *((volatile UCHAR *)(0x872E0u)) = 1u; + + TX_RESTORE } + #endif +#ifndef TX_THREAD_GET_SYSTEM_STATE + +extern volatile ULONG _tx_thread_system_state; +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | ((~__get_PSW_register()) & (1u << 17u))) +#endif + + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + /* 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/AC5 Version 6.1.6 *"; -#else -#ifdef TX_MISRA_ENABLE -extern CHAR _tx_version_id[100]; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv3/IAR Version 6.1.7 *"; #else extern CHAR _tx_version_id[]; #endif -#endif + #endif + diff --git a/ports/rxv3/iar/readme_threadx.txt b/ports/rxv3/iar/readme_threadx.txt new file mode 100644 index 00000000..9d991b8e --- /dev/null +++ b/ports/rxv3/iar/readme_threadx.txt @@ -0,0 +1,155 @@ + Microsoft's Azure RTOS ThreadX for Renesas RXv3 + + Using the IAR Tools + + +1. Building the ThreadX run-time Library + +Please see the Samples repository on GitHub for the Azure RTOS demonstrations +for the RXv3. + + +2. Demonstration System + +Please see the Samples repository on GitHub for the Azure RTOS demonstrations +for the RXv3. + + +3. System Initialization + +The system entry point using the IAR tools is at the label __iar_program_start. + +The vector area is setup in the file tx_initialize_low_level.s. This file is also +responsible for setting up various system data structures, interrupt vectors, and +the periodic timer interrupt. This file is also an ideal place add hardware +initialization code. + +The ThreadX demonstration for the RXv3 utilizes CMT0 as a periodic timer interrupt +source. The CMT0 interrupt is typically setup for 10ms periodic interrupts and the +interrupt priority level is set to level 7. You may change any of the timer +parameters as needed. + +In addition, _tx_initialize_low_level determines the first available address for use +by the application, which is supplied as the sole input parameter to your application +definition function, tx_application_define. The first available memory is determined +by the location of the FREEMEM section so it should be placed AFTER all other RAM +sections in your linker control file. + + +4. Context Switch, Register Usage and Stack Frames + +The RXv3 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17, +to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT +should not be manipulated in any way by the application. The port will setup the +interrupt within _tx_initialize_low_level and the compiler will automatically install +the necessary interrupt vector. As such no additional initialization is necessary by the +application. + +The following defines the saved context stack frame used by the ThreadX port. The +state of the CPU registers at the time of a context switch is saved on the running +thread's stack The top of the suspended thread's stack is pointed to by +tx_thread_stack_ptr in the associated thread control block TX_THREAD. + + Offset Interrupted Stack Frame + + 0x00 1 + 0x04 ACC0 + 0x08 ACC1 + 0x0C R6 + 0x10 R7 + 0x14 R8 + 0x18 R9 + 0x1C R10 + 0x20 R11 + 0x24 R12 + 0x28 R13 + 0x2C FPSW + 0x30 R14 + 0x34 R15 + 0x38 R3 + 0x3C R4 + 0x40 R5 + 0x44 R1 + 0x48 R2 + 0x4C PC - return address + 0x50 PSW + +Note: By default IAR does not save the state of the accumulator registers ACC0 and ACC1 +when entering an ISR. This means that if the ISR uses any of the DSP instructions the +content of those registers could be corrupted. Saving and restoring of the acummulators +can be enabled by adding the --save_acc command line option. + + +5. Improving Performance + +The distribution version of ThreadX is built without any compiler optimizations. This +makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself. +Of course, this costs some performance. To make ThreadX run faster, you can change the +ThreadX Library project to disable debug information and enable the desired optimizations. + +In addition, you can eliminate the ThreadX basic API error checking by compiling your +application code with the symbol TX_DISABLE_ERROR_CHECKING defined before tx_api.h +is included. + + +6. Timer Processing + +Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done +from within the callback of a periodic timer with a period of 100Hz. In the sample projects +a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source. + + +7. Interrupt Handling + +Interrupt handling is unaffected by the ThreadX port as such user interrupts can be +written according to the toolchain's documentation. It is recommended not to use interrupt +priority 15 as this is the priority of the context switch interrupt. However using interrupt +priority 15 won't cause any negative side effectd but doing so may may slightly reduce +performance. Please refer to the toolchain documentation for additional details on how to +define interupt service routines. + + +8. Execution Profiling + +The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists +of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation +of the EPK for generic usage details. + +To add the EPK to your RXv3 release make the following modifications: + +* Enable the following define for both the Threadx library and the application +TX_EXECUTION_PROFILE_ENABLE + +* Setup CMT1 as a free running 16 bit timer. + +* In tx_execution_profile.h, change following around line 52: + +#ifdef TX_EXECUTION_64BIT_TIME +typedef unsigned long long EXECUTION_TIME; +#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF +#else +typedef unsigned long EXECUTION_TIME; +#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF +#endif + +/* Define basic constants for the execution profile kit. */ + +#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A) + +Rebuild the Threadx library and the application. +Refer to the EPK documentation how to interpret the results. + + +9. Revision History + +For generic code revision information, please refer to the readme_threadx_generic.txt +file, which is included in your distribution. The following details the revision +information associated with this specific port of ThreadX: + +06-02-2021 Initial ThreadX release for the RXv3using IAR tools, version 6.1.7 + + +Copyright(c) 1996-2021 Microsoft Corporation + + +https://azure.com/rtos \ No newline at end of file diff --git a/ports/cortex_m23/ac5/src/tx_thread_context_restore.s b/ports/rxv3/iar/src/tx_initialize_low_level.s similarity index 62% rename from ports/cortex_m23/ac5/src/tx_thread_context_restore.s rename to ports/rxv3/iar/src/tx_initialize_low_level.s index 6a3e9a49..5e6f447f 100644 --- a/ports/cortex_m23/ac5/src/tx_thread_context_restore.s +++ b/ports/rxv3/iar/src/tx_initialize_low_level.s @@ -12,64 +12,88 @@ ; ;/**************************************************************************/ ;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ ;/** */ -;/** ThreadX Component */ -;/** */ -;/** Thread */ +;/** Initialize */ ;/** */ ;/**************************************************************************/ ;/**************************************************************************/ ; + + extern __tx_initialize_unused_memory + + section .text:CODE:ROOT + ; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_context_restore Cortex-M23/AC5 */ -;/* 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) -;{ - EXPORT _tx_thread_context_restore -_tx_thread_context_restore FUNCTION +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_initialize_low_level RXv3/IAR */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ + public __tx_initialize_low_level + +__tx_initialize_low_level: + +; /* Save the first available memory address. */ +; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start; ; -; /* Return to interrupt processing. */ -; - BX lr -;} - ENDFUNC - ALIGN - LTORG + MOV.L #__tx_free_memory_start, R1 ; Pickup unused memory address + MOV.L #__tx_initialize_unused_memory,R2 + MOV.L R1,[R2] ; Save first free memory address + +; /* Set priority of SWINT to 1. */ + MOV.L #0x87303, r1 + MOV.L #1, r2 + MOV.B r2, [r1] + +; /* Enable SWINT. */ + MOV.L #0x87203, r1 + MOV.B [r1], r2 + OR #(1 << 3), r2 + MOV.B r2, [r1] + + RTS + + section FREEMEM:DATA + public __tx_free_memory_start +__tx_free_memory_start + DS32 4 + END diff --git a/ports/rxv3/iar/src/tx_thread_context_restore.s b/ports/rxv3/iar/src/tx_thread_context_restore.s new file mode 100644 index 00000000..8afc4d8f --- /dev/null +++ b/ports/rxv3/iar/src/tx_thread_context_restore.s @@ -0,0 +1,205 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; +; + extern __tx_thread_system_state + extern __tx_thread_current_ptr + extern __tx_thread_preempt_disable + extern __tx_thread_execute_ptr + extern __tx_timer_time_slice + extern __tx_thread_schedule + + section .text:CODE:ROOT + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_restore RXv3/IAR */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the interrupt context if it is processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ + public __tx_thread_context_restore + +__tx_thread_context_restore: +; +; /* Lockout interrupts. */ + + CLRPSW I ; disable interrupts + +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { + + MOV.L #__tx_thread_system_state, R1 + MOV.L [R1], R2 + SUB #1, R2 + MOV.L R2,[R1] + BEQ __tx_thread_not_nested_restore + +; +; /* Interrupts are nested. */ +; +; /* Recover the saved registers from the interrupt stack +; and return to the point of interrupt. */ +; +__tx_thread_nested_restore: + POPC FPSW ; restore FPU status + POPM R14-R15 ; restore R14-R15 + POPM R3-R5 ; restore R3-R5 + POPM R1-R2 ; restore R1-R2 + RTE ; return to point of interrupt, restore PSW including IPL +; } + +__tx_thread_not_nested_restore: +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { + + MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address + MOV.L [R1], R2 + CMP #0, R2 + BEQ __tx_thread_idle_system_restore + + MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag + MOV.L [R3], R3 + CMP #0, R3 + BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless + + MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr) + CMP [R3], R2 + BNE __tx_thread_preempt_restore ; jump to pre-empt restoring +; +__tx_thread_no_preempt_restore: + SETPSW U ; user stack + POPC FPSW ; restore FPU status + POPM R14-R15 ; restore R14-R15 + POPM R3-R5 ; restore R3-R5 + POPM R1-R2 ; restore R1-R2 + RTE ; return to point of interrupt, restore PSW including IPL + +; } +; else +; { + +__tx_thread_preempt_restore: + +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { + + MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address + MOV.L [R3],R4 ; Pickup actual time-slice + CMP #0, R4 + BEQ __tx_thread_dont_save_ts ; no time slice to save +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + MOV.L R4,24[R2] ; Save thread's time slice + MOV.L #0,R4 ; Clear value + MOV.L R4,[R3] ; Disable global time slice flag +; } +__tx_thread_dont_save_ts: +; +; /* Now store the remaining registers! */ + + SETPSW U ; user stack + PUSHM R6-R13 + + MVFACGU #0, A1, R4 ; Save accumulators. + MVFACHI #0, A1, R5 + MVFACLO #0, A1, R6 + PUSHM R4-R6 + MVFACGU #0, A0, R4 + MVFACHI #0, A0, R5 + MVFACLO #0, A0, R6 + PUSHM R4-R6 + + MOV.L #1, R3 ; indicate interrupt stack frame + PUSH.L R3 + +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; R1 -> _tx_thread_current_ptr +; R2 -> *_tx_thread_current_ptr + + MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block + MOV.L #0,R2 ; Build NULL value + MOV.L R2,[R1] ; Set current thread to NULL + +; /* Return to the scheduler. */ +; _tx_thread_schedule(); + +__tx_thread_idle_system_restore: + MVTC #0, PSW ; reset interrupt priority level to 0 + BRA __tx_thread_schedule ; jump to scheduler +; } +; +;} +; + END diff --git a/ports/rxv3/iar/src/tx_thread_context_save.s b/ports/rxv3/iar/src/tx_thread_context_save.s new file mode 100644 index 00000000..df1c1bdf --- /dev/null +++ b/ports/rxv3/iar/src/tx_thread_context_save.s @@ -0,0 +1,170 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; + extern __tx_thread_system_state + extern __tx_thread_current_ptr + + section .text:CODE:ROOT +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_save RXv3/IAR */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_save(VOID) +;{ + public __tx_thread_context_save + +__tx_thread_context_save: +; +; /* Upon entry to this routine, it is assumed that interrupts are locked +; out and the (interrupt) stack frame looks like the following: +; +; (lower address) SP -> [return address of this call] +; SP+4 -> Saved R1 +; SP+8 -> Saved R2 +; SP+12-> Interrupted PC +; SP+16-> Interrupted PSW +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + + MOV.L #__tx_thread_system_state, R1 ; pick up address of system state + MOV.L [R1], R2 ; pick up system state + CMP #0, R2 ; 0 -> no nesting + BEQ __tx_thread_not_nested_save +; +; /* Nested interrupt condition. */ +; + ADD #1, r2 ; _tx_thread_system_state++ + MOV.L r2, [r1] + +; +; /* Save the rest of the scratch registers on the interrupt stack and return to the +; calling ISR. */ + POP R1 ; recuperate return address from stack + PUSHM R3-R5 + PUSHM R14-R15 + PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom) + JMP R1 ; return address was preserved in R1 + +; +__tx_thread_not_nested_save: +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD #1, R2 ; _tx_thread_system_state++ + MOV.L R2, [R1] + + MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer + MOV.L [R2], R2 + CMP #0,R2 ; Is it NULL? + BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore +; +; /* Move stack frame over to the current threads stack. */ +; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */ +; + MVFC USP, R1 ; pick up user stack pointer + MOV.L 16[R0], R2 + MOV.L R2, [-R1] ; save PSW on thread stack + MOV.L 12[R0], R2 + MOV.L R2, [-R1] ; save PC on thread stack + MOV.L 8[R0], R2 + MOV.L R2, [-R1] ; save R2 on thread stack + MOV.L 4[R0], R2 + MOV.L R2, [-R1] ; save R1 on thread stack + MOV.L R5, [-R1] ; save R5 on thread stack + MOV.L R4, [-R1] ; save R4 on thread stack + MOV.L R3, [-R1] ; save R3 on thread stack + MOV.L R15, [-R1] ; save R15 on thread stack + MOV.L R14, [-R1] ; save R14 on thread stack + MVFC FPSW, R3 + MOV.L R3, [-R1] ; save FPSW on thread stack + + POP R2 ; pick up return address from interrupt stack + ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom + MVTC R1, USP ; set user/thread stack pointer + JMP R2 ; return to ISR + +; } +; else +; { +; +__tx_thread_idle_system_save: +; +; /* Interrupt occurred in the scheduling loop. */ +; + POP R1 ; pick up return address + ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers + JMP R1 ; return to caller +; +; } +;} + END diff --git a/ports/cortex_m33/ac5/src/tx_thread_interrupt_disable.s b/ports/rxv3/iar/src/tx_thread_interrupt_control.s similarity index 66% rename from ports/cortex_m33/ac5/src/tx_thread_interrupt_disable.s rename to ports/rxv3/iar/src/tx_thread_interrupt_control.s index e5e8ec40..8d2923a1 100644 --- a/ports/cortex_m33/ac5/src/tx_thread_interrupt_disable.s +++ b/ports/rxv3/iar/src/tx_thread_interrupt_control.s @@ -12,66 +12,82 @@ ; ;/**************************************************************************/ ;/**************************************************************************/ -;/** */ -;/** ThreadX Component */ +;/** */ +;/** ThreadX Component */ ;/** */ ;/** Thread */ ;/** */ ;/**************************************************************************/ ;/**************************************************************************/ ; +;#define TX_SOURCE_CODE ; - AREA ||.text||, CODE, READONLY - PRESERVE8 -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_thread_interrupt_disable Cortex-M33/AC5 */ -;/* 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) +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; + section .text:CODE:ROOT +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_control RXv3/IAR */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_control(UINT new_posture) ;{ - EXPORT _tx_thread_interrupt_disable -_tx_thread_interrupt_disable FUNCTION + public __tx_thread_interrupt_control +__tx_thread_interrupt_control: ; -; /* Return current interrupt lockout posture. */ +; /* Pickup current interrupt lockout posture. */ ; - MRS r0, PRIMASK - CPSID i - BX lr + + MVFC PSW, R2 ; Save PSW to R2 + MOV.L R2, R3 ; Make a copy of PSW in r3 + ; +; /* Apply the new interrupt posture. */ +; + + BTST #16, R1 ; test I bit of PSW of "new posture" + BMNE #16, R2 ; conditionally set I bit of intermediate posture + + MVTC R2, PSW ; save intermediate posture to PSW + + MOV.L R3,R1 ; Get original SR + RTS ; Return to caller ;} - ENDFUNC END diff --git a/ports/rxv3/iar/src/tx_thread_schedule.s b/ports/rxv3/iar/src/tx_thread_schedule.s new file mode 100644 index 00000000..fef0daf9 --- /dev/null +++ b/ports/rxv3/iar/src/tx_thread_schedule.s @@ -0,0 +1,179 @@ +;/**************************************************************************/ +;/* */ +;/* 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_timer.h" +; +; + extern __tx_thread_execute_ptr + extern __tx_thread_current_ptr + extern __tx_timer_time_slice + + section .text:CODE:ROOT + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_schedule RXv3/IAR */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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 */ +;/* _tx_thread_context_restore Restore thread's context */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_schedule(VOID) +;{ + public __tx_thread_schedule + +__tx_thread_schedule: +; +; /* Enable interrupts. */ +; + SETPSW I +; +; /* Wait for a thread to execute. */ +; do +; { + MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr +__tx_thread_schedule_loop: + MOV.L [R1],R2 ; Pickup next thread to execute + CMP #0,R2 ; Is it NULL? + BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking +; +; } +; while(_tx_thread_execute_ptr == TX_NULL); +; +; /* Yes! We have a thread to execute. Lockout interrupts and +; transfer control to it. */ +; + CLRPSW I ; disable interrupts +; +; /* Setup the current thread pointer. */ +; _tx_thread_current_ptr = _tx_thread_execute_ptr; +; + MOV.L #__tx_thread_current_ptr, R3 + MOV.L R2,[R3] ; Setup current thread pointer +; +; /* Increment the run count for this thread. */ +; _tx_thread_current_ptr -> tx_thread_run_count++; +; + MOV.L 4[R2],R3 ; Pickup run count + ADD #1,R3 ; Increment run counter + MOV.L R3,4[R2] ; Store it back in control block +; +; /* Setup time-slice, if present. */ +; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; +; + MOV.L 24[R2],R3 ; Pickup thread time-slice + MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice + MOV.L R3, [R4] ; Setup time-slice +; +; /* Switch to the thread's stack. */ +; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; + SETPSW U ; user stack mode + MOV.L 8[R2],R0 ; Pickup stack pointer +; +; /* Determine if an interrupt frame or a synchronous task suspension frame +; is present. */ +; + POP R1 ; Pickup stack type + CMP #1, R1 ; Is it an interrupt stack? + BNE __tx_thread_synch_return ; No, a synchronous return frame is present. + + POPM R1-R3 ; Restore accumulators. + MVTACLO R3, A0 + MVTACHI R2, A0 + MVTACGU R1, A0 + POPM R1-R3 + MVTACLO R3, A1 + MVTACHI R2, A1 + MVTACGU R1, A1 + + POPM R6-R13 ; Recover interrupt stack frame + POPC FPSW + POPM R14-R15 + POPM R3-R5 + POPM R1-R2 + RTE ; return to point of interrupt, this restores PC and PSW + +__tx_thread_synch_return: + POPC PSW + POPM R6-R13 ; Recover solicited stack frame + RTS +; +;} + + extern __tx_thread_context_save + extern __tx_thread_context_restore + +; Software triggered interrupt used to perform context switches. +; The priority of this interrupt is set to the lowest priority within +; tx_initialize_low_level() and triggered by ThreadX when calling +; _tx_thread_system_return(). + public ___interrupt_27 +___interrupt_27: + + PUSHM R1-R2 + + BSR __tx_thread_context_save + + BRA __tx_thread_context_restore + + END diff --git a/ports/cortex_m23/ac5/src/tx_thread_stack_build.s b/ports/rxv3/iar/src/tx_thread_stack_build.s similarity index 52% rename from ports/cortex_m23/ac5/src/tx_thread_stack_build.s rename to ports/rxv3/iar/src/tx_thread_stack_build.s index 4fdd0a07..7a4b67ac 100644 --- a/ports/cortex_m23/ac5/src/tx_thread_stack_build.s +++ b/ports/rxv3/iar/src/tx_thread_stack_build.s @@ -20,18 +20,18 @@ ;/**************************************************************************/ ;/**************************************************************************/ ; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 + + section .text:CODE:ROOT + ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ -;/* _tx_thread_stack_build Cortex-M23/AC5 */ -;/* 6.1 */ +;/* _tx_thread_stack_build RXv3/IAR */ +;/* 6.1.7 */ ;/* AUTHOR */ ;/* */ -;/* Scott Larson, Microsoft Corporation */ +;/* William E. Lamie, Microsoft Corporation */ ;/* */ ;/* DESCRIPTION */ ;/* */ @@ -60,80 +60,88 @@ ;/* */ ;/* DATE NAME DESCRIPTION */ ;/* */ -;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ ;/* */ ;/**************************************************************************/ -;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) -;{ - EXPORT _tx_thread_stack_build -_tx_thread_stack_build FUNCTION + + public __tx_thread_stack_build + +__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 +; +; /* Build an interrupt frame. The form of the fake interrupt stack +; on the Renesas RX should look like the following after it is built: +; +; Stack Top: 1 Interrupt stack frame type +; ACC0 +; ACC1 +; R6 +; R7 +; R8 +; R9 +; R10 +; R11 +; R12 +; R13 +; FPSW +; R14 +; R15 +; R3 +; R4 +; R5 +; R1 +; R2 +; PC +; PSW + ; ; Stack Bottom: (higher memory address) */ ; - LDR r2, [r0, #16] ; Pickup end of stack area - MOVS r3, #0x7 ; - BICS r2, r2, r3 ; Align frame for 8-byte alignment - SUBS r2, r2, #68 ; Subtract frame size - IF :DEF: 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 + MOV.L 16[R1],R3 ; Pickup end of stack area + BCLR #0, R3 ; mask for 4-byte alignment + BCLR #1, R3 ; -; /* Actually build the stack frame. */ -; - MOV 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 +; /* Build the stack frame. */ ; + MOV.L #30000h, R4 + MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set) + MOV.L R2, [-R3] ; initial PC + MOV.L #0, R4 + MOV.L R4,[-R3] ; initial R2 ... + MOV.L R4,[-R3] ; initial R1 ... + MOV.L R4,[-R3] ; initial R5 ... + MOV.L R4,[-R3] ; initial R4 ... + MOV.L R4,[-R3] ; initial R3 ... + MOV.L R4,[-R3] ; initial R15 ... + MOV.L R4,[-R3] ; initial R14 ... + MVFC FPSW, r4 + MOV.L R4, [-R3] ; initial FPSW + MOV.L #0, R4 + MOV.L R4,[-R3] ; initial R13 ... + MOV.L R4,[-R3] ; initial R12 ... + MOV.L R4,[-R3] ; initial R11 ... + MOV.L R4,[-R3] ; initial R10 ... + MOV.L R4,[-R3] ; initial R9 ... + MOV.L R4,[-R3] ; initial R8 ... + MOV.L R4,[-R3] ; initial R7 ... + MOV.L R4,[-R3] ; initial R6 ... + + MOV.L R4,[-R3] ; Accumulator 1 + MOV.L R4,[-R3] + MOV.L R4,[-R3] + + MOV.L R4,[-R3] ; Accumulator 0 + MOV.L R4,[-R3] + MOV.L R4,[-R3] + + MOV.L #1, R4 + MOV.L R4,[-R3] ; indicate interrupt stack frame ; /* 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 +; thread_ptr -> tx_thread_stack_ptr = R1; + MOV.L R3, 8[R1] + ; store initial SP in thread control block + RTS + ;} - ENDFUNC + END diff --git a/ports/cortex_m23/ac5/src/tx_thread_context_save.s b/ports/rxv3/iar/src/tx_thread_system_return.s similarity index 82% rename from ports/cortex_m23/ac5/src/tx_thread_context_save.s rename to ports/rxv3/iar/src/tx_thread_system_return.s index 6db66b25..8f6ec628 100644 --- a/ports/cortex_m23/ac5/src/tx_thread_context_save.s +++ b/ports/rxv3/iar/src/tx_thread_system_return.s @@ -19,23 +19,25 @@ ;/** */ ;/**************************************************************************/ ;/**************************************************************************/ -; -; - AREA ||.text||, CODE, READONLY - PRESERVE8 + + section .text:CODE:ROOT + ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ -;/* _tx_thread_context_save Cortex-M23/AC5 */ -;/* 6.1 */ +;/* _tx_thread_system_return RXv3/IAR */ +;/* 6.1.7 */ ;/* AUTHOR */ ;/* */ -;/* Scott Larson, Microsoft Corporation */ +;/* William E. Lamie, Microsoft Corporation */ ;/* */ ;/* DESCRIPTION */ ;/* */ -;/* This function is not needed for Cortex-M. */ +;/* This function is target processor specific. It is used to transfer */ +;/* control from a thread back to the system. Only a minimal context */ +;/* is saved since the compiler assumes temp registers are going to get */ +;/* slicked by a function call anyway. */ ;/* */ ;/* INPUT */ ;/* */ @@ -47,29 +49,26 @@ ;/* */ ;/* CALLS */ ;/* */ -;/* None */ +;/* _tx_thread_schedule Thread scheduling loop */ ;/* */ ;/* CALLED BY */ ;/* */ -;/* None */ +;/* ThreadX components */ ;/* */ ;/* RELEASE HISTORY */ ;/* */ ;/* DATE NAME DESCRIPTION */ ;/* */ -;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ ;/* */ ;/**************************************************************************/ -;VOID _tx_thread_context_save(VOID) -;{ - EXPORT _tx_thread_context_save -_tx_thread_context_save FUNCTION -; -; /* Return to interrupt processing. */ -; - BX lr -;} - ENDFUNC - ALIGN - LTORG + + public __tx_thread_system_return + +__tx_thread_system_return: + + BRA __tx_thread_system_return + + RTS + END diff --git a/ports/rxv3/iar/src/tx_timer_interrupt.s b/ports/rxv3/iar/src/tx_timer_interrupt.s new file mode 100644 index 00000000..8f615a20 --- /dev/null +++ b/ports/rxv3/iar/src/tx_timer_interrupt.s @@ -0,0 +1,235 @@ +;/**************************************************************************/ +;/* */ +;/* 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 */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ + + extern __tx_timer_expiration_process + extern __tx_timer_system_clock + extern __tx_timer_expired_time_slice + extern __tx_timer_current_ptr + extern __tx_timer_expired + extern __tx_timer_list_start + extern __tx_timer_time_slice + extern __tx_timer_list_end + extern __tx_thread_time_slice + + section .text:CODE:ROOT + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_timer_interrupt RXv3/IAR */ +;/* 6.1.7 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, 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_thread_context_save Save interrupted context */ +;/* _tx_timer_expiration_process Timer expiration processing */ +;/* _tx_thread_time_slice Time slice interrupted thread */ +;/* _tx_thread_context_restore Restore interrupted context */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* interrupt vector */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +;/* */ +;/**************************************************************************/ + + public __tx_timer_interrupt +__tx_timer_interrupt: +; +; /* Upon entry to this routine, it is assumed that all interrupts are locked +; out and the stack looks like the following: +; SP+4 -> Interrupted PC +; SP+8-> Interrupted SR +; */ +; +; /* Increment the system clock. */ +; _tx_timer_system_clock++; +; + PUSHM R14-R15 + PUSHM R1-R5 + + MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock + MOV.L [R1], R2 ; Pickup system clock + ADD #1, R2 ; Increment system clock + MOV.L R2,[R1] ; Store new system clock +; +; /* Test for time-slice expiration. */ +; if (_tx_timer_time_slice) +; { +; + MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice + MOV.L [R1], R2 ; Pickup the current time slice + CMP #0, R2 ; Is a time slice active? + BEQ __tx_timer_no_time_slice ; No, skip timer slice processing +; +; /* Decrement the time_slice. */ +; _tx_timer_time_slice--; +; + SUB #1, R2 ; Decrement the time-slice + MOV.L R2, [R1] ; Store time-slice +; +; /* Check for expiration. */ +; if (__tx_timer_time_slice == 0) +; + CMP #0, R2 ; Has it expired? + BNE __tx_timer_no_time_slice ; No, time-slice has not expired +; +; /* Set the time-slice expired flag. */ +; _tx_timer_expired_time_slice = TX_TRUE; +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice + MOV.L #1, R2 ; Build expired value + MOV.L R2, [R1] ; Set expired time slice variable +; } +; +__tx_timer_no_time_slice: +; +; /* Test for timer expiration. */ +; if (*_tx_timer_current_ptr) +; { +; + MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr + MOV.L [R1], R2 ; Pickup current pointer + MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++ + CMP #0, R1 ; Is timer pointer NULL? + BEQ __tx_timer_no_timer ; Yes, no timer has expired + +; +; /* Set expiration flag. */ +; _tx_timer_expired = TX_TRUE; +; + MOV.L #__tx_timer_expired,R2 ; Build address of expired flag + MOV.L #1, R1 ; Build expired value + MOV.L R1, [R2] + BRA __tx_timer_done ; Finished with timer processing +; +; } +; else +; { +__tx_timer_no_timer: +; +; /* No timer expired, increment the timer pointer. */ +; _tx_timer_current_ptr++; +; +; /* R2 already contains __tx_timer_current_ptr++ */ +; +; /* Check for wrap-around. */ +; if (_tx_timer_current_ptr == _tx_timer_list_end) +; + MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr + MOV.L [R1], R1 ; Pickup actual timer list end + CMP R1, R2 ; Are we at list end? + BNE __tx_timer_skip_wrap ; No, don't move pointer to the + ; top of the list +; +; /* Wrap to beginning of list. */ +; _tx_timer_current_ptr = _tx_timer_list_start; +; + MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr + MOV.L [R2], R2 ; Pickup the start of the list +; } +; +__tx_timer_skip_wrap: + MOV.L #__tx_timer_current_ptr,R1 + MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr + +__tx_timer_done: +; +; /* See if anything has expired. */ +; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) +; { +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr + MOV.L [R1], R1 ; Pickup expired time slice + MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address + MOV.L [R2], R2 ; Pickup actual flag + OR R1, R2 ; Or flags together + BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired + +__tx_something_expired: +; /* Did a timer expire? */ +; if (_tx_timer_expired) +; { + MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address + MOV.L [R1], R1 ; Pickup expired flag + CMP #0,R1 ; Is the expired timer flag set? + BEQ __tx_timer_dont_activate ; No, skip timer activation +; +; /* Process timer expiration. */ +; _tx_timer_expiration_process(); +; + BSR __tx_timer_expiration_process ; Call the timer expiration handling routine +; +; } +__tx_timer_dont_activate: +; +; /* Did time slice expire? */ +; if (_tx_timer_expired_time_slice) +; { +; + MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr + MOV.L [R1], R1 ; Pickup actual flag + CMP #0,R1 ; Has time-slice expired? + BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration +; +; /* Time slice interrupted thread. */ +; _tx_thread_time_slice(); + + BSR __tx_thread_time_slice ; Call time-slice processing +; } +; +__tx_timer_not_ts_expiration: + +__tx_timer_nothing_expired: + + POPM R1-R5 + POPM R14-R15 +; + RTS ; return to point of interrupt +; +;} + END \ No newline at end of file diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds b/ports_module/cortex-m3/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds deleted file mode 100644 index b1993316..00000000 --- a/ports_module/cortex-m3/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds +++ /dev/null @@ -1,3 +0,0 @@ -wait -load ..\sample_threadx_module\Debug\sample_threadx_module.axf -wait diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds b/ports_module/cortex-m3/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds deleted file mode 100644 index fc83a4f2..00000000 --- a/ports_module/cortex-m3/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds +++ /dev/null @@ -1,3 +0,0 @@ -wait -add-symbol-file ..\sample_threadx_module\Debug\sample_threadx_module.axf -wait diff --git a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/.project b/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/.project deleted file mode 100644 index bddfb9ee..00000000 --- a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/.project +++ /dev/null @@ -1,29 +0,0 @@ - - - sample_threadx_module_manager - - - sample_threadx_module - tx - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - com.arm.debug.ds.nature - org.eclipse.cdt.core.cnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - diff --git a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds b/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds deleted file mode 100644 index b1993316..00000000 --- a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds +++ /dev/null @@ -1,3 +0,0 @@ -wait -load ..\sample_threadx_module\Debug\sample_threadx_module.axf -wait diff --git a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds b/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds deleted file mode 100644 index fc83a4f2..00000000 --- a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds +++ /dev/null @@ -1,3 +0,0 @@ -wait -add-symbol-file ..\sample_threadx_module\Debug\sample_threadx_module.axf -wait diff --git a/ports_module/cortex-m4/iar/example_build/azure_rtos.eww b/ports_module/cortex-m4/iar/example_build/azure_rtos.eww deleted file mode 100644 index 75799733..00000000 --- a/ports_module/cortex-m4/iar/example_build/azure_rtos.eww +++ /dev/null @@ -1,19 +0,0 @@ - - - - $WS_DIR$\sample_threadx.ewp - - - $WS_DIR$\sample_threadx_module_manager.ewp - - - $WS_DIR$\sample_threadx_module.ewp - - - $WS_DIR$\tx.ewp - - - $WS_DIR$\txm.ewp - - - diff --git a/ports_module/cortex-a7/ac5/example_build/build_all.bat b/ports_module/cortex_a7/ac5/example_build/build_all.bat similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/build_all.bat rename to ports_module/cortex_a7/ac5/example_build/build_all.bat diff --git a/ports_module/cortex-a7/ac5/example_build/build_threadx.bat b/ports_module/cortex_a7/ac5/example_build/build_threadx.bat similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/build_threadx.bat rename to ports_module/cortex_a7/ac5/example_build/build_threadx.bat diff --git a/ports_module/cortex-a7/ac5/example_build/build_threadx_module_library.bat b/ports_module/cortex_a7/ac5/example_build/build_threadx_module_library.bat similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/build_threadx_module_library.bat rename to ports_module/cortex_a7/ac5/example_build/build_threadx_module_library.bat diff --git a/ports_module/cortex-a7/ac5/example_build/build_threadx_module_manager_sample.bat b/ports_module/cortex_a7/ac5/example_build/build_threadx_module_manager_sample.bat similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/build_threadx_module_manager_sample.bat rename to ports_module/cortex_a7/ac5/example_build/build_threadx_module_manager_sample.bat diff --git a/ports_module/cortex-a7/ac5/example_build/build_threadx_module_sample.bat b/ports_module/cortex_a7/ac5/example_build/build_threadx_module_sample.bat similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/build_threadx_module_sample.bat rename to ports_module/cortex_a7/ac5/example_build/build_threadx_module_sample.bat diff --git a/ports_module/cortex-a7/ac5/example_build/module_code.c b/ports_module/cortex_a7/ac5/example_build/module_code.c similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/module_code.c rename to ports_module/cortex_a7/ac5/example_build/module_code.c diff --git a/ports_module/cortex-a7/ac5/example_build/sample_threadx_module.c b/ports_module/cortex_a7/ac5/example_build/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/sample_threadx_module.c rename to ports_module/cortex_a7/ac5/example_build/sample_threadx_module.c diff --git a/ports_module/cortex-a7/ac5/example_build/sample_threadx_module_manager.c b/ports_module/cortex_a7/ac5/example_build/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/sample_threadx_module_manager.c rename to ports_module/cortex_a7/ac5/example_build/sample_threadx_module_manager.c diff --git a/ports_module/cortex-a7/ac5/example_build/scatter.scat b/ports_module/cortex_a7/ac5/example_build/scatter.scat similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/scatter.scat rename to ports_module/cortex_a7/ac5/example_build/scatter.scat diff --git a/ports_module/cortex-a7/ac5/example_build/tx_initialize_low_level.s b/ports_module/cortex_a7/ac5/example_build/tx_initialize_low_level.s similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/tx_initialize_low_level.s rename to ports_module/cortex_a7/ac5/example_build/tx_initialize_low_level.s diff --git a/ports_module/cortex-a7/ac5/example_build/txm_module_preamble.s b/ports_module/cortex_a7/ac5/example_build/txm_module_preamble.s similarity index 100% rename from ports_module/cortex-a7/ac5/example_build/txm_module_preamble.s rename to ports_module/cortex_a7/ac5/example_build/txm_module_preamble.s diff --git a/ports_module/cortex-a7/ac5/inc/tx_port.h b/ports_module/cortex_a7/ac5/inc/tx_port.h similarity index 100% rename from ports_module/cortex-a7/ac5/inc/tx_port.h rename to ports_module/cortex_a7/ac5/inc/tx_port.h diff --git a/ports_module/cortex-a7/ac5/inc/txm_module_port.h b/ports_module/cortex_a7/ac5/inc/txm_module_port.h similarity index 100% rename from ports_module/cortex-a7/ac5/inc/txm_module_port.h rename to ports_module/cortex_a7/ac5/inc/txm_module_port.h diff --git a/ports_module/cortex-a7/ac5/module_lib/src/txm_module_initialize.s b/ports_module/cortex_a7/ac5/module_lib/src/txm_module_initialize.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_lib/src/txm_module_initialize.s rename to ports_module/cortex_a7/ac5/module_lib/src/txm_module_initialize.s diff --git a/ports_module/cortex-a7/ac5/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_a7/ac5/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-a7/ac5/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_a7/ac5/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_context_restore.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_context_restore.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_context_restore.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_context_restore.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_context_save.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_context_save.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_context_save.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_context_save.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_context_restore.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_context_restore.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_context_restore.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_context_restore.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_context_save.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_context_save.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_context_save.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_context_save.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_nesting_end.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_nesting_end.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_nesting_end.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_nesting_end.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_nesting_start.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_nesting_start.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_fiq_nesting_start.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_fiq_nesting_start.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_interrupt_control.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_interrupt_control.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_interrupt_control.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_interrupt_control.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_interrupt_disable.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_interrupt_disable.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_interrupt_disable.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_interrupt_disable.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_interrupt_restore.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_interrupt_restore.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_interrupt_restore.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_interrupt_restore.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_irq_nesting_end.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_irq_nesting_end.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_irq_nesting_end.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_irq_nesting_end.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_irq_nesting_start.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_irq_nesting_start.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_irq_nesting_start.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_irq_nesting_start.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_schedule.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_schedule.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_schedule.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_stack_build.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_stack_build.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_stack_build.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_stack_build.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_system_return.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_system_return.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_system_return.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_system_return.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_thread_vectored_context_save.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_thread_vectored_context_save.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_thread_vectored_context_save.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_thread_vectored_context_save.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/tx_timer_interrupt.s b/ports_module/cortex_a7/ac5/module_manager/src/tx_timer_interrupt.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/tx_timer_interrupt.s rename to ports_module/cortex_a7/ac5/module_manager/src/tx_timer_interrupt.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_mm_initialize.c b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_mm_initialize.c similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_mm_initialize.c rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_mm_initialize.c diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_thread_stack_build.s b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_thread_stack_build.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_thread_stack_build.s rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_thread_stack_build.s diff --git a/ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_user_mode_entry.s b/ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_user_mode_entry.s similarity index 100% rename from ports_module/cortex-a7/ac5/module_manager/src/txm_module_manager_user_mode_entry.s rename to ports_module/cortex_a7/ac5/module_manager/src/txm_module_manager_user_mode_entry.s diff --git a/ports_module/cortex_m23/ac6/inc/tx_port.h b/ports_module/cortex_m23/ac6/inc/tx_port.h index f2604699..76a4444b 100644 --- a/ports_module/cortex_m23/ac6/inc/tx_port.h +++ b/ports_module/cortex_m23/ac6/inc/tx_port.h @@ -91,6 +91,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c index 311e67b6..b4679878 100644 --- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c +++ b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c @@ -335,7 +335,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M23/AC6 */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -370,6 +370,8 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -402,7 +404,7 @@ ULONG sp; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports_module/cortex_m23/gnu/inc/tx_port.h b/ports_module/cortex_m23/gnu/inc/tx_port.h index 7c87baff..83923e7f 100644 --- a/ports_module/cortex_m23/gnu/inc/tx_port.h +++ b/ports_module/cortex_m23/gnu/inc/tx_port.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M23/GNU */ -/* 6.1.6 */ +/* 6.1.7 */ /* */ /* AUTHOR */ /* */ @@ -54,6 +54,10 @@ /* ULONG64_DEFINED,updated */ /* macro definition, */ /* resulting in version 6.1.6 */ +/* 06-02-2021 Scott Larson Modified comment(s), */ +/* added symbol to enable */ +/* stack error handler, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -95,6 +99,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" diff --git a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c index 0e8cbde0..72bc05f8 100644 --- a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c +++ b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c @@ -342,7 +342,7 @@ ULONG ipsr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M23/GNU */ -/* 6.1.3 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -377,6 +377,8 @@ ULONG ipsr; /* 12-31-2020 Scott Larson Modified comment(s), and */ /* fixed M23 GCC build, */ /* resulting in version 6.1.3 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -411,7 +413,7 @@ ULONG ipsr; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports_module/cortex_m23/iar/inc/tx_port.h b/ports_module/cortex_m23/iar/inc/tx_port.h index 71c81e2c..54c6d6ec 100644 --- a/ports_module/cortex_m23/iar/inc/tx_port.h +++ b/ports_module/cortex_m23/iar/inc/tx_port.h @@ -101,6 +101,12 @@ UINT _txe_thread_secure_stack_free(struct TX_THREAD_STRUCT *thread_ptr); UINT _tx_thread_secure_stack_allocate(struct TX_THREAD_STRUCT *tx_thread, ULONG stack_size); UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread); +/* This port overrides tx_thread_stack_error_notify with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_NOTIFY + +/* This port overrides tx_thread_stack_error_handler with an architecture specific version */ +#define TX_PORT_THREAD_STACK_ERROR_HANDLER + /* This hardware has stack checking that we take advantage of - do NOT define. */ #ifdef TX_ENABLE_STACK_CHECKING #error "Do not define TX_ENABLE_STACK_CHECKING" diff --git a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c index b9ba72ff..d7e96333 100644 --- a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c +++ b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c @@ -335,7 +335,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* FUNCTION RELEASE */ /* */ /* _tx_thread_secure_stack_context_save Cortex-M23/IAR */ -/* 6.1.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -370,6 +370,8 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* 10-16-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.1 */ +/* 06-02-2021 Scott Larson Fix stack pointer save, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ __attribute__((cmse_nonsecure_entry)) @@ -402,7 +404,7 @@ ULONG sp; } /* Save stack pointer. */ - *(ULONG *) info_ptr -> tx_thread_secure_stack_ptr = sp; + info_ptr -> tx_thread_secure_stack_ptr = (VOID *) 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. */ diff --git a/ports_module/cortex-m3/ac5/example_build/build.bat b/ports_module/cortex_m3/ac5/example_build/build.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/build.bat rename to ports_module/cortex_m3/ac5/example_build/build.bat diff --git a/ports_module/cortex-m3/ac5/example_build/build_threadx.bat b/ports_module/cortex_m3/ac5/example_build/build_threadx.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/build_threadx.bat rename to ports_module/cortex_m3/ac5/example_build/build_threadx.bat diff --git a/ports_module/cortex-m3/ac5/example_build/build_threadx_demo.bat b/ports_module/cortex_m3/ac5/example_build/build_threadx_demo.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/build_threadx_demo.bat rename to ports_module/cortex_m3/ac5/example_build/build_threadx_demo.bat diff --git a/ports_module/cortex-m3/ac5/example_build/build_threadx_module_demo.bat b/ports_module/cortex_m3/ac5/example_build/build_threadx_module_demo.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/build_threadx_module_demo.bat rename to ports_module/cortex_m3/ac5/example_build/build_threadx_module_demo.bat diff --git a/ports_module/cortex-m3/ac5/example_build/build_threadx_module_library.bat b/ports_module/cortex_m3/ac5/example_build/build_threadx_module_library.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/build_threadx_module_library.bat rename to ports_module/cortex_m3/ac5/example_build/build_threadx_module_library.bat diff --git a/ports_module/cortex-m3/ac5/example_build/build_threadx_module_manager_demo.bat b/ports_module/cortex_m3/ac5/example_build/build_threadx_module_manager_demo.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/build_threadx_module_manager_demo.bat rename to ports_module/cortex_m3/ac5/example_build/build_threadx_module_manager_demo.bat diff --git a/ports_module/cortex-m3/ac5/example_build/clean.bat b/ports_module/cortex_m3/ac5/example_build/clean.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/clean.bat rename to ports_module/cortex_m3/ac5/example_build/clean.bat diff --git a/ports_module/cortex-m3/ac5/example_build/sample_threadx.c b/ports_module/cortex_m3/ac5/example_build/sample_threadx.c similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/sample_threadx.c rename to ports_module/cortex_m3/ac5/example_build/sample_threadx.c diff --git a/ports_module/cortex-m3/ac5/example_build/sample_threadx_module.c b/ports_module/cortex_m3/ac5/example_build/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/sample_threadx_module.c rename to ports_module/cortex_m3/ac5/example_build/sample_threadx_module.c diff --git a/ports_module/cortex-m3/ac5/example_build/sample_threadx_module_manager.c b/ports_module/cortex_m3/ac5/example_build/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/sample_threadx_module_manager.c rename to ports_module/cortex_m3/ac5/example_build/sample_threadx_module_manager.c diff --git a/ports_module/cortex-m3/ac5/example_build/setenv.bat b/ports_module/cortex_m3/ac5/example_build/setenv.bat similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/setenv.bat rename to ports_module/cortex_m3/ac5/example_build/setenv.bat diff --git a/ports_module/cortex-m3/ac5/example_build/tx_initialize_low_level.S b/ports_module/cortex_m3/ac5/example_build/tx_initialize_low_level.S similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/tx_initialize_low_level.S rename to ports_module/cortex_m3/ac5/example_build/tx_initialize_low_level.S diff --git a/ports_module/cortex-m3/ac5/example_build/txm_module_preamble.S b/ports_module/cortex_m3/ac5/example_build/txm_module_preamble.S similarity index 100% rename from ports_module/cortex-m3/ac5/example_build/txm_module_preamble.S rename to ports_module/cortex_m3/ac5/example_build/txm_module_preamble.S diff --git a/ports_module/cortex-m3/ac5/inc/tx_port.h b/ports_module/cortex_m3/ac5/inc/tx_port.h similarity index 100% rename from ports_module/cortex-m3/ac5/inc/tx_port.h rename to ports_module/cortex_m3/ac5/inc/tx_port.h diff --git a/ports_module/cortex-m3/ac5/inc/txm_module_port.h b/ports_module/cortex_m3/ac5/inc/txm_module_port.h similarity index 100% rename from ports_module/cortex-m3/ac5/inc/txm_module_port.h rename to ports_module/cortex_m3/ac5/inc/txm_module_port.h diff --git a/ports_module/cortex-m3/ac5/module_lib/src/txm_module_initialize.S b/ports_module/cortex_m3/ac5/module_lib/src/txm_module_initialize.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_lib/src/txm_module_initialize.S rename to ports_module/cortex_m3/ac5/module_lib/src/txm_module_initialize.S diff --git a/ports_module/cortex-m3/ac5/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m3/ac5/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-m3/ac5/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_m3/ac5/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_context_restore.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_context_restore.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_context_restore.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_context_restore.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_context_save.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_context_save.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_context_save.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_context_save.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_interrupt_control.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_interrupt_control.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_interrupt_control.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_interrupt_control.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_interrupt_disable.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_interrupt_disable.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_interrupt_disable.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_interrupt_disable.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_interrupt_restore.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_interrupt_restore.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_interrupt_restore.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_interrupt_restore.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_schedule.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_stack_build.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_stack_build.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_stack_build.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_stack_build.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_thread_system_return.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_system_return.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_thread_system_return.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_thread_system_return.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/tx_timer_interrupt.S b/ports_module/cortex_m3/ac5/module_manager/src/tx_timer_interrupt.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/tx_timer_interrupt.S rename to ports_module/cortex_m3/ac5/module_manager/src/tx_timer_interrupt.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_alignment_adjust.c diff --git a/ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_external_memory_enable.c diff --git a/ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c diff --git a/ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_thread_stack_build.S b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_thread_stack_build.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_thread_stack_build.S rename to ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_thread_stack_build.S diff --git a/ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_user_mode_entry.S b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_user_mode_entry.S similarity index 100% rename from ports_module/cortex-m3/ac5/module_manager/src/txm_module_manager_user_mode_entry.S rename to ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_user_mode_entry.S diff --git a/ports_module/cortex-m3/ac6/example_build/all.bat b/ports_module/cortex_m3/ac6/example_build/all.bat similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/all.bat rename to ports_module/cortex_m3/ac6/example_build/all.bat diff --git a/ports_module/cortex-m3/ac6/example_build/build.bat b/ports_module/cortex_m3/ac6/example_build/build.bat similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/build.bat rename to ports_module/cortex_m3/ac6/example_build/build.bat diff --git a/ports_module/cortex-m3/ac6/example_build/clean.bat b/ports_module/cortex_m3/ac6/example_build/clean.bat similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/clean.bat rename to ports_module/cortex_m3/ac6/example_build/clean.bat diff --git a/ports_module/cortex-m3/ac6/example_build/initws.bat b/ports_module/cortex_m3/ac6/example_build/initws.bat similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/initws.bat rename to ports_module/cortex_m3/ac6/example_build/initws.bat diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx/.cproject b/ports_module/cortex_m3/ac6/example_build/sample_threadx/.cproject similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx/.cproject rename to ports_module/cortex_m3/ac6/example_build/sample_threadx/.cproject diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx/.project b/ports_module/cortex_m3/ac6/example_build/sample_threadx/.project similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx/.project rename to ports_module/cortex_m3/ac6/example_build/sample_threadx/.project diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx/exceptions.c b/ports_module/cortex_m3/ac6/example_build/sample_threadx/exceptions.c similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx/exceptions.c rename to ports_module/cortex_m3/ac6/example_build/sample_threadx/exceptions.c diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx/sample_threadx.c b/ports_module/cortex_m3/ac6/example_build/sample_threadx/sample_threadx.c similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx/sample_threadx.c rename to ports_module/cortex_m3/ac6/example_build/sample_threadx/sample_threadx.c diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_module/cortex_m3/ac6/example_build/sample_threadx/sample_threadx.launch similarity index 80% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx/sample_threadx.launch rename to ports_module/cortex_m3/ac6/example_build/sample_threadx/sample_threadx.launch index d2582f5b..5931ba76 100644 --- a/ports_module/cortex-m3/ac6/example_build/sample_threadx/sample_threadx.launch +++ b/ports_module/cortex_m3/ac6/example_build/sample_threadx/sample_threadx.launch @@ -1,42 +1,42 @@ - - + + - - - + + + - - + + - + - - + + - + - - - - - - - + + + + + + + - + - - - - + + + + @@ -51,38 +51,32 @@ - - - - + - + - + - - - - + - + - + @@ -127,6 +121,7 @@ + @@ -178,7 +173,7 @@ - + diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx/sample_threadx.scat b/ports_module/cortex_m3/ac6/example_build/sample_threadx/sample_threadx.scat similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx/sample_threadx.scat rename to ports_module/cortex_m3/ac6/example_build/sample_threadx/sample_threadx.scat diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx/tx_initialize_low_level.S b/ports_module/cortex_m3/ac6/example_build/sample_threadx/tx_initialize_low_level.S similarity index 100% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx/tx_initialize_low_level.S rename to ports_module/cortex_m3/ac6/example_build/sample_threadx/tx_initialize_low_level.S diff --git a/ports_module/cortex-m3/ac6/example_build/sample_threadx_module/.cproject b/ports_module/cortex_m3/ac6/example_build/sample_threadx_module/.cproject similarity index 90% rename from ports_module/cortex-m3/ac6/example_build/sample_threadx_module/.cproject rename to ports_module/cortex_m3/ac6/example_build/sample_threadx_module/.cproject index 35a2d603..3c6f49d9 100644 --- a/ports_module/cortex-m3/ac6/example_build/sample_threadx_module/.cproject +++ b/ports_module/cortex_m3/ac6/example_build/sample_threadx_module/.cproject @@ -57,10 +57,6 @@ - - - - BILINK - 0 - - - - Coder - 0 - - - - - Release - - ARM - - 0 - - General - 3 - - 31 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 36 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 10 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - - - - - ILINK - 0 - - 23 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - diff --git a/ports_module/cortex-m4/iar/example_build/txm_module_preamble.s b/ports_module/cortex_m4/iar/example_build/txm_module_preamble.s similarity index 100% rename from ports_module/cortex-m4/iar/example_build/txm_module_preamble.s rename to ports_module/cortex_m4/iar/example_build/txm_module_preamble.s diff --git a/ports_module/cortex-m4/iar/inc/tx_port.h b/ports_module/cortex_m4/iar/inc/tx_port.h similarity index 100% rename from ports_module/cortex-m4/iar/inc/tx_port.h rename to ports_module/cortex_m4/iar/inc/tx_port.h diff --git a/ports_module/cortex-m4/iar/inc/txm_module_port.h b/ports_module/cortex_m4/iar/inc/txm_module_port.h similarity index 100% rename from ports_module/cortex-m4/iar/inc/txm_module_port.h rename to ports_module/cortex_m4/iar/inc/txm_module_port.h diff --git a/ports_module/cortex-m4/iar/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m4/iar/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-m4/iar/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_m4/iar/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_iar.c b/ports_module/cortex_m4/iar/module_manager/src/tx_iar.c similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_iar.c rename to ports_module/cortex_m4/iar/module_manager/src/tx_iar.c diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_misra.s b/ports_module/cortex_m4/iar/module_manager/src/tx_misra.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_misra.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_misra.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_context_restore.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_context_restore.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_context_restore.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_context_restore.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_context_save.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_context_save.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_context_save.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_context_save.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_interrupt_control.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_interrupt_control.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_interrupt_control.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_interrupt_control.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_interrupt_disable.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_interrupt_disable.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_interrupt_disable.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_interrupt_disable.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_interrupt_restore.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_interrupt_restore.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_interrupt_restore.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_interrupt_restore.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s similarity index 94% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_schedule.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s index 116c092b..d2d66f6c 100644 --- a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M4/MPU/IAR */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -69,11 +69,14 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), arrange */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), arrange */ /* code to fix link error when */ /* VFP is enabled, resulting */ /* in version 6.1.2 */ +/* 06-02-2021 Scott Larson Fixed extended stack handling */ +/* when calling kernel APIs, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -430,20 +433,24 @@ __tx_SVCallHandler: STR r0, [r2, #16] // Set stack end STR r3, [r2, #20] // Set stack size #endif - MRS r3, PSP // Pickup thread stack pointer + TST lr, #0x10 // Test for extended module stack + ITT EQ + ORREQ r3, r3, #1 // If so, set LSB in thread stack pointer to indicate extended frame + ORREQ lr, lr, #0x10 // Set bit, return with standard frame STR r3, [r2, #0xB0] // Save thread stack pointer - + BIC r3, #1 // Clear possibly OR'd bit + /* Build kernel stack by copying thread stack two registers at a time */ ADD r3, r3, #32 // Start at bottom of hardware stack - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} MSR PSP, r0 // Set kernel stack pointer @@ -481,16 +488,21 @@ _tx_thread_user_return: #endif LDR r0, [r2, #0xB0] // Load the module thread stack pointer MRS r3, PSP // Pickup kernel stack pointer + TST r0, #1 // Is module stack extended? + ITTE NE // If so... + BICNE lr, #0x10 // Clear bit, return with extended frame + BICNE r0, #1 // Clear bit that indicates extended module frame + ORREQ lr, lr, #0x10 // Else set bit, return with standard frame /* 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} + 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} SUB r0, r0, #32 // Subtract 32 to get back to top of stack MSR PSP, r0 // Set thread stack pointer diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_stack_build.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_stack_build.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_stack_build.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_stack_build.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_thread_system_return.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_system_return.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_thread_system_return.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_thread_system_return.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/tx_timer_interrupt.s b/ports_module/cortex_m4/iar/module_manager/src/tx_timer_interrupt.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/tx_timer_interrupt.s rename to ports_module/cortex_m4/iar/module_manager/src/tx_timer_interrupt.s diff --git a/ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_alignment_adjust.c diff --git a/ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_external_memory_enable.c diff --git a/ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c diff --git a/ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_thread_stack_build.s b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_thread_stack_build.s similarity index 100% rename from ports_module/cortex-m4/iar/module_manager/src/txm_module_manager_thread_stack_build.s rename to ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_thread_stack_build.s diff --git a/ports_module/cortex-m7/ac5/example_build/build.bat b/ports_module/cortex_m7/ac5/example_build/build.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/build.bat rename to ports_module/cortex_m7/ac5/example_build/build.bat diff --git a/ports_module/cortex-m7/ac5/example_build/build_threadx.bat b/ports_module/cortex_m7/ac5/example_build/build_threadx.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/build_threadx.bat rename to ports_module/cortex_m7/ac5/example_build/build_threadx.bat diff --git a/ports_module/cortex-m7/ac5/example_build/build_threadx_demo.bat b/ports_module/cortex_m7/ac5/example_build/build_threadx_demo.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/build_threadx_demo.bat rename to ports_module/cortex_m7/ac5/example_build/build_threadx_demo.bat diff --git a/ports_module/cortex-m7/ac5/example_build/build_threadx_module_demo.bat b/ports_module/cortex_m7/ac5/example_build/build_threadx_module_demo.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/build_threadx_module_demo.bat rename to ports_module/cortex_m7/ac5/example_build/build_threadx_module_demo.bat diff --git a/ports_module/cortex-m7/ac5/example_build/build_threadx_module_library.bat b/ports_module/cortex_m7/ac5/example_build/build_threadx_module_library.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/build_threadx_module_library.bat rename to ports_module/cortex_m7/ac5/example_build/build_threadx_module_library.bat diff --git a/ports_module/cortex-m7/ac5/example_build/build_threadx_module_manager_demo.bat b/ports_module/cortex_m7/ac5/example_build/build_threadx_module_manager_demo.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/build_threadx_module_manager_demo.bat rename to ports_module/cortex_m7/ac5/example_build/build_threadx_module_manager_demo.bat diff --git a/ports_module/cortex-m7/ac5/example_build/clean.bat b/ports_module/cortex_m7/ac5/example_build/clean.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/clean.bat rename to ports_module/cortex_m7/ac5/example_build/clean.bat diff --git a/ports_module/cortex-m7/ac5/example_build/sample_threadx.c b/ports_module/cortex_m7/ac5/example_build/sample_threadx.c similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/sample_threadx.c rename to ports_module/cortex_m7/ac5/example_build/sample_threadx.c diff --git a/ports_module/cortex-m7/ac5/example_build/sample_threadx_module.c b/ports_module/cortex_m7/ac5/example_build/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/sample_threadx_module.c rename to ports_module/cortex_m7/ac5/example_build/sample_threadx_module.c diff --git a/ports_module/cortex-m7/ac5/example_build/sample_threadx_module_manager.c b/ports_module/cortex_m7/ac5/example_build/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/sample_threadx_module_manager.c rename to ports_module/cortex_m7/ac5/example_build/sample_threadx_module_manager.c diff --git a/ports_module/cortex-m7/ac5/example_build/setenv.bat b/ports_module/cortex_m7/ac5/example_build/setenv.bat similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/setenv.bat rename to ports_module/cortex_m7/ac5/example_build/setenv.bat diff --git a/ports_module/cortex-m7/ac5/example_build/tx_initialize_low_level.S b/ports_module/cortex_m7/ac5/example_build/tx_initialize_low_level.S similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/tx_initialize_low_level.S rename to ports_module/cortex_m7/ac5/example_build/tx_initialize_low_level.S diff --git a/ports_module/cortex-m7/ac5/example_build/txm_module_preamble.S b/ports_module/cortex_m7/ac5/example_build/txm_module_preamble.S similarity index 100% rename from ports_module/cortex-m7/ac5/example_build/txm_module_preamble.S rename to ports_module/cortex_m7/ac5/example_build/txm_module_preamble.S diff --git a/ports_module/cortex-m7/ac5/inc/tx_port.h b/ports_module/cortex_m7/ac5/inc/tx_port.h similarity index 100% rename from ports_module/cortex-m7/ac5/inc/tx_port.h rename to ports_module/cortex_m7/ac5/inc/tx_port.h diff --git a/ports_module/cortex-m7/ac5/inc/txm_module_port.h b/ports_module/cortex_m7/ac5/inc/txm_module_port.h similarity index 90% rename from ports_module/cortex-m7/ac5/inc/txm_module_port.h rename to ports_module/cortex_m7/ac5/inc/txm_module_port.h index d876f338..539a4f19 100644 --- a/ports_module/cortex-m7/ac5/inc/txm_module_port.h +++ b/ports_module/cortex_m7/ac5/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-M7/MPU/AC5 */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -40,10 +40,12 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), */ /* increase kernel stack size, */ /* resulting in version 6.1.2 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -119,7 +121,6 @@ The following extensions must also be defined in tx_port.h: #define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000 #endif - /* Define constants specific to the tools the module can be built with for this particular modules port. */ #define TXM_MODULE_IAR_COMPILER 0x00000000 @@ -174,6 +175,8 @@ The following extensions must also be defined in tx_port.h: #define INLINE_DECLARE inline +#ifndef TXM_MODULE_MANAGER_8_MPU + /* Define the number of MPU entries assigned to the code and data sections. On Cortex-M7 parts, there are 16 total entries. ThreadX uses one for access to the kernel entry function, thus 15 remain for code and data protection. */ @@ -205,6 +208,28 @@ typedef struct TXM_MODULE_MPU_INFO_STRUCT ULONG txm_module_instance_shared_memory_address[TXM_MODULE_MPU_SHARED_ENTRIES]; \ ULONG txm_module_instance_shared_memory_length[TXM_MODULE_MPU_SHARED_ENTRIES]; +#else /* TXM_MODULE_MANAGER_8_MPU is defined */ + +/* Define the number of MPU entries assigned to the code and data sections. + On Cortex-M4 parts, there are 8 total entries. ThreadX uses one for access + to the kernel entry function, thus 7 remain for code and data protection. */ +#define TXM_MODULE_MANAGER_CODE_MPU_ENTRIES 4 +#define TXM_MODULE_MANAGER_DATA_MPU_ENTRIES 3 +#define TXM_MODULE_MANAGER_SHARED_MPU_INDEX 8 +#define TXM_MODULE_MANAGER_SHARED_MPU_REGION 4 + +/* Shared memory region attributes. */ +#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1 +#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT 0x01000000 + +/* Define the port-extensions to the module manager instance structure. */ + +#define TXM_MODULE_MANAGER_PORT_EXTENSION \ + ULONG txm_module_instance_mpu_registers[16]; \ + ULONG txm_module_instance_shared_memory_address; \ + ULONG txm_module_instance_shared_memory_length; + +#endif /* TXM_MODULE_MANAGER_8_MPU */ /* Define the memory fault information structure that is populated when a memory fault occurs. */ @@ -327,8 +352,20 @@ typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT /* Define the macros to perform port-specific checks when passing pointers to the kernel. */ /* Define macro to make sure object is inside the module's data. */ +#ifndef TXM_MODULE_MANAGER_8_MPU #define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ _txm_module_manager_inside_data_check(module_instance, obj_ptr, obj_size) +#else +#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ + /* Check for overflow. */ \ + (((obj_ptr) < ((obj_ptr) + (obj_size))) && \ + /* Check if it's inside module data. */ \ + ((((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) && \ + (((obj_ptr) + (obj_size)) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1))) || \ + /* Check if it's inside shared memory. */ \ + (((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address) && \ + (((obj_ptr) + (obj_size)) <= (ALIGN_TYPE) (module_instance -> txm_module_instance_shared_memory_address + module_instance -> txm_module_instance_shared_memory_length))))) +#endif /* Define some internal prototypes to this module port. */ @@ -349,6 +386,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance #define TXM_MODULE_MANAGER_VERSION_ID \ CHAR _txm_module_manager_version_id[] = \ - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/AC5 Version 6.1.2 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/AC5 Version 6.1.7 *"; #endif diff --git a/ports_module/cortex-m7/ac5/module_lib/src/txm_module_initialize.S b/ports_module/cortex_m7/ac5/module_lib/src/txm_module_initialize.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_lib/src/txm_module_initialize.S rename to ports_module/cortex_m7/ac5/module_lib/src/txm_module_initialize.S diff --git a/ports_module/cortex-m7/ac5/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m7/ac5/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-m7/ac5/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_m7/ac5/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_context_restore.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_context_restore.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_context_restore.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_context_restore.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_context_save.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_context_save.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_context_save.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_context_save.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_interrupt_control.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_interrupt_control.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_interrupt_control.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_interrupt_control.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_interrupt_disable.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_interrupt_disable.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_interrupt_disable.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_interrupt_disable.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_interrupt_restore.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_interrupt_restore.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_interrupt_restore.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_interrupt_restore.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.S similarity index 93% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_schedule.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.S index 1354a406..31897e33 100644 --- a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.S @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/MPU/AC5 */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -73,11 +73,15 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), arrange */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), arrange */ /* code to fix link error when */ /* VFP is enabled, resulting */ /* in version 6.1.2 */ +/* 06-02-2021 Scott Larson Fixed extended stack handling */ +/* when calling kernel APIs, */ +/* added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -360,6 +364,7 @@ __tx_ts_restore // Use alias registers to quickly load MPU ADD r0, r0, #100 // Build address of MPU register start in thread control block +#ifndef TXM_MODULE_MANAGER_8_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 @@ -368,6 +373,12 @@ __tx_ts_restore 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 LDR r0, =0xE000ED94 // Build MPU control reg address MOV r1, #5 // Build enable value with background region enabled STR r1, [r0] // Enable MPU @@ -435,18 +446,23 @@ __tx_SVCallHandler ENDIF MRS r3, PSP // Pickup thread stack pointer + TST lr, #0x10 // Test for extended module stack + ITT EQ + ORREQ r3, r3, #1 // If so, set LSB in thread stack pointer to indicate extended frame + ORREQ lr, lr, #0x10 // Set bit, return with standard frame STR r3, [r2, #0xB0] // Save thread stack pointer - + BIC r3, #1 // Clear possibly OR'd bit + /* Build kernel stack by copying thread stack two registers at a time */ ADD r3, r3, #32 // Start at bottom of hardware stack - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} MSR PSP, r0 // Set kernel stack pointer @@ -484,16 +500,21 @@ _tx_thread_user_return ENDIF LDR r0, [r2, #0xB0] // Load the module thread stack pointer MRS r3, PSP // Pickup kernel stack pointer + TST r0, #1 // Is module stack extended? + ITTE NE // If so... + BICNE lr, #0x10 // Clear bit, return with extended frame + BICNE r0, #1 // Clear bit that indicates extended module frame + ORREQ lr, lr, #0x10 // Else set bit, return with standard frame /* 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} + 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} SUB r0, r0, #32 // Subtract 32 to get back to top of stack MSR PSP, r0 // Set thread stack pointer diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_stack_build.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_stack_build.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_stack_build.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_stack_build.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_thread_system_return.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_system_return.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_thread_system_return.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_thread_system_return.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/tx_timer_interrupt.S b/ports_module/cortex_m7/ac5/module_manager/src/tx_timer_interrupt.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/tx_timer_interrupt.S rename to ports_module/cortex_m7/ac5/module_manager/src/tx_timer_interrupt.S diff --git a/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c new file mode 100644 index 00000000..59a8e0d0 --- /dev/null +++ b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c @@ -0,0 +1,450 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Module Manager */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define TX_SOURCE_CODE + +#include "tx_api.h" +#include "txm_module.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_power_of_two_block_size Cortex-M7/MPU/AC5 */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function calculates a power of two size at or immediately above*/ +/* the input size and returns it to the caller. */ +/* */ +/* INPUT */ +/* */ +/* size Block size */ +/* */ +/* OUTPUT */ +/* */ +/* calculated size Rounded up to power of two */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _txm_module_manager_alignment_adjust Adjust alignment for Cortex-M */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* */ +/**************************************************************************/ +ULONG _txm_power_of_two_block_size(ULONG size) +{ + /* Check for 0 size. */ + if(size == 0) + return 0; + + /* Minimum MPU block size is 32. */ + if(size <= 32) + return 32; + + /* Bit twiddling trick to round to next high power of 2 + (if original size is power of 2, it will return original size. Perfect!) */ + size--; + size |= size >> 1; + size |= size >> 2; + size |= size >> 4; + size |= size >> 8; + size |= size >> 16; + size++; + + /* Return a power of 2 size at or above the input size. */ + return(size); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_module_manager_alignment_adjust Cortex-M7/MPU/AC5 */ +/* 6.1.7 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function adjusts the alignment and size of the code and data */ +/* section for a given module implementation. */ +/* */ +/* INPUT */ +/* */ +/* module_preamble Pointer to module preamble */ +/* code_size Size of the code area (updated) */ +/* code_alignment Code area alignment (updated) */ +/* data_size Size of data area (updated) */ +/* data_alignment Data area alignment (updated) */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _txm_power_of_two_block_size Calculate power of two size */ +/* */ +/* CALLED BY */ +/* */ +/* Initial thread stack frame */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ +/* */ +/**************************************************************************/ +VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, + ULONG *code_size, + ULONG *code_alignment, + ULONG *data_size, + ULONG *data_alignment) +{ +#ifndef TXM_MODULE_MANAGER_8_MPU +ULONG local_code_size; +ULONG local_code_alignment; +ULONG local_data_size; +ULONG local_data_alignment; +ULONG code_size_accum; +ULONG data_size_accum; + + /* Copy the input parameters into local variables for ease of use. */ + local_code_size = *code_size; + local_code_alignment = *code_alignment; + local_data_size = *data_size; + local_data_alignment = *data_alignment; + + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2; + code_size_accum = local_code_alignment + local_code_alignment; + code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1); + code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum); + local_code_size = code_size_accum; + + /* Determine data block sizes. Minimize the alignment requirement. + There are 4 MPU data entries available. The following is how the data size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to data size. + 2. 1/4 of the largest power of two that is greater than or equal to data size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + local_data_alignment = _txm_power_of_two_block_size(local_data_size) >> 2; + data_size_accum = local_data_alignment + local_data_alignment; + data_size_accum = data_size_accum + (_txm_power_of_two_block_size(local_data_size - data_size_accum) >> 1); + data_size_accum = data_size_accum + _txm_power_of_two_block_size(local_data_size - data_size_accum); + local_data_size = data_size_accum; + + /* Return all the information to the caller. */ + *code_size = local_code_size; + *code_alignment = local_code_alignment; + *data_size = local_data_size; + *data_alignment = local_data_alignment; + +#else + +ULONG local_code_size; +ULONG local_code_alignment; +ULONG local_data_size; +ULONG local_data_alignment; +ULONG code_block_size; +ULONG data_block_size; +ULONG code_size_accum; +ULONG data_size_accum; + + /* Copy the input parameters into local variables for ease of use. */ + local_code_size = *code_size; + local_code_alignment = *code_alignment; + local_data_size = *data_size; + local_data_alignment = *data_alignment; + + + /* Test for external memory enabled in preamble. */ + if(module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS) + { + /* External/shared memory enabled. TXM_MODULE_MANAGER_CODE_MPU_ENTRIES-1 code entries will be used. */ + if (local_code_size <= (32*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32 is best. */ + code_block_size = 32; + } + else if (local_code_size <= (64*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 64 is best. */ + code_block_size = 64; + } + else if (local_code_size <= (128*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 128 is best. */ + code_block_size = 128; + } + else if (local_code_size <= (256*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 256 is best. */ + code_block_size = 256; + } + else if (local_code_size <= (512*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 512 is best. */ + code_block_size = 512; + } + else if (local_code_size <= (1024*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1024 is best. */ + code_block_size = 1024; + } + else if (local_code_size <= (2048*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2048 is best. */ + code_block_size = 2048; + } + else if (local_code_size <= (4096*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4096 is best. */ + code_block_size = 4096; + } + else if (local_code_size <= (8192*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 8192 is best. */ + code_block_size = 8192; + } + else if (local_code_size <= (16384*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 16384 is best. */ + code_block_size = 16384; + } + else if (local_code_size <= (32768*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32768 is best. */ + code_block_size = 32768; + } + else if (local_code_size <= (65536*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 65536 is best. */ + code_block_size = 65536; + } + else if (local_code_size <= (131072*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 131072 is best. */ + code_block_size = 131072; + } + else if (local_code_size <= (262144*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 262144 is best. */ + code_block_size = 262144; + } + else if (local_code_size <= (524288*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 524288 is best. */ + code_block_size = 524288; + } + else if (local_code_size <= (1048576*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1048576 is best. */ + code_block_size = 1048576; + } + else if (local_code_size <= (2097152*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2097152 is best. */ + code_block_size = 2097152; + } + else if (local_code_size <= (4194304*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4194304 is best. */ + code_block_size = 4194304; + } + else + { + /* Just set block size to 32MB just to create an allocation error! */ + code_block_size = 33554432; + } + + /* Calculate the new code size. */ + local_code_size = code_block_size*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1); + + /* Determine if the code block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (code_block_size > local_code_alignment) + local_code_alignment = code_block_size; + + } + else + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2; + code_size_accum = local_code_alignment + local_code_alignment; + code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1); + code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum); + local_code_size = code_size_accum; + } + + /* Determine the best data block size, which in our case is the minimal alignment. */ + if (local_data_size <= (32*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32 is best. */ + data_block_size = 32; + } + else if (local_data_size <= (64*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 64 is best. */ + data_block_size = 64; + } + else if (local_data_size <= (128*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 128 is best. */ + data_block_size = 128; + } + else if (local_data_size <= (256*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 256 is best. */ + data_block_size = 256; + } + else if (local_data_size <= (512*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 512 is best. */ + data_block_size = 512; + } + else if (local_data_size <= (1024*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1024 is best. */ + data_block_size = 1024; + } + else if (local_data_size <= (2048*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2048 is best. */ + data_block_size = 2048; + } + else if (local_data_size <= (4096*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4096 is best. */ + data_block_size = 4096; + } + else if (local_data_size <= (8192*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 8192 is best. */ + data_block_size = 8192; + } + else if (local_data_size <= (16384*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 16384 is best. */ + data_block_size = 16384; + } + else if (local_data_size <= (32768*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32768 is best. */ + data_block_size = 32768; + } + else if (local_data_size <= (65536*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 65536 is best. */ + data_block_size = 65536; + } + else if (local_data_size <= (131072*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 131072 is best. */ + data_block_size = 131072; + } + else if (local_data_size <= (262144*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 262144 is best. */ + data_block_size = 262144; + } + else if (local_data_size <= (524288*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 524288 is best. */ + data_block_size = 524288; + } + else if (local_data_size <= (1048576*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1048576 is best. */ + data_block_size = 1048576; + } + else if (local_data_size <= (2097152*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2097152 is best. */ + data_block_size = 2097152; + } + else if (local_data_size <= (4194304*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4194304 is best. */ + data_block_size = 4194304; + } + else + { + /* Just set data block size to 32MB just to create an allocation error! */ + data_block_size = 33554432; + } + + /* Calculate the new data size. */ + data_size_accum = data_block_size; + while(data_size_accum < local_data_size) + { + data_size_accum += data_block_size; + } + local_data_size = data_size_accum; + + /* Determine if the data block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (data_block_size > local_data_alignment) + { + local_data_alignment = data_block_size; + } + + /* Return all the information to the caller. */ + *code_size = local_code_size; + *code_alignment = local_code_alignment; + *data_size = local_data_size; + *data_alignment = local_data_alignment; + +#endif +} diff --git a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 69% rename from ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c index f9a317a9..36d5fb9c 100644 --- a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c +++ b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_external_memory_enable.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_external_memory_enable Cortex-M7/MPU/AC5 */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -69,7 +69,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in verison 6.1.7 */ /* */ /**************************************************************************/ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance, @@ -77,7 +79,7 @@ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_ins ULONG length, UINT attributes) { - +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG block_size; ULONG region_size; ULONG srd_bits; @@ -186,4 +188,109 @@ ULONG attributes_check = 0; /* Return success. */ return(TX_SUCCESS); + +#else + +ULONG block_size; +ULONG region_size; +ULONG subregion_bits; +ULONG address; +UINT attributes_check = 0; +TXM_MODULE_PREAMBLE *module_preamble; + + /* Determine if the module manager has not been initialized yet. */ + if (_txm_module_manager_ready != TX_TRUE) + { + /* Module manager has not been initialized. */ + return(TX_NOT_AVAILABLE); + } + + /* Determine if the module is valid. */ + if (module_instance == TX_NULL) + { + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Get module manager protection mutex. */ + _tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER); + + /* Determine if the module instance is valid. */ + if (module_instance -> txm_module_instance_id != TXM_MODULE_ID) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Determine if the module instance is in the loaded state. */ + if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if the module is not ready. */ + return(TX_START_ERROR); + } + + /* Check if preamble shared mem and mem protection property bits are set. */ + module_preamble = module_instance -> txm_module_instance_preamble_ptr; + if((module_preamble -> txm_module_preamble_property_flags & (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + != (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if bit not set. */ + return(TXM_MODULE_INVALID_PROPERTIES); + } + + /* Start address and length must adhere to Cortex-M MPU. + The address must align with the block size. */ + + block_size = _txm_power_of_two_block_size(length); + address = (ULONG) start_address; + if(address != (address & ~(block_size - 1))) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return alignment error. */ + return(TXM_MODULE_ALIGNMENT_ERROR); + } + + /* At this point, we have a valid address and block size. + Set up MPU registers. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] = address | TXM_MODULE_MANAGER_SHARED_MPU_REGION | 0x10; + + /* Calculate the region size. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + /* Calculate the subregion bits. */ + subregion_bits = _txm_module_manager_calculate_srd_bits(block_size, length); + + /* Check for valid attributes. */ + if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE) + { + attributes_check = TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT; + } + + /* Build register with attributes. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX+1] = region_size | subregion_bits | attributes_check | 0x12070001; + + /* Keep track of shared memory address and length in module instance. */ + module_instance -> txm_module_instance_shared_memory_address = address; + module_instance -> txm_module_instance_shared_memory_length = length; + + /* Recalculate MPU settings. */ + _txm_module_manager_mm_register_setup(module_instance); + + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return success. */ + return(TX_SUCCESS); + +#endif } diff --git a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 71% rename from ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c index 3dce9ab7..030bd5cc 100644 --- a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c +++ b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c @@ -259,6 +259,7 @@ UINT srd_bit_index; /* 14 Unused region */ /* 15 Unused region */ /* */ +/* If TXM_MODULE_MANAGER_8_MPU is defined, there are only 8 MPU slots. */ /* */ /* INPUT */ /* */ @@ -280,11 +281,14 @@ UINT srd_bit_index; /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance) { +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG code_address; ULONG code_size; @@ -452,10 +456,256 @@ UINT i; /* Increment MPU table index. */ mpu_table_index++; } + +#else + +ULONG code_address; +ULONG code_size; +ULONG data_address; +ULONG data_size; +ULONG start_stop_stack_size; +ULONG callback_stack_size; +ULONG block_size; +ULONG base_address_register; +ULONG base_attribute_register; +ULONG region_size; +ULONG srd_bits = 0; +UINT mpu_register = 0; +UINT mpu_table_index; +UINT i; + + + /* Setup the first region for the ThreadX trampoline code. */ + /* Set base register to user mode entry, which is guaranteed to be at least 32-byte aligned. */ + base_address_register = (ULONG) _txm_module_manager_user_mode_entry; + /* Mask address to proper range, region 0, set Valid bit. */ + base_address_register = (base_address_register & 0xFFFFFFE0) | mpu_register | 0x10; + module_instance -> txm_module_instance_mpu_registers[0] = base_address_register; + + /* Attributes: read only, write-back, shareable, size 32 bytes, region enabled. */ + module_instance -> txm_module_instance_mpu_registers[1] = 0x06070009; + + /* Initialize the MPU register. */ + mpu_register = 1; + + /* Initialize the MPU table index. */ + mpu_table_index = 2; + + /* Setup values for code area. */ + code_address = (ULONG) module_instance -> txm_module_instance_code_start; + code_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_code_size; + + /* Check if shared memory was set up. If so, only 3 entries are available for + code protection. If not set up, 4 code entries are available. */ + if(module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] == 0) + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES; i++) + { + /* First two MPU blocks are 1/4 of the largest power of two + that is greater than or equal to code size. */ + if (i < 2) + { + block_size = _txm_power_of_two_block_size(code_size) >> 2; + } + + /* Third MPU block is the largest power of 2 that fits in the remaining space. */ + else if (i == 2) + { + /* Subtract (block_size*2) from code_size to calculate remaining space. */ + code_size = code_size - (block_size << 1); + block_size = _txm_power_of_two_block_size(code_size) >> 1; + } + + /* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */ + else + { + /* Calculate remaining space. */ + code_size = code_size - block_size; + block_size = _txm_power_of_two_block_size(code_size); + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base address register. */ + base_address_register = (code_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070001; + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + } + + /* Only 3 code entries available. */ + else + { + /* Calculate block size, one code entry taken up by shared memory. */ + block_size = _txm_power_of_two_block_size(code_size / (TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)); + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1; i++) + { + /* Build the base address register. */ + base_address_register = code_address & ~(block_size - 1) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (code_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070000; + + /* Is there still some code? If so set the region enable bit. */ + if (code_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Decrement the code size. */ + if (code_size > block_size) + { + code_size = code_size - block_size; + } + else + { + code_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Adjust indeces to pass over the shared memory entry. */ + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Setup values for data area. */ + data_address = (ULONG) module_instance -> txm_module_instance_data_start; + + /* Adjust the size of the module elements to be aligned to the default alignment. We do this + so that when we partition the allocated memory, we can simply place these regions right beside + each other without having to align their pointers. Note this only works when they all have + the same alignment. */ + + data_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_data_size; + start_stop_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_start_stop_stack_size; + callback_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_callback_stack_size; + + data_size = ((data_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + start_stop_stack_size = ((start_stop_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + callback_stack_size = ((callback_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + /* Update the data size to include thread stacks. */ + data_size = data_size + start_stop_stack_size + callback_stack_size; + + block_size = _txm_power_of_two_block_size(data_size / TXM_MODULE_MANAGER_DATA_MPU_ENTRIES); + + /* Reset SRD bitfield. */ + srd_bits = 0; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the data area. */ + for (i = 0; i < TXM_MODULE_MANAGER_DATA_MPU_ENTRIES; i++) + { + /* Build the base address register. */ + base_address_register = (data_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (data_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, data_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x13070000; + + /* Is there still some data? If so set the region enable bit. */ + if (data_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the data address. */ + data_address = data_address + block_size; + + /* Decrement the data size. */ + if (data_size > block_size) + { + data_size = data_size - block_size; + } + else + { + data_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + +#endif } - +#ifndef TXM_MODULE_MANAGER_8_MPU /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -537,3 +787,4 @@ ALIGN_TYPE shared_memory_address_end; return(TX_FALSE); } +#endif diff --git a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_thread_stack_build.S b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_thread_stack_build.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_thread_stack_build.S rename to ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_thread_stack_build.S diff --git a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_user_mode_entry.S b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_user_mode_entry.S similarity index 100% rename from ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_user_mode_entry.S rename to ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_user_mode_entry.S diff --git a/ports_module/cortex-m7/ac6/example_build/all.bat b/ports_module/cortex_m7/ac6/example_build/all.bat similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/all.bat rename to ports_module/cortex_m7/ac6/example_build/all.bat diff --git a/ports_module/cortex-m7/ac6/example_build/build.bat b/ports_module/cortex_m7/ac6/example_build/build.bat similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/build.bat rename to ports_module/cortex_m7/ac6/example_build/build.bat diff --git a/ports_module/cortex-m7/ac6/example_build/clean.bat b/ports_module/cortex_m7/ac6/example_build/clean.bat similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/clean.bat rename to ports_module/cortex_m7/ac6/example_build/clean.bat diff --git a/ports_module/cortex-m7/ac6/example_build/initws.bat b/ports_module/cortex_m7/ac6/example_build/initws.bat similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/initws.bat rename to ports_module/cortex_m7/ac6/example_build/initws.bat diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/.cproject b/ports_module/cortex_m7/ac6/example_build/sample_threadx/.cproject similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx/.cproject rename to ports_module/cortex_m7/ac6/example_build/sample_threadx/.cproject diff --git a/ports_module/cortex-m4/ac6/example_build/sample_threadx/.project b/ports_module/cortex_m7/ac6/example_build/sample_threadx/.project similarity index 97% rename from ports_module/cortex-m4/ac6/example_build/sample_threadx/.project rename to ports_module/cortex_m7/ac6/example_build/sample_threadx/.project index 2a6b3cb1..725328bd 100644 --- a/ports_module/cortex-m4/ac6/example_build/sample_threadx/.project +++ b/ports_module/cortex_m7/ac6/example_build/sample_threadx/.project @@ -3,7 +3,6 @@ sample_threadx - tx diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/exceptions.c b/ports_module/cortex_m7/ac6/example_build/sample_threadx/exceptions.c similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx/exceptions.c rename to ports_module/cortex_m7/ac6/example_build/sample_threadx/exceptions.c diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/sample_threadx.c b/ports_module/cortex_m7/ac6/example_build/sample_threadx/sample_threadx.c similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx/sample_threadx.c rename to ports_module/cortex_m7/ac6/example_build/sample_threadx/sample_threadx.c diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_module/cortex_m7/ac6/example_build/sample_threadx/sample_threadx.launch similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx/sample_threadx.launch rename to ports_module/cortex_m7/ac6/example_build/sample_threadx/sample_threadx.launch diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/sample_threadx.scat b/ports_module/cortex_m7/ac6/example_build/sample_threadx/sample_threadx.scat similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx/sample_threadx.scat rename to ports_module/cortex_m7/ac6/example_build/sample_threadx/sample_threadx.scat diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/tx_initialize_low_level.S b/ports_module/cortex_m7/ac6/example_build/sample_threadx/tx_initialize_low_level.S similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx/tx_initialize_low_level.S rename to ports_module/cortex_m7/ac6/example_build/sample_threadx/tx_initialize_low_level.S diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.cproject b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module/.cproject similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.cproject rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module/.cproject diff --git a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module/.project b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module/.project similarity index 97% rename from ports_module/cortex-m4/ac6/example_build/sample_threadx_module/.project rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module/.project index 5f1f1fa6..17f6aba3 100644 --- a/ports_module/cortex-m4/ac6/example_build/sample_threadx_module/.project +++ b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module/.project @@ -3,7 +3,6 @@ sample_threadx_module - txm diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/sample_threadx_module.c b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module/sample_threadx_module.c rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module/sample_threadx_module.c diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/txm_module_preamble.S b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module/txm_module_preamble.S similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module/txm_module_preamble.S rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module/txm_module_preamble.S diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.cproject b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/.cproject similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.cproject rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/.cproject diff --git a/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/.project b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/.project new file mode 100644 index 00000000..f1ca14fa --- /dev/null +++ b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/.project @@ -0,0 +1,27 @@ + + + sample_threadx_module_manager + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.arm.debug.ds.nature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/exceptions.c b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/exceptions.c similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/exceptions.c rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/exceptions.c diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch similarity index 62% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch index 6cace9e2..7b783402 100644 --- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch +++ b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch @@ -12,58 +12,58 @@ - + - + - + - + - + - + - + - + - - - + + + - + - - - - - - - + + + + + + + - + - - - + + + - - + + - + - + @@ -78,32 +78,38 @@ - + + + + - + - + - + - + + + + - + - + - + @@ -149,7 +155,7 @@ - + diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S b/ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S rename to ports_module/cortex_m7/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S diff --git a/ports_module/cortex-m7/ac6/example_build/setenv.bat b/ports_module/cortex_m7/ac6/example_build/setenv.bat similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/setenv.bat rename to ports_module/cortex_m7/ac6/example_build/setenv.bat diff --git a/ports_module/cortex-m7/ac6/example_build/tx/.cproject b/ports_module/cortex_m7/ac6/example_build/tx/.cproject similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/tx/.cproject rename to ports_module/cortex_m7/ac6/example_build/tx/.cproject diff --git a/ports_module/cortex-m7/ac6/example_build/tx/.project b/ports_module/cortex_m7/ac6/example_build/tx/.project similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/tx/.project rename to ports_module/cortex_m7/ac6/example_build/tx/.project diff --git a/ports_module/cortex-m7/ac6/example_build/txm/.cproject b/ports_module/cortex_m7/ac6/example_build/txm/.cproject similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/txm/.cproject rename to ports_module/cortex_m7/ac6/example_build/txm/.cproject diff --git a/ports_module/cortex-m7/ac6/example_build/txm/.project b/ports_module/cortex_m7/ac6/example_build/txm/.project similarity index 100% rename from ports_module/cortex-m7/ac6/example_build/txm/.project rename to ports_module/cortex_m7/ac6/example_build/txm/.project diff --git a/ports_module/cortex-m7/ac6/inc/tx_port.h b/ports_module/cortex_m7/ac6/inc/tx_port.h similarity index 100% rename from ports_module/cortex-m7/ac6/inc/tx_port.h rename to ports_module/cortex_m7/ac6/inc/tx_port.h diff --git a/ports_module/cortex-m7/ac6/inc/txm_module_port.h b/ports_module/cortex_m7/ac6/inc/txm_module_port.h similarity index 90% rename from ports_module/cortex-m7/ac6/inc/txm_module_port.h rename to ports_module/cortex_m7/ac6/inc/txm_module_port.h index 584134bb..47ec932e 100644 --- a/ports_module/cortex-m7/ac6/inc/txm_module_port.h +++ b/ports_module/cortex_m7/ac6/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-M7/MPU/AC6 */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -40,9 +40,11 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.2 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -113,7 +115,6 @@ The following extensions must also be defined in tx_port.h: #define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000 #endif - /* Define constants specific to the tools the module can be built with for this particular modules port. */ #define TXM_MODULE_IAR_COMPILER 0x00000000 @@ -168,6 +169,8 @@ The following extensions must also be defined in tx_port.h: #define INLINE_DECLARE inline +#ifndef TXM_MODULE_MANAGER_8_MPU + /* Define the number of MPU entries assigned to the code and data sections. On Cortex-M7 parts, there are 16 total entries. ThreadX uses one for access to the kernel entry function, thus 15 remain for code and data protection. */ @@ -199,6 +202,28 @@ typedef struct TXM_MODULE_MPU_INFO_STRUCT ULONG txm_module_instance_shared_memory_address[TXM_MODULE_MPU_SHARED_ENTRIES]; \ ULONG txm_module_instance_shared_memory_length[TXM_MODULE_MPU_SHARED_ENTRIES]; +#else /* TXM_MODULE_MANAGER_8_MPU is defined */ + +/* Define the number of MPU entries assigned to the code and data sections. + On Cortex-M4 parts, there are 8 total entries. ThreadX uses one for access + to the kernel entry function, thus 7 remain for code and data protection. */ +#define TXM_MODULE_MANAGER_CODE_MPU_ENTRIES 4 +#define TXM_MODULE_MANAGER_DATA_MPU_ENTRIES 3 +#define TXM_MODULE_MANAGER_SHARED_MPU_INDEX 8 +#define TXM_MODULE_MANAGER_SHARED_MPU_REGION 4 + +/* Shared memory region attributes. */ +#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1 +#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT 0x01000000 + +/* Define the port-extensions to the module manager instance structure. */ + +#define TXM_MODULE_MANAGER_PORT_EXTENSION \ + ULONG txm_module_instance_mpu_registers[16]; \ + ULONG txm_module_instance_shared_memory_address; \ + ULONG txm_module_instance_shared_memory_length; + +#endif /* TXM_MODULE_MANAGER_8_MPU */ /* Define the memory fault information structure that is populated when a memory fault occurs. */ @@ -321,8 +346,20 @@ typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT /* Define the macros to perform port-specific checks when passing pointers to the kernel. */ /* Define macro to make sure object is inside the module's data. */ +#ifndef TXM_MODULE_MANAGER_8_MPU #define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ _txm_module_manager_inside_data_check(module_instance, obj_ptr, obj_size) +#else +#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ + /* Check for overflow. */ \ + (((obj_ptr) < ((obj_ptr) + (obj_size))) && \ + /* Check if it's inside module data. */ \ + ((((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) && \ + (((obj_ptr) + (obj_size)) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1))) || \ + /* Check if it's inside shared memory. */ \ + (((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address) && \ + (((obj_ptr) + (obj_size)) <= (ALIGN_TYPE) (module_instance -> txm_module_instance_shared_memory_address + module_instance -> txm_module_instance_shared_memory_length))))) +#endif /* Define some internal prototypes to this module port. */ @@ -343,6 +380,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance #define TXM_MODULE_MANAGER_VERSION_ID \ CHAR _txm_module_manager_version_id[] = \ - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/AC6 Version 6.1.2 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/AC6 Version 6.1.7 *"; #endif diff --git a/ports_module/cortex-m7/ac6/module_lib/src/txm_module_initialize.S b/ports_module/cortex_m7/ac6/module_lib/src/txm_module_initialize.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_lib/src/txm_module_initialize.S rename to ports_module/cortex_m7/ac6/module_lib/src/txm_module_initialize.S diff --git a/ports_module/cortex-m7/ac6/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m7/ac6/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-m7/ac6/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_m7/ac6/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-m7/ac6/module_manager/src/tx_thread_context_restore.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_context_restore.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/tx_thread_context_restore.S rename to ports_module/cortex_m7/ac6/module_manager/src/tx_thread_context_restore.S diff --git a/ports_module/cortex-m7/ac6/module_manager/src/tx_thread_context_save.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_context_save.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/tx_thread_context_save.S rename to ports_module/cortex_m7/ac6/module_manager/src/tx_thread_context_save.S diff --git a/ports_module/cortex-m7/ac6/module_manager/src/tx_thread_interrupt_control.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_interrupt_control.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/tx_thread_interrupt_control.S rename to ports_module/cortex_m7/ac6/module_manager/src/tx_thread_interrupt_control.S diff --git a/ports_module/cortex-m7/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S similarity index 93% rename from ports_module/cortex-m7/ac6/module_manager/src/tx_thread_schedule.S rename to ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S index 67b30c36..a5e35116 100644 --- a/ports_module/cortex-m7/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/MPU/AC6 */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -72,11 +72,15 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), arrange */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), arrange */ /* code to fix link error when */ /* VFP is enabled, resulting */ /* in version 6.1.2 */ +/* 06-02-2021 Scott Larson Fixed extended stack handling */ +/* when calling kernel APIs, */ +/* added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -370,6 +374,7 @@ __tx_ts_restore: // Use alias registers to quickly load MPU ADD r0, r0, #100 // Build address of MPU register start in thread control block +#ifndef TXM_MODULE_MANAGER_8_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 @@ -378,6 +383,12 @@ __tx_ts_restore: 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 LDR r0, =0xE000ED94 // Build MPU control reg address MOV r1, #5 // Build enable value with background region enabled STR r1, [r0] // Enable MPU @@ -445,20 +456,24 @@ __tx_SVCallHandler: STR r0, [r2, #16] // Set stack end STR r3, [r2, #20] // Set stack size #endif - MRS r3, PSP // Pickup thread stack pointer + TST lr, #0x10 // Test for extended module stack + ITT EQ + ORREQ r3, r3, #1 // If so, set LSB in thread stack pointer to indicate extended frame + ORREQ lr, lr, #0x10 // Set bit, return with standard frame STR r3, [r2, #0xB0] // Save thread stack pointer - + BIC r3, #1 // Clear possibly OR'd bit + /* Build kernel stack by copying thread stack two registers at a time */ ADD r3, r3, #32 // Start at bottom of hardware stack - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} MSR PSP, r0 // Set kernel stack pointer @@ -495,16 +510,21 @@ _tx_thread_user_return: #endif LDR r0, [r2, #0xB0] // Load the module thread stack pointer MRS r3, PSP // Pickup kernel stack pointer + TST r0, #1 // Is module stack extended? + ITTE NE // If so... + BICNE lr, #0x10 // Clear bit, return with extended frame + BICNE r0, #1 // Clear bit that indicates extended module frame + ORREQ lr, lr, #0x10 // Else set bit, return with standard frame /* 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} + 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} SUB r0, r0, #32 // Subtract 32 to get back to top of stack MSR PSP, r0 // Set thread stack pointer diff --git a/ports_module/cortex-m7/ac6/module_manager/src/tx_thread_stack_build.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_stack_build.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/tx_thread_stack_build.S rename to ports_module/cortex_m7/ac6/module_manager/src/tx_thread_stack_build.S diff --git a/ports_module/cortex-m7/ac6/module_manager/src/tx_thread_system_return.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_system_return.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/tx_thread_system_return.S rename to ports_module/cortex_m7/ac6/module_manager/src/tx_thread_system_return.S diff --git a/ports_module/cortex-m7/ac6/module_manager/src/tx_timer_interrupt.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_timer_interrupt.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/tx_timer_interrupt.S rename to ports_module/cortex_m7/ac6/module_manager/src/tx_timer_interrupt.S diff --git a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 52% rename from ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_alignment_adjust.c index 7c39daaf..d2ac6914 100644 --- a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_alignment_adjust.c +++ b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_alignment_adjust.c @@ -94,7 +94,7 @@ ULONG _txm_power_of_two_block_size(ULONG size) /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_alignment_adjust Cortex-M7/MPU/AC6 */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -128,7 +128,9 @@ ULONG _txm_power_of_two_block_size(ULONG size) /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, @@ -137,7 +139,7 @@ VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *data_size, ULONG *data_alignment) { - +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG local_code_size; ULONG local_code_alignment; ULONG local_data_size; @@ -182,4 +184,267 @@ ULONG data_size_accum; *code_alignment = local_code_alignment; *data_size = local_data_size; *data_alignment = local_data_alignment; + +#else + +ULONG local_code_size; +ULONG local_code_alignment; +ULONG local_data_size; +ULONG local_data_alignment; +ULONG code_block_size; +ULONG data_block_size; +ULONG code_size_accum; +ULONG data_size_accum; + + /* Copy the input parameters into local variables for ease of use. */ + local_code_size = *code_size; + local_code_alignment = *code_alignment; + local_data_size = *data_size; + local_data_alignment = *data_alignment; + + + /* Test for external memory enabled in preamble. */ + if(module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS) + { + /* External/shared memory enabled. TXM_MODULE_MANAGER_CODE_MPU_ENTRIES-1 code entries will be used. */ + if (local_code_size <= (32*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32 is best. */ + code_block_size = 32; + } + else if (local_code_size <= (64*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 64 is best. */ + code_block_size = 64; + } + else if (local_code_size <= (128*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 128 is best. */ + code_block_size = 128; + } + else if (local_code_size <= (256*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 256 is best. */ + code_block_size = 256; + } + else if (local_code_size <= (512*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 512 is best. */ + code_block_size = 512; + } + else if (local_code_size <= (1024*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1024 is best. */ + code_block_size = 1024; + } + else if (local_code_size <= (2048*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2048 is best. */ + code_block_size = 2048; + } + else if (local_code_size <= (4096*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4096 is best. */ + code_block_size = 4096; + } + else if (local_code_size <= (8192*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 8192 is best. */ + code_block_size = 8192; + } + else if (local_code_size <= (16384*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 16384 is best. */ + code_block_size = 16384; + } + else if (local_code_size <= (32768*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32768 is best. */ + code_block_size = 32768; + } + else if (local_code_size <= (65536*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 65536 is best. */ + code_block_size = 65536; + } + else if (local_code_size <= (131072*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 131072 is best. */ + code_block_size = 131072; + } + else if (local_code_size <= (262144*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 262144 is best. */ + code_block_size = 262144; + } + else if (local_code_size <= (524288*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 524288 is best. */ + code_block_size = 524288; + } + else if (local_code_size <= (1048576*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1048576 is best. */ + code_block_size = 1048576; + } + else if (local_code_size <= (2097152*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2097152 is best. */ + code_block_size = 2097152; + } + else if (local_code_size <= (4194304*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4194304 is best. */ + code_block_size = 4194304; + } + else + { + /* Just set block size to 32MB just to create an allocation error! */ + code_block_size = 33554432; + } + + /* Calculate the new code size. */ + local_code_size = code_block_size*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1); + + /* Determine if the code block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (code_block_size > local_code_alignment) + local_code_alignment = code_block_size; + + } + else + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2; + code_size_accum = local_code_alignment + local_code_alignment; + code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1); + code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum); + local_code_size = code_size_accum; + } + + /* Determine the best data block size, which in our case is the minimal alignment. */ + if (local_data_size <= (32*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32 is best. */ + data_block_size = 32; + } + else if (local_data_size <= (64*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 64 is best. */ + data_block_size = 64; + } + else if (local_data_size <= (128*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 128 is best. */ + data_block_size = 128; + } + else if (local_data_size <= (256*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 256 is best. */ + data_block_size = 256; + } + else if (local_data_size <= (512*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 512 is best. */ + data_block_size = 512; + } + else if (local_data_size <= (1024*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1024 is best. */ + data_block_size = 1024; + } + else if (local_data_size <= (2048*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2048 is best. */ + data_block_size = 2048; + } + else if (local_data_size <= (4096*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4096 is best. */ + data_block_size = 4096; + } + else if (local_data_size <= (8192*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 8192 is best. */ + data_block_size = 8192; + } + else if (local_data_size <= (16384*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 16384 is best. */ + data_block_size = 16384; + } + else if (local_data_size <= (32768*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32768 is best. */ + data_block_size = 32768; + } + else if (local_data_size <= (65536*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 65536 is best. */ + data_block_size = 65536; + } + else if (local_data_size <= (131072*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 131072 is best. */ + data_block_size = 131072; + } + else if (local_data_size <= (262144*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 262144 is best. */ + data_block_size = 262144; + } + else if (local_data_size <= (524288*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 524288 is best. */ + data_block_size = 524288; + } + else if (local_data_size <= (1048576*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1048576 is best. */ + data_block_size = 1048576; + } + else if (local_data_size <= (2097152*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2097152 is best. */ + data_block_size = 2097152; + } + else if (local_data_size <= (4194304*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4194304 is best. */ + data_block_size = 4194304; + } + else + { + /* Just set data block size to 32MB just to create an allocation error! */ + data_block_size = 33554432; + } + + /* Calculate the new data size. */ + data_size_accum = data_block_size; + while(data_size_accum < local_data_size) + { + data_size_accum += data_block_size; + } + local_data_size = data_size_accum; + + /* Determine if the data block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (data_block_size > local_data_alignment) + { + local_data_alignment = data_block_size; + } + + /* Return all the information to the caller. */ + *code_size = local_code_size; + *code_alignment = local_code_alignment; + *data_size = local_data_size; + *data_alignment = local_data_alignment; + +#endif } diff --git a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 69% rename from ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_external_memory_enable.c index 8eaf2833..6c9106ce 100644 --- a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_external_memory_enable.c +++ b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_external_memory_enable.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_external_memory_enable Cortex-M7/MPU/AC6 */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -69,7 +69,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in verison 6.1.7 */ /* */ /**************************************************************************/ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance, @@ -77,7 +79,7 @@ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_ins ULONG length, UINT attributes) { - +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG block_size; ULONG region_size; ULONG srd_bits; @@ -186,4 +188,109 @@ ULONG attributes_check = 0; /* Return success. */ return(TX_SUCCESS); + +#else + +ULONG block_size; +ULONG region_size; +ULONG subregion_bits; +ULONG address; +UINT attributes_check = 0; +TXM_MODULE_PREAMBLE *module_preamble; + + /* Determine if the module manager has not been initialized yet. */ + if (_txm_module_manager_ready != TX_TRUE) + { + /* Module manager has not been initialized. */ + return(TX_NOT_AVAILABLE); + } + + /* Determine if the module is valid. */ + if (module_instance == TX_NULL) + { + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Get module manager protection mutex. */ + _tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER); + + /* Determine if the module instance is valid. */ + if (module_instance -> txm_module_instance_id != TXM_MODULE_ID) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Determine if the module instance is in the loaded state. */ + if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if the module is not ready. */ + return(TX_START_ERROR); + } + + /* Check if preamble shared mem and mem protection property bits are set. */ + module_preamble = module_instance -> txm_module_instance_preamble_ptr; + if((module_preamble -> txm_module_preamble_property_flags & (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + != (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if bit not set. */ + return(TXM_MODULE_INVALID_PROPERTIES); + } + + /* Start address and length must adhere to Cortex-M MPU. + The address must align with the block size. */ + + block_size = _txm_power_of_two_block_size(length); + address = (ULONG) start_address; + if(address != (address & ~(block_size - 1))) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return alignment error. */ + return(TXM_MODULE_ALIGNMENT_ERROR); + } + + /* At this point, we have a valid address and block size. + Set up MPU registers. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] = address | TXM_MODULE_MANAGER_SHARED_MPU_REGION | 0x10; + + /* Calculate the region size. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + /* Calculate the subregion bits. */ + subregion_bits = _txm_module_manager_calculate_srd_bits(block_size, length); + + /* Check for valid attributes. */ + if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE) + { + attributes_check = TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT; + } + + /* Build register with attributes. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX+1] = region_size | subregion_bits | attributes_check | 0x12070001; + + /* Keep track of shared memory address and length in module instance. */ + module_instance -> txm_module_instance_shared_memory_address = address; + module_instance -> txm_module_instance_shared_memory_length = length; + + /* Recalculate MPU settings. */ + _txm_module_manager_mm_register_setup(module_instance); + + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return success. */ + return(TX_SUCCESS); + +#endif } diff --git a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 71% rename from ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c index 359b628b..ec9e6ba4 100644 --- a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c +++ b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c @@ -231,7 +231,7 @@ UINT srd_bit_index; /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_mm_register_setup Cortex-M7/MPU/AC6 */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -259,6 +259,7 @@ UINT srd_bit_index; /* 14 Unused region */ /* 15 Unused region */ /* */ +/* If TXM_MODULE_MANAGER_8_MPU is defined, there are only 8 MPU slots. */ /* */ /* INPUT */ /* */ @@ -280,11 +281,14 @@ UINT srd_bit_index; /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance) { +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG code_address; ULONG code_size; @@ -452,10 +456,256 @@ UINT i; /* Increment MPU table index. */ mpu_table_index++; } + +#else + +ULONG code_address; +ULONG code_size; +ULONG data_address; +ULONG data_size; +ULONG start_stop_stack_size; +ULONG callback_stack_size; +ULONG block_size; +ULONG base_address_register; +ULONG base_attribute_register; +ULONG region_size; +ULONG srd_bits = 0; +UINT mpu_register = 0; +UINT mpu_table_index; +UINT i; + + + /* Setup the first region for the ThreadX trampoline code. */ + /* Set base register to user mode entry, which is guaranteed to be at least 32-byte aligned. */ + base_address_register = (ULONG) _txm_module_manager_user_mode_entry; + /* Mask address to proper range, region 0, set Valid bit. */ + base_address_register = (base_address_register & 0xFFFFFFE0) | mpu_register | 0x10; + module_instance -> txm_module_instance_mpu_registers[0] = base_address_register; + + /* Attributes: read only, write-back, shareable, size 32 bytes, region enabled. */ + module_instance -> txm_module_instance_mpu_registers[1] = 0x06070009; + + /* Initialize the MPU register. */ + mpu_register = 1; + + /* Initialize the MPU table index. */ + mpu_table_index = 2; + + /* Setup values for code area. */ + code_address = (ULONG) module_instance -> txm_module_instance_code_start; + code_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_code_size; + + /* Check if shared memory was set up. If so, only 3 entries are available for + code protection. If not set up, 4 code entries are available. */ + if(module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] == 0) + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES; i++) + { + /* First two MPU blocks are 1/4 of the largest power of two + that is greater than or equal to code size. */ + if (i < 2) + { + block_size = _txm_power_of_two_block_size(code_size) >> 2; + } + + /* Third MPU block is the largest power of 2 that fits in the remaining space. */ + else if (i == 2) + { + /* Subtract (block_size*2) from code_size to calculate remaining space. */ + code_size = code_size - (block_size << 1); + block_size = _txm_power_of_two_block_size(code_size) >> 1; + } + + /* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */ + else + { + /* Calculate remaining space. */ + code_size = code_size - block_size; + block_size = _txm_power_of_two_block_size(code_size); + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base address register. */ + base_address_register = (code_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070001; + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + } + + /* Only 3 code entries available. */ + else + { + /* Calculate block size, one code entry taken up by shared memory. */ + block_size = _txm_power_of_two_block_size(code_size / (TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)); + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1; i++) + { + /* Build the base address register. */ + base_address_register = code_address & ~(block_size - 1) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (code_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070000; + + /* Is there still some code? If so set the region enable bit. */ + if (code_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Decrement the code size. */ + if (code_size > block_size) + { + code_size = code_size - block_size; + } + else + { + code_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Adjust indeces to pass over the shared memory entry. */ + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Setup values for data area. */ + data_address = (ULONG) module_instance -> txm_module_instance_data_start; + + /* Adjust the size of the module elements to be aligned to the default alignment. We do this + so that when we partition the allocated memory, we can simply place these regions right beside + each other without having to align their pointers. Note this only works when they all have + the same alignment. */ + + data_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_data_size; + start_stop_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_start_stop_stack_size; + callback_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_callback_stack_size; + + data_size = ((data_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + start_stop_stack_size = ((start_stop_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + callback_stack_size = ((callback_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + /* Update the data size to include thread stacks. */ + data_size = data_size + start_stop_stack_size + callback_stack_size; + + block_size = _txm_power_of_two_block_size(data_size / TXM_MODULE_MANAGER_DATA_MPU_ENTRIES); + + /* Reset SRD bitfield. */ + srd_bits = 0; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the data area. */ + for (i = 0; i < TXM_MODULE_MANAGER_DATA_MPU_ENTRIES; i++) + { + /* Build the base address register. */ + base_address_register = (data_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (data_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, data_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x13070000; + + /* Is there still some data? If so set the region enable bit. */ + if (data_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the data address. */ + data_address = data_address + block_size; + + /* Decrement the data size. */ + if (data_size > block_size) + { + data_size = data_size - block_size; + } + else + { + data_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + +#endif } - +#ifndef TXM_MODULE_MANAGER_8_MPU /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -537,3 +787,4 @@ ALIGN_TYPE shared_memory_address_end; return(TX_FALSE); } +#endif diff --git a/ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_thread_stack_build.S b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_thread_stack_build.S similarity index 100% rename from ports_module/cortex-m7/ac6/module_manager/src/txm_module_manager_thread_stack_build.S rename to ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_thread_stack_build.S diff --git a/ports_module/cortex-m7/gnu/example_build/build_all.bat b/ports_module/cortex_m7/gnu/example_build/build_all.bat similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/build_all.bat rename to ports_module/cortex_m7/gnu/example_build/build_all.bat diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx.bat b/ports_module/cortex_m7/gnu/example_build/build_threadx.bat similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/build_threadx.bat rename to ports_module/cortex_m7/gnu/example_build/build_threadx.bat diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx_module_library.bat b/ports_module/cortex_m7/gnu/example_build/build_threadx_module_library.bat similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/build_threadx_module_library.bat rename to ports_module/cortex_m7/gnu/example_build/build_threadx_module_library.bat diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx_module_manager_sample.bat b/ports_module/cortex_m7/gnu/example_build/build_threadx_module_manager_sample.bat similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/build_threadx_module_manager_sample.bat rename to ports_module/cortex_m7/gnu/example_build/build_threadx_module_manager_sample.bat diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx_module_sample.bat b/ports_module/cortex_m7/gnu/example_build/build_threadx_module_sample.bat similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/build_threadx_module_sample.bat rename to ports_module/cortex_m7/gnu/example_build/build_threadx_module_sample.bat diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx_sample.bat b/ports_module/cortex_m7/gnu/example_build/build_threadx_sample.bat similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/build_threadx_sample.bat rename to ports_module/cortex_m7/gnu/example_build/build_threadx_sample.bat diff --git a/ports_module/cortex-m7/gnu/example_build/cortexm_crt0.s b/ports_module/cortex_m7/gnu/example_build/cortexm_crt0.s similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/cortexm_crt0.s rename to ports_module/cortex_m7/gnu/example_build/cortexm_crt0.s diff --git a/ports_module/cortex-m7/gnu/example_build/gcc_setup.s b/ports_module/cortex_m7/gnu/example_build/gcc_setup.s similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/gcc_setup.s rename to ports_module/cortex_m7/gnu/example_build/gcc_setup.s diff --git a/ports_module/cortex-m7/gnu/example_build/sample_threadx.ld b/ports_module/cortex_m7/gnu/example_build/sample_threadx.ld similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/sample_threadx.ld rename to ports_module/cortex_m7/gnu/example_build/sample_threadx.ld diff --git a/ports_module/cortex-m7/gnu/example_build/sample_threadx_module.c b/ports_module/cortex_m7/gnu/example_build/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/sample_threadx_module.c rename to ports_module/cortex_m7/gnu/example_build/sample_threadx_module.c diff --git a/ports_module/cortex-m7/gnu/example_build/sample_threadx_module.ld b/ports_module/cortex_m7/gnu/example_build/sample_threadx_module.ld similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/sample_threadx_module.ld rename to ports_module/cortex_m7/gnu/example_build/sample_threadx_module.ld diff --git a/ports_module/cortex-m7/gnu/example_build/sample_threadx_module_manager.c b/ports_module/cortex_m7/gnu/example_build/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/sample_threadx_module_manager.c rename to ports_module/cortex_m7/gnu/example_build/sample_threadx_module_manager.c diff --git a/ports_module/cortex-m7/gnu/example_build/tx_initialize_low_level.S b/ports_module/cortex_m7/gnu/example_build/tx_initialize_low_level.S similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/tx_initialize_low_level.S rename to ports_module/cortex_m7/gnu/example_build/tx_initialize_low_level.S diff --git a/ports_module/cortex-m7/gnu/example_build/tx_simulator_startup.s b/ports_module/cortex_m7/gnu/example_build/tx_simulator_startup.s similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/tx_simulator_startup.s rename to ports_module/cortex_m7/gnu/example_build/tx_simulator_startup.s diff --git a/ports_module/cortex-m7/gnu/example_build/txm_module_preamble.S b/ports_module/cortex_m7/gnu/example_build/txm_module_preamble.S similarity index 100% rename from ports_module/cortex-m7/gnu/example_build/txm_module_preamble.S rename to ports_module/cortex_m7/gnu/example_build/txm_module_preamble.S diff --git a/ports_module/cortex-m7/gnu/inc/tx_port.h b/ports_module/cortex_m7/gnu/inc/tx_port.h similarity index 100% rename from ports_module/cortex-m7/gnu/inc/tx_port.h rename to ports_module/cortex_m7/gnu/inc/tx_port.h diff --git a/ports_module/cortex-m7/gnu/inc/txm_module_port.h b/ports_module/cortex_m7/gnu/inc/txm_module_port.h similarity index 90% rename from ports_module/cortex-m7/gnu/inc/txm_module_port.h rename to ports_module/cortex_m7/gnu/inc/txm_module_port.h index 4c883ddb..8040d77c 100644 --- a/ports_module/cortex-m7/gnu/inc/txm_module_port.h +++ b/ports_module/cortex_m7/gnu/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-M7/MPU/GNU */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -40,9 +40,11 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), */ /* resulting in version 6.1.2 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -167,6 +169,8 @@ The following extensions must also be defined in tx_port.h: #define INLINE_DECLARE inline +#ifndef TXM_MODULE_MANAGER_8_MPU + /* Define the number of MPU entries assigned to the code and data sections. On Cortex-M7 parts, there are 16 total entries. ThreadX uses one for access to the kernel entry function, thus 15 remain for code and data protection. */ @@ -198,6 +202,28 @@ typedef struct TXM_MODULE_MPU_INFO_STRUCT ULONG txm_module_instance_shared_memory_address[TXM_MODULE_MPU_SHARED_ENTRIES]; \ ULONG txm_module_instance_shared_memory_length[TXM_MODULE_MPU_SHARED_ENTRIES]; +#else /* TXM_MODULE_MANAGER_8_MPU is defined */ + +/* Define the number of MPU entries assigned to the code and data sections. + On Cortex-M4 parts, there are 8 total entries. ThreadX uses one for access + to the kernel entry function, thus 7 remain for code and data protection. */ +#define TXM_MODULE_MANAGER_CODE_MPU_ENTRIES 4 +#define TXM_MODULE_MANAGER_DATA_MPU_ENTRIES 3 +#define TXM_MODULE_MANAGER_SHARED_MPU_INDEX 8 +#define TXM_MODULE_MANAGER_SHARED_MPU_REGION 4 + +/* Shared memory region attributes. */ +#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1 +#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT 0x01000000 + +/* Define the port-extensions to the module manager instance structure. */ + +#define TXM_MODULE_MANAGER_PORT_EXTENSION \ + ULONG txm_module_instance_mpu_registers[16]; \ + ULONG txm_module_instance_shared_memory_address; \ + ULONG txm_module_instance_shared_memory_length; + +#endif /* TXM_MODULE_MANAGER_8_MPU */ /* Define the memory fault information structure that is populated when a memory fault occurs. */ @@ -320,8 +346,20 @@ typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT /* Define the macros to perform port-specific checks when passing pointers to the kernel. */ /* Define macro to make sure object is inside the module's data. */ +#ifndef TXM_MODULE_MANAGER_8_MPU #define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ _txm_module_manager_inside_data_check(module_instance, obj_ptr, obj_size) +#else +#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ + /* Check for overflow. */ \ + (((obj_ptr) < ((obj_ptr) + (obj_size))) && \ + /* Check if it's inside module data. */ \ + ((((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) && \ + (((obj_ptr) + (obj_size)) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1))) || \ + /* Check if it's inside shared memory. */ \ + (((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address) && \ + (((obj_ptr) + (obj_size)) <= (ALIGN_TYPE) (module_instance -> txm_module_instance_shared_memory_address + module_instance -> txm_module_instance_shared_memory_length))))) +#endif /* Define some internal prototypes to this module port. */ @@ -342,6 +380,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance #define TXM_MODULE_MANAGER_VERSION_ID \ CHAR _txm_module_manager_version_id[] = \ - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/GNU Version 6.1.2 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/GNU Version 6.1.7 *"; #endif diff --git a/ports_module/cortex-m7/gnu/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m7/gnu/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-m7/gnu/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_m7/gnu/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-m7/gnu/module_manager/src/tx_thread_context_restore.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_context_restore.S similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/tx_thread_context_restore.S rename to ports_module/cortex_m7/gnu/module_manager/src/tx_thread_context_restore.S diff --git a/ports_module/cortex-m7/gnu/module_manager/src/tx_thread_context_save.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_context_save.S similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/tx_thread_context_save.S rename to ports_module/cortex_m7/gnu/module_manager/src/tx_thread_context_save.S diff --git a/ports_module/cortex-m7/gnu/module_manager/src/tx_thread_interrupt_control.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_interrupt_control.S similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/tx_thread_interrupt_control.S rename to ports_module/cortex_m7/gnu/module_manager/src/tx_thread_interrupt_control.S diff --git a/ports_module/cortex-m7/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S similarity index 93% rename from ports_module/cortex-m7/gnu/module_manager/src/tx_thread_schedule.S rename to ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S index 8f821bf0..909d7449 100644 --- a/ports_module/cortex-m7/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/MPU/GNU */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -70,11 +70,15 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), arrange */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), arrange */ /* code to fix link error when */ /* VFP is enabled, resulting */ /* in version 6.1.2 */ +/* 06-02-2021 Scott Larson Fixed extended stack handling */ +/* when calling kernel APIs, */ +/* added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -368,6 +372,7 @@ __tx_ts_restore: // Use alias registers to quickly load MPU ADD r0, r0, #100 // Build address of MPU register start in thread control block +#ifndef TXM_MODULE_MANAGER_8_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 @@ -376,6 +381,12 @@ __tx_ts_restore: 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 LDR r0, =0xE000ED94 // Build MPU control reg address MOV r1, #5 // Build enable value with background region enabled STR r1, [r0] // Enable MPU @@ -444,20 +455,24 @@ __tx_SVCallHandler: STR r0, [r2, #16] // Set stack end STR r3, [r2, #20] // Set stack size #endif - MRS r3, PSP // Pickup thread stack pointer + TST lr, #0x10 // Test for extended module stack + ITT EQ + ORREQ r3, r3, #1 // If so, set LSB in thread stack pointer to indicate extended frame + ORREQ lr, lr, #0x10 // Set bit, return with standard frame STR r3, [r2, #0xB0] // Save thread stack pointer - + BIC r3, #1 // Clear possibly OR'd bit + /* Build kernel stack by copying thread stack two registers at a time */ ADD r3, r3, #32 // Start at bottom of hardware stack - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} MSR PSP, r0 // Set kernel stack pointer @@ -494,16 +509,21 @@ _tx_thread_user_return: #endif LDR r0, [r2, #0xB0] // Load the module thread stack pointer MRS r3, PSP // Pickup kernel stack pointer + TST r0, #1 // Is module stack extended? + ITTE NE // If so... + BICNE lr, #0x10 // Clear bit, return with extended frame + BICNE r0, #1 // Clear bit that indicates extended module frame + ORREQ lr, lr, #0x10 // Else set bit, return with standard frame /* 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} + 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} SUB r0, r0, #32 // Subtract 32 to get back to top of stack MSR PSP, r0 // Set thread stack pointer diff --git a/ports_module/cortex-m7/gnu/module_manager/src/tx_thread_stack_build.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_stack_build.S similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/tx_thread_stack_build.S rename to ports_module/cortex_m7/gnu/module_manager/src/tx_thread_stack_build.S diff --git a/ports_module/cortex-m7/gnu/module_manager/src/tx_thread_system_return.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_system_return.S similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/tx_thread_system_return.S rename to ports_module/cortex_m7/gnu/module_manager/src/tx_thread_system_return.S diff --git a/ports_module/cortex-m7/gnu/module_manager/src/tx_timer_interrupt.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_timer_interrupt.S similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/tx_timer_interrupt.S rename to ports_module/cortex_m7/gnu/module_manager/src/tx_timer_interrupt.S diff --git a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 52% rename from ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_alignment_adjust.c index 611ad89e..64efbff0 100644 --- a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_alignment_adjust.c +++ b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_alignment_adjust.c @@ -94,7 +94,7 @@ ULONG _txm_power_of_two_block_size(ULONG size) /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_alignment_adjust Cortex-M7/MPU/GNU */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -128,7 +128,9 @@ ULONG _txm_power_of_two_block_size(ULONG size) /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, @@ -137,7 +139,7 @@ VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *data_size, ULONG *data_alignment) { - +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG local_code_size; ULONG local_code_alignment; ULONG local_data_size; @@ -182,4 +184,267 @@ ULONG data_size_accum; *code_alignment = local_code_alignment; *data_size = local_data_size; *data_alignment = local_data_alignment; + +#else + +ULONG local_code_size; +ULONG local_code_alignment; +ULONG local_data_size; +ULONG local_data_alignment; +ULONG code_block_size; +ULONG data_block_size; +ULONG code_size_accum; +ULONG data_size_accum; + + /* Copy the input parameters into local variables for ease of use. */ + local_code_size = *code_size; + local_code_alignment = *code_alignment; + local_data_size = *data_size; + local_data_alignment = *data_alignment; + + + /* Test for external memory enabled in preamble. */ + if(module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS) + { + /* External/shared memory enabled. TXM_MODULE_MANAGER_CODE_MPU_ENTRIES-1 code entries will be used. */ + if (local_code_size <= (32*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32 is best. */ + code_block_size = 32; + } + else if (local_code_size <= (64*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 64 is best. */ + code_block_size = 64; + } + else if (local_code_size <= (128*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 128 is best. */ + code_block_size = 128; + } + else if (local_code_size <= (256*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 256 is best. */ + code_block_size = 256; + } + else if (local_code_size <= (512*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 512 is best. */ + code_block_size = 512; + } + else if (local_code_size <= (1024*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1024 is best. */ + code_block_size = 1024; + } + else if (local_code_size <= (2048*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2048 is best. */ + code_block_size = 2048; + } + else if (local_code_size <= (4096*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4096 is best. */ + code_block_size = 4096; + } + else if (local_code_size <= (8192*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 8192 is best. */ + code_block_size = 8192; + } + else if (local_code_size <= (16384*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 16384 is best. */ + code_block_size = 16384; + } + else if (local_code_size <= (32768*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32768 is best. */ + code_block_size = 32768; + } + else if (local_code_size <= (65536*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 65536 is best. */ + code_block_size = 65536; + } + else if (local_code_size <= (131072*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 131072 is best. */ + code_block_size = 131072; + } + else if (local_code_size <= (262144*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 262144 is best. */ + code_block_size = 262144; + } + else if (local_code_size <= (524288*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 524288 is best. */ + code_block_size = 524288; + } + else if (local_code_size <= (1048576*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1048576 is best. */ + code_block_size = 1048576; + } + else if (local_code_size <= (2097152*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2097152 is best. */ + code_block_size = 2097152; + } + else if (local_code_size <= (4194304*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4194304 is best. */ + code_block_size = 4194304; + } + else + { + /* Just set block size to 32MB just to create an allocation error! */ + code_block_size = 33554432; + } + + /* Calculate the new code size. */ + local_code_size = code_block_size*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1); + + /* Determine if the code block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (code_block_size > local_code_alignment) + local_code_alignment = code_block_size; + + } + else + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2; + code_size_accum = local_code_alignment + local_code_alignment; + code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1); + code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum); + local_code_size = code_size_accum; + } + + /* Determine the best data block size, which in our case is the minimal alignment. */ + if (local_data_size <= (32*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32 is best. */ + data_block_size = 32; + } + else if (local_data_size <= (64*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 64 is best. */ + data_block_size = 64; + } + else if (local_data_size <= (128*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 128 is best. */ + data_block_size = 128; + } + else if (local_data_size <= (256*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 256 is best. */ + data_block_size = 256; + } + else if (local_data_size <= (512*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 512 is best. */ + data_block_size = 512; + } + else if (local_data_size <= (1024*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1024 is best. */ + data_block_size = 1024; + } + else if (local_data_size <= (2048*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2048 is best. */ + data_block_size = 2048; + } + else if (local_data_size <= (4096*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4096 is best. */ + data_block_size = 4096; + } + else if (local_data_size <= (8192*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 8192 is best. */ + data_block_size = 8192; + } + else if (local_data_size <= (16384*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 16384 is best. */ + data_block_size = 16384; + } + else if (local_data_size <= (32768*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32768 is best. */ + data_block_size = 32768; + } + else if (local_data_size <= (65536*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 65536 is best. */ + data_block_size = 65536; + } + else if (local_data_size <= (131072*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 131072 is best. */ + data_block_size = 131072; + } + else if (local_data_size <= (262144*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 262144 is best. */ + data_block_size = 262144; + } + else if (local_data_size <= (524288*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 524288 is best. */ + data_block_size = 524288; + } + else if (local_data_size <= (1048576*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1048576 is best. */ + data_block_size = 1048576; + } + else if (local_data_size <= (2097152*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2097152 is best. */ + data_block_size = 2097152; + } + else if (local_data_size <= (4194304*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4194304 is best. */ + data_block_size = 4194304; + } + else + { + /* Just set data block size to 32MB just to create an allocation error! */ + data_block_size = 33554432; + } + + /* Calculate the new data size. */ + data_size_accum = data_block_size; + while(data_size_accum < local_data_size) + { + data_size_accum += data_block_size; + } + local_data_size = data_size_accum; + + /* Determine if the data block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (data_block_size > local_data_alignment) + { + local_data_alignment = data_block_size; + } + + /* Return all the information to the caller. */ + *code_size = local_code_size; + *code_alignment = local_code_alignment; + *data_size = local_data_size; + *data_alignment = local_data_alignment; + +#endif } diff --git a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 69% rename from ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_external_memory_enable.c index e2e7698d..24b0fa4b 100644 --- a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_external_memory_enable.c +++ b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_external_memory_enable.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_external_memory_enable Cortex-M7/MPU/GNU */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -69,7 +69,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in verison 6.1.7 */ /* */ /**************************************************************************/ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance, @@ -77,7 +79,7 @@ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_ins ULONG length, UINT attributes) { - +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG block_size; ULONG region_size; ULONG srd_bits; @@ -186,4 +188,109 @@ ULONG attributes_check = 0; /* Return success. */ return(TX_SUCCESS); + +#else + +ULONG block_size; +ULONG region_size; +ULONG subregion_bits; +ULONG address; +UINT attributes_check = 0; +TXM_MODULE_PREAMBLE *module_preamble; + + /* Determine if the module manager has not been initialized yet. */ + if (_txm_module_manager_ready != TX_TRUE) + { + /* Module manager has not been initialized. */ + return(TX_NOT_AVAILABLE); + } + + /* Determine if the module is valid. */ + if (module_instance == TX_NULL) + { + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Get module manager protection mutex. */ + _tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER); + + /* Determine if the module instance is valid. */ + if (module_instance -> txm_module_instance_id != TXM_MODULE_ID) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Determine if the module instance is in the loaded state. */ + if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if the module is not ready. */ + return(TX_START_ERROR); + } + + /* Check if preamble shared mem and mem protection property bits are set. */ + module_preamble = module_instance -> txm_module_instance_preamble_ptr; + if((module_preamble -> txm_module_preamble_property_flags & (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + != (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if bit not set. */ + return(TXM_MODULE_INVALID_PROPERTIES); + } + + /* Start address and length must adhere to Cortex-M MPU. + The address must align with the block size. */ + + block_size = _txm_power_of_two_block_size(length); + address = (ULONG) start_address; + if(address != (address & ~(block_size - 1))) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return alignment error. */ + return(TXM_MODULE_ALIGNMENT_ERROR); + } + + /* At this point, we have a valid address and block size. + Set up MPU registers. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] = address | TXM_MODULE_MANAGER_SHARED_MPU_REGION | 0x10; + + /* Calculate the region size. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + /* Calculate the subregion bits. */ + subregion_bits = _txm_module_manager_calculate_srd_bits(block_size, length); + + /* Check for valid attributes. */ + if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE) + { + attributes_check = TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT; + } + + /* Build register with attributes. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX+1] = region_size | subregion_bits | attributes_check | 0x12070001; + + /* Keep track of shared memory address and length in module instance. */ + module_instance -> txm_module_instance_shared_memory_address = address; + module_instance -> txm_module_instance_shared_memory_length = length; + + /* Recalculate MPU settings. */ + _txm_module_manager_mm_register_setup(module_instance); + + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return success. */ + return(TX_SUCCESS); + +#endif } diff --git a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 71% rename from ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c index da7187ba..7460ad0c 100644 --- a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c +++ b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c @@ -231,7 +231,7 @@ UINT srd_bit_index; /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_mm_register_setup Cortex-M7/MPU/GNU */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -259,6 +259,7 @@ UINT srd_bit_index; /* 14 Unused region */ /* 15 Unused region */ /* */ +/* If TXM_MODULE_MANAGER_8_MPU is defined, there are only 8 MPU slots. */ /* */ /* INPUT */ /* */ @@ -280,11 +281,14 @@ UINT srd_bit_index; /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance) { +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG code_address; ULONG code_size; @@ -452,10 +456,256 @@ UINT i; /* Increment MPU table index. */ mpu_table_index++; } + +#else + +ULONG code_address; +ULONG code_size; +ULONG data_address; +ULONG data_size; +ULONG start_stop_stack_size; +ULONG callback_stack_size; +ULONG block_size; +ULONG base_address_register; +ULONG base_attribute_register; +ULONG region_size; +ULONG srd_bits = 0; +UINT mpu_register = 0; +UINT mpu_table_index; +UINT i; + + + /* Setup the first region for the ThreadX trampoline code. */ + /* Set base register to user mode entry, which is guaranteed to be at least 32-byte aligned. */ + base_address_register = (ULONG) _txm_module_manager_user_mode_entry; + /* Mask address to proper range, region 0, set Valid bit. */ + base_address_register = (base_address_register & 0xFFFFFFE0) | mpu_register | 0x10; + module_instance -> txm_module_instance_mpu_registers[0] = base_address_register; + + /* Attributes: read only, write-back, shareable, size 32 bytes, region enabled. */ + module_instance -> txm_module_instance_mpu_registers[1] = 0x06070009; + + /* Initialize the MPU register. */ + mpu_register = 1; + + /* Initialize the MPU table index. */ + mpu_table_index = 2; + + /* Setup values for code area. */ + code_address = (ULONG) module_instance -> txm_module_instance_code_start; + code_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_code_size; + + /* Check if shared memory was set up. If so, only 3 entries are available for + code protection. If not set up, 4 code entries are available. */ + if(module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] == 0) + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES; i++) + { + /* First two MPU blocks are 1/4 of the largest power of two + that is greater than or equal to code size. */ + if (i < 2) + { + block_size = _txm_power_of_two_block_size(code_size) >> 2; + } + + /* Third MPU block is the largest power of 2 that fits in the remaining space. */ + else if (i == 2) + { + /* Subtract (block_size*2) from code_size to calculate remaining space. */ + code_size = code_size - (block_size << 1); + block_size = _txm_power_of_two_block_size(code_size) >> 1; + } + + /* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */ + else + { + /* Calculate remaining space. */ + code_size = code_size - block_size; + block_size = _txm_power_of_two_block_size(code_size); + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base address register. */ + base_address_register = (code_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070001; + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + } + + /* Only 3 code entries available. */ + else + { + /* Calculate block size, one code entry taken up by shared memory. */ + block_size = _txm_power_of_two_block_size(code_size / (TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)); + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1; i++) + { + /* Build the base address register. */ + base_address_register = code_address & ~(block_size - 1) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (code_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070000; + + /* Is there still some code? If so set the region enable bit. */ + if (code_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Decrement the code size. */ + if (code_size > block_size) + { + code_size = code_size - block_size; + } + else + { + code_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Adjust indeces to pass over the shared memory entry. */ + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Setup values for data area. */ + data_address = (ULONG) module_instance -> txm_module_instance_data_start; + + /* Adjust the size of the module elements to be aligned to the default alignment. We do this + so that when we partition the allocated memory, we can simply place these regions right beside + each other without having to align their pointers. Note this only works when they all have + the same alignment. */ + + data_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_data_size; + start_stop_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_start_stop_stack_size; + callback_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_callback_stack_size; + + data_size = ((data_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + start_stop_stack_size = ((start_stop_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + callback_stack_size = ((callback_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + /* Update the data size to include thread stacks. */ + data_size = data_size + start_stop_stack_size + callback_stack_size; + + block_size = _txm_power_of_two_block_size(data_size / TXM_MODULE_MANAGER_DATA_MPU_ENTRIES); + + /* Reset SRD bitfield. */ + srd_bits = 0; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the data area. */ + for (i = 0; i < TXM_MODULE_MANAGER_DATA_MPU_ENTRIES; i++) + { + /* Build the base address register. */ + base_address_register = (data_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (data_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, data_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x13070000; + + /* Is there still some data? If so set the region enable bit. */ + if (data_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the data address. */ + data_address = data_address + block_size; + + /* Decrement the data size. */ + if (data_size > block_size) + { + data_size = data_size - block_size; + } + else + { + data_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + +#endif } - +#ifndef TXM_MODULE_MANAGER_8_MPU /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -537,3 +787,4 @@ ALIGN_TYPE shared_memory_address_end; return(TX_FALSE); } +#endif diff --git a/ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_thread_stack_build.s b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_thread_stack_build.s similarity index 100% rename from ports_module/cortex-m7/gnu/module_manager/src/txm_module_manager_thread_stack_build.s rename to ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_thread_stack_build.s diff --git a/ports_module/cortex-m7/iar/example_build/azure_rtos.eww b/ports_module/cortex_m7/iar/example_build/azure_rtos.eww similarity index 100% rename from ports_module/cortex-m7/iar/example_build/azure_rtos.eww rename to ports_module/cortex_m7/iar/example_build/azure_rtos.eww diff --git a/ports_module/cortex-m7/iar/example_build/cstartup_M.s b/ports_module/cortex_m7/iar/example_build/cstartup_M.s similarity index 100% rename from ports_module/cortex-m7/iar/example_build/cstartup_M.s rename to ports_module/cortex_m7/iar/example_build/cstartup_M.s diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/board.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/board.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/board.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/board.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/bmp.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/bmp.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/bmp.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/bmp.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/board_lowlevel.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/board_lowlevel.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/board_lowlevel.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/board_lowlevel.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/board_memories.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/board_memories.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/board_memories.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/board_memories.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/cs2100.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/cs2100.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/cs2100.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/cs2100.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/dbg_console.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/dbg_console.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/dbg_console.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/dbg_console.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/frame_buffer.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/frame_buffer.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/frame_buffer.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/frame_buffer.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/gmacb_phy.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/gmacb_phy.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/gmacb_phy.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/gmacb_phy.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/gmii.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/gmii.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/gmii.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/gmii.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_ebi_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_reg.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_reg.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_reg.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_reg.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/ili9488_spi_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/image_sensor_inf.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/image_sensor_inf.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/image_sensor_inf.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/image_sensor_inf.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_color.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_color.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_color.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_color.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_draw.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_draw.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_draw.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_draw.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font10x14.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font10x14.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font10x14.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_font10x14.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_gimp_image.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_gimp_image.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_gimp_image.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcd_gimp_image.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcdd.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcdd.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/lcdd.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/lcdd.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/led.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/led.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/led.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/led.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/math.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/math.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/math.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/math.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/mcan_config.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/mcan_config.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/mcan_config.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/mcan_config.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/rtc_calib.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/rtc_calib.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/rtc_calib.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/rtc_calib.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/s25fl1.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/s25fl1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/s25fl1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/s25fl1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/syscalls.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/syscalls.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/syscalls.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/syscalls.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/wm8904.h b/ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/wm8904.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libboard_samv7-ek/include/wm8904.h rename to ports_module/cortex_m7/iar/example_build/libraries/libboard_samv7-ek/include/wm8904.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/chip.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/chip.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/chip.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/chip.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/compiler.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/compiler.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/compiler.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/compiler.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/acc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/acc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/acc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/acc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/adc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/adc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/adc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/adc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/aes.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/aes.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/aes.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/aes.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/afe_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/afe_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/afe_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/afe_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/afec.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/afec.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/afec.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/afec.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_common_tables.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_common_tables.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_common_tables.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_common_tables.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_const_structs.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_const_structs.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_const_structs.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_const_structs.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_math.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_math.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_math.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/arm_math.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0plus.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0plus.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0plus.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm0plus.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm3.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm3.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm3.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm3.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm4.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm4.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm4.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm4.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm7.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm7.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm7.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cm7.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmFunc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmFunc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmFunc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmFunc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmInstr.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmInstr.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmInstr.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmInstr.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmSimd.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmSimd.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmSimd.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_cmSimd.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc000.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc000.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc000.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc000.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc300.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc300.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc300.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/cmsis/CMSIS/Include/core_sc300.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/dac_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/dac_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/dac_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/dac_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/efc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/efc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/efc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/efc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/exceptions.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/exceptions.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/exceptions.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/exceptions.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/flashd.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/flashd.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/flashd.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/flashd.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/gmac.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/gmac.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/gmac.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/gmac.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/gmacd.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/gmacd.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/gmacd.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/gmacd.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/hsmci.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/hsmci.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/hsmci.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/hsmci.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/icm.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/icm.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/icm.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/icm.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/isi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/isi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/isi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/isi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/iso7816_4.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/iso7816_4.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/iso7816_4.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/iso7816_4.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mcan.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mcan.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mcan.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mcan.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mcid.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mcid.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mcid.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mcid.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mediaLB.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mediaLB.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mediaLB.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mediaLB.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mpu.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mpu.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/mpu.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/mpu.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pio.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pio.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pio.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pio.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pio_capture.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pio_capture.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pio_capture.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pio_capture.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pio_it.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pio_it.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pio_it.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pio_it.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pmc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pmc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pmc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pmc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pwmc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pwmc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/pwmc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/pwmc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/qspi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/qspi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/qspi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/qspi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/qspi_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/qspi_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/qspi_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/qspi_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/rstc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/rstc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/rstc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/rstc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/rtc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/rtc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/rtc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/rtc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/rtt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/rtt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/rtt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/rtt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_acc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_acc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_acc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_acc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_aes.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_aes.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_aes.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_aes.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_afec.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_afec.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_afec.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_afec.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_chipid.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_chipid.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_chipid.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_chipid.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_dacc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_dacc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_dacc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_dacc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_efc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_efc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_efc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_efc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gmac.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gmac.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gmac.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gmac.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gpbr.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gpbr.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gpbr.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_gpbr.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_hsmci.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_hsmci.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_hsmci.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_hsmci.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_icm.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_icm.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_icm.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_icm.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_isi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_isi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_isi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_isi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_matrix.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_matrix.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_matrix.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_matrix.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mcan.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mcan.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mcan.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mcan.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mlb.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mlb.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mlb.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_mlb.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pio.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pio.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pio.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pio.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pmc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pmc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pmc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pmc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pwm.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pwm.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pwm.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_pwm.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_qspi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_qspi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_qspi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_qspi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rstc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rstc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rstc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rstc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rswdt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rswdt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rswdt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rswdt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_rtt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_sdramc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_sdramc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_sdramc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_sdramc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_smc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_smc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_smc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_smc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_spi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_spi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_spi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_spi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_ssc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_ssc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_ssc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_ssc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_supc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_supc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_supc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_supc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_tc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_tc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_tc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_tc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_trng.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_trng.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_trng.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_trng.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twihs.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twihs.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twihs.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_twihs.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uart.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uart.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uart.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uart.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uotghs.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uotghs.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uotghs.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_uotghs.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usart.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usart.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usart.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usart.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usbhs.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usbhs.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usbhs.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_usbhs.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_utmi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_utmi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_utmi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_utmi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_wdt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_wdt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_wdt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_wdt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_xdmac.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_xdmac.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_xdmac.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/component/component_xdmac.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_acc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_acc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_acc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_acc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_aes.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_aes.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_aes.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_aes.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_afec1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_chipid.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_chipid.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_chipid.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_chipid.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_dacc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_dacc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_dacc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_dacc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_efc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_efc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_efc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_efc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gmac.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gmac.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gmac.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gmac.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gpbr.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gpbr.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gpbr.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_gpbr.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_hsmci.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_hsmci.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_hsmci.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_hsmci.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_icm.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_icm.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_icm.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_icm.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_isi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_isi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_isi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_isi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_matrix.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_matrix.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_matrix.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_matrix.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mcan1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mlb.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mlb.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mlb.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_mlb.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioa.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioa.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioa.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioa.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piob.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piob.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piob.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piob.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piod.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piod.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piod.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_piod.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioe.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioe.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioe.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pioe.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pmc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pmc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pmc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pmc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_pwm1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_qspi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_qspi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_qspi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_qspi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rstc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rstc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rstc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rstc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rswdt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rswdt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rswdt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rswdt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_rtt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_sdramc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_sdramc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_sdramc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_sdramc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_smc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_smc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_smc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_smc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_spi1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_ssc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_ssc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_ssc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_ssc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_supc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_supc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_supc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_supc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc2.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc2.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc2.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc2.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc3.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc3.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc3.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_tc3.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_trng.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_trng.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_trng.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_trng.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs2.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs2.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs2.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_twihs2.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart2.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart2.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart2.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart2.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart3.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart3.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart3.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart3.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart4.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart4.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart4.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_uart4.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart0.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart0.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart0.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart0.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart1.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart1.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart1.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart1.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart2.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart2.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart2.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usart2.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usbhs.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usbhs.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usbhs.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_usbhs.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_utmi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_utmi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_utmi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_utmi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_wdt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_wdt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_wdt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_wdt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_xdmac.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_xdmac.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_xdmac.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/instance/instance_xdmac.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j19.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j19.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j19.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j19.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j20.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j20.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j20.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j20.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j21.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j21.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j21.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71j21.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n19.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n19.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n19.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n19.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n20.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n20.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n20.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n20.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n21.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n21.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n21.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71n21.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q19.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q19.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q19.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q19.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q20.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q20.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q20.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q20.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q21.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q21.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q21.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/pio/pio_samv71q21.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j19.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j19.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j19.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j19.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j20.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j20.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j20.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j20.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j21.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j21.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j21.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71j21.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n19.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n19.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n19.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n19.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n20.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n20.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n20.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n20.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n21.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n21.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n21.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71n21.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q19.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q19.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q19.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q19.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q20.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q20.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q20.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q20.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q21.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q21.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q21.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/samv71q21.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/system_samv71.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/system_samv71.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/samv7/system_samv71.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/samv7/system_samv71.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/sdramc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/sdramc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/sdramc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/sdramc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/smc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/smc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/smc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/smc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/spi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/spi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/spi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/spi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/spi_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/spi_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/spi_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/spi_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/ssc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/ssc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/ssc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/ssc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/supc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/supc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/supc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/supc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/tc.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/tc.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/tc.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/tc.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/timetick.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/timetick.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/timetick.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/timetick.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/trace.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/trace.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/trace.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/trace.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/trng.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/trng.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/trng.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/trng.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/twi.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/twi.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/twi.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/twi.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/twid.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/twid.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/twid.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/twid.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/uart.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/uart.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/uart.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/uart.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/uart_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/uart_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/uart_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/uart_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/usart.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/usart.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/usart.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/usart.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/usart_dma.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/usart_dma.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/usart_dma.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/usart_dma.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/usbhs.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/usbhs.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/usbhs.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/usbhs.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/video.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/video.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/video.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/video.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/wdt.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/wdt.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/wdt.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/wdt.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/xdma_hardware_interface.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/xdma_hardware_interface.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/xdma_hardware_interface.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/xdma_hardware_interface.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/xdmac.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/xdmac.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/xdmac.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/xdmac.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/xdmad.h b/ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/xdmad.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libchip_samv7/include/xdmad.h rename to ports_module/cortex_m7/iar/example_build/libraries/libchip_samv7/include/xdmad.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/libraries.a b/ports_module/cortex_m7/iar/example_build/libraries/libraries.a similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/libraries.a rename to ports_module/cortex_m7/iar/example_build/libraries/libraries.a diff --git a/ports_module/cortex-m7/iar/example_build/libraries/utils/md5/md5.h b/ports_module/cortex_m7/iar/example_build/libraries/utils/md5/md5.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/utils/md5/md5.h rename to ports_module/cortex_m7/iar/example_build/libraries/utils/md5/md5.h diff --git a/ports_module/cortex-m7/iar/example_build/libraries/utils/utility.h b/ports_module/cortex_m7/iar/example_build/libraries/utils/utility.h similarity index 100% rename from ports_module/cortex-m7/iar/example_build/libraries/utils/utility.h rename to ports_module/cortex_m7/iar/example_build/libraries/utils/utility.h diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx.c b/ports_module/cortex_m7/iar/example_build/sample_threadx.c similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx.c rename to ports_module/cortex_m7/iar/example_build/sample_threadx.c diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx.ewd b/ports_module/cortex_m7/iar/example_build/sample_threadx.ewd similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx.ewd rename to ports_module/cortex_m7/iar/example_build/sample_threadx.ewd diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx.ewp b/ports_module/cortex_m7/iar/example_build/sample_threadx.ewp similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx.ewp rename to ports_module/cortex_m7/iar/example_build/sample_threadx.ewp diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx.icf b/ports_module/cortex_m7/iar/example_build/sample_threadx.icf similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx.icf rename to ports_module/cortex_m7/iar/example_build/sample_threadx.icf diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module.c b/ports_module/cortex_m7/iar/example_build/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module.c rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module.c diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module.ewd b/ports_module/cortex_m7/iar/example_build/sample_threadx_module.ewd similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module.ewd rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module.ewd diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module.ewp b/ports_module/cortex_m7/iar/example_build/sample_threadx_module.ewp similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module.ewp rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module.ewp diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module.icf b/ports_module/cortex_m7/iar/example_build/sample_threadx_module.icf similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module.icf rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module.icf diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.c b/ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.c rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.c diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.ewd b/ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.ewd similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.ewd rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.ewd diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.ewp b/ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.ewp similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.ewp rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.ewp diff --git a/ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.icf b/ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.icf similarity index 100% rename from ports_module/cortex-m7/iar/example_build/sample_threadx_module_manager.icf rename to ports_module/cortex_m7/iar/example_build/sample_threadx_module_manager.icf diff --git a/ports_module/cortex-m7/iar/example_build/startup.s b/ports_module/cortex_m7/iar/example_build/startup.s similarity index 100% rename from ports_module/cortex-m7/iar/example_build/startup.s rename to ports_module/cortex_m7/iar/example_build/startup.s diff --git a/ports_module/cortex-m7/iar/example_build/tx.ewp b/ports_module/cortex_m7/iar/example_build/tx.ewp similarity index 100% rename from ports_module/cortex-m7/iar/example_build/tx.ewp rename to ports_module/cortex_m7/iar/example_build/tx.ewp diff --git a/ports_module/cortex-m7/iar/example_build/tx_initialize_low_level.s b/ports_module/cortex_m7/iar/example_build/tx_initialize_low_level.s similarity index 100% rename from ports_module/cortex-m7/iar/example_build/tx_initialize_low_level.s rename to ports_module/cortex_m7/iar/example_build/tx_initialize_low_level.s diff --git a/ports_module/cortex-m7/iar/example_build/txm.ewp b/ports_module/cortex_m7/iar/example_build/txm.ewp similarity index 100% rename from ports_module/cortex-m7/iar/example_build/txm.ewp rename to ports_module/cortex_m7/iar/example_build/txm.ewp diff --git a/ports_module/cortex-m7/iar/example_build/txm_module_preamble.s b/ports_module/cortex_m7/iar/example_build/txm_module_preamble.s similarity index 100% rename from ports_module/cortex-m7/iar/example_build/txm_module_preamble.s rename to ports_module/cortex_m7/iar/example_build/txm_module_preamble.s diff --git a/ports_module/cortex-m7/iar/inc/tx_port.h b/ports_module/cortex_m7/iar/inc/tx_port.h similarity index 100% rename from ports_module/cortex-m7/iar/inc/tx_port.h rename to ports_module/cortex_m7/iar/inc/tx_port.h diff --git a/ports_module/cortex-m7/iar/inc/txm_module_port.h b/ports_module/cortex_m7/iar/inc/txm_module_port.h similarity index 90% rename from ports_module/cortex-m7/iar/inc/txm_module_port.h rename to ports_module/cortex_m7/iar/inc/txm_module_port.h index 7d56647e..6659fc5f 100644 --- a/ports_module/cortex-m7/iar/inc/txm_module_port.h +++ b/ports_module/cortex_m7/iar/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-M7/MPU/IAR */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -40,10 +40,12 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), */ /* increase kernel stack size, */ /* resulting in version 6.1.2 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ @@ -115,7 +117,6 @@ The following extensions must also be defined in tx_port.h: #define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000 #endif - /* Define constants specific to the tools the module can be built with for this particular modules port. */ #define TXM_MODULE_IAR_COMPILER 0x00000000 @@ -170,6 +171,8 @@ The following extensions must also be defined in tx_port.h: #define INLINE_DECLARE inline +#ifndef TXM_MODULE_MANAGER_8_MPU + /* Define the number of MPU entries assigned to the code and data sections. On Cortex-M7 parts, there are 16 total entries. ThreadX uses one for access to the kernel entry function, thus 15 remain for code and data protection. */ @@ -201,6 +204,28 @@ typedef struct TXM_MODULE_MPU_INFO_STRUCT ULONG txm_module_instance_shared_memory_address[TXM_MODULE_MPU_SHARED_ENTRIES]; \ ULONG txm_module_instance_shared_memory_length[TXM_MODULE_MPU_SHARED_ENTRIES]; +#else /* TXM_MODULE_MANAGER_8_MPU is defined */ + +/* Define the number of MPU entries assigned to the code and data sections. + On Cortex-M4 parts, there are 8 total entries. ThreadX uses one for access + to the kernel entry function, thus 7 remain for code and data protection. */ +#define TXM_MODULE_MANAGER_CODE_MPU_ENTRIES 4 +#define TXM_MODULE_MANAGER_DATA_MPU_ENTRIES 3 +#define TXM_MODULE_MANAGER_SHARED_MPU_INDEX 8 +#define TXM_MODULE_MANAGER_SHARED_MPU_REGION 4 + +/* Shared memory region attributes. */ +#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1 +#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT 0x01000000 + +/* Define the port-extensions to the module manager instance structure. */ + +#define TXM_MODULE_MANAGER_PORT_EXTENSION \ + ULONG txm_module_instance_mpu_registers[16]; \ + ULONG txm_module_instance_shared_memory_address; \ + ULONG txm_module_instance_shared_memory_length; + +#endif /* TXM_MODULE_MANAGER_8_MPU */ /* Define the memory fault information structure that is populated when a memory fault occurs. */ @@ -323,8 +348,20 @@ typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT /* Define the macros to perform port-specific checks when passing pointers to the kernel. */ /* Define macro to make sure object is inside the module's data. */ +#ifndef TXM_MODULE_MANAGER_8_MPU #define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ _txm_module_manager_inside_data_check(module_instance, obj_ptr, obj_size) +#else +#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ + /* Check for overflow. */ \ + (((obj_ptr) < ((obj_ptr) + (obj_size))) && \ + /* Check if it's inside module data. */ \ + ((((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) && \ + (((obj_ptr) + (obj_size)) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1))) || \ + /* Check if it's inside shared memory. */ \ + (((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address) && \ + (((obj_ptr) + (obj_size)) <= (ALIGN_TYPE) (module_instance -> txm_module_instance_shared_memory_address + module_instance -> txm_module_instance_shared_memory_length))))) +#endif /* Define some internal prototypes to this module port. */ @@ -345,6 +382,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance #define TXM_MODULE_MANAGER_VERSION_ID \ CHAR _txm_module_manager_version_id[] = \ - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/IAR Version 6.1.2 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/MPU/IAR Version 6.1.7 *"; #endif diff --git a/ports_module/cortex-m7/iar/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m7/iar/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-m7/iar/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_m7/iar/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_iar.c b/ports_module/cortex_m7/iar/module_manager/src/tx_iar.c similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_iar.c rename to ports_module/cortex_m7/iar/module_manager/src/tx_iar.c diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_misra.s b/ports_module/cortex_m7/iar/module_manager/src/tx_misra.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_misra.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_misra.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_context_restore.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_context_restore.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_context_restore.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_context_restore.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_context_save.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_context_save.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_context_save.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_context_save.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_interrupt_control.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_interrupt_control.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_interrupt_control.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_interrupt_control.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_interrupt_disable.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_interrupt_disable.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_interrupt_disable.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_interrupt_disable.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_interrupt_restore.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_interrupt_restore.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_interrupt_restore.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_interrupt_restore.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s similarity index 93% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_schedule.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s index e81b462a..417ac9b5 100644 --- a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/MPU/IAR */ -/* 6.1.2 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -69,11 +69,15 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* 11-09-2020 Scott Larson Modified comment(s), arrange */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 11-09-2020 Scott Larson Modified comment(s), arrange */ /* code to fix link error when */ /* VFP is enabled, resulting */ /* in version 6.1.2 */ +/* 06-02-2021 Scott Larson Fixed extended stack handling */ +/* when calling kernel APIs, */ +/* added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -360,6 +364,7 @@ __tx_ts_restore: // Use alias registers to quickly load MPU ADD r0, r0, #100 // Build address of MPU register start in thread control block +#ifndef TXM_MODULE_MANAGER_8_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 @@ -368,6 +373,12 @@ __tx_ts_restore: 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 LDR r0, =0xE000ED94 // Build MPU control reg address MOV r1, #5 // Build enable value with background region enabled STR r1, [r0] // Enable MPU @@ -434,20 +445,24 @@ __tx_SVCallHandler: STR r0, [r2, #16] // Set stack end STR r3, [r2, #20] // Set stack size #endif - MRS r3, PSP // Pickup thread stack pointer + TST lr, #0x10 // Test for extended module stack + ITT EQ + ORREQ r3, r3, #1 // If so, set LSB in thread stack pointer to indicate extended frame + ORREQ lr, lr, #0x10 // Set bit, return with standard frame STR r3, [r2, #0xB0] // Save thread stack pointer - + BIC r3, #1 // Clear possibly OR'd bit + /* Build kernel stack by copying thread stack two registers at a time */ ADD r3, r3, #32 // Start at bottom of hardware stack - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} - LDMDB r3!,{r1-r2} - STMDB r0!,{r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} + LDMDB r3!, {r1-r2} + STMDB r0!, {r1-r2} MSR PSP, r0 // Set kernel stack pointer @@ -485,16 +500,21 @@ _tx_thread_user_return: #endif LDR r0, [r2, #0xB0] // Load the module thread stack pointer MRS r3, PSP // Pickup kernel stack pointer + TST r0, #1 // Is module stack extended? + ITTE NE // If so... + BICNE lr, #0x10 // Clear bit, return with extended frame + BICNE r0, #1 // Clear bit that indicates extended module frame + ORREQ lr, lr, #0x10 // Else set bit, return with standard frame /* 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} + 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} SUB r0, r0, #32 // Subtract 32 to get back to top of stack MSR PSP, r0 // Set thread stack pointer diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_stack_build.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_stack_build.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_stack_build.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_stack_build.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_thread_system_return.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_system_return.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_thread_system_return.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_thread_system_return.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/tx_timer_interrupt.s b/ports_module/cortex_m7/iar/module_manager/src/tx_timer_interrupt.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/tx_timer_interrupt.s rename to ports_module/cortex_m7/iar/module_manager/src/tx_timer_interrupt.s diff --git a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 52% rename from ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_alignment_adjust.c index 278c3f8a..6bc46d0d 100644 --- a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_alignment_adjust.c +++ b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_alignment_adjust.c @@ -94,7 +94,7 @@ ULONG _txm_power_of_two_block_size(ULONG size) /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_alignment_adjust Cortex-M7/MPU/IAR */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -128,7 +128,9 @@ ULONG _txm_power_of_two_block_size(ULONG size) /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, @@ -137,7 +139,7 @@ VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *data_size, ULONG *data_alignment) { - +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG local_code_size; ULONG local_code_alignment; ULONG local_data_size; @@ -182,4 +184,267 @@ ULONG data_size_accum; *code_alignment = local_code_alignment; *data_size = local_data_size; *data_alignment = local_data_alignment; + +#else + +ULONG local_code_size; +ULONG local_code_alignment; +ULONG local_data_size; +ULONG local_data_alignment; +ULONG code_block_size; +ULONG data_block_size; +ULONG code_size_accum; +ULONG data_size_accum; + + /* Copy the input parameters into local variables for ease of use. */ + local_code_size = *code_size; + local_code_alignment = *code_alignment; + local_data_size = *data_size; + local_data_alignment = *data_alignment; + + + /* Test for external memory enabled in preamble. */ + if(module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS) + { + /* External/shared memory enabled. TXM_MODULE_MANAGER_CODE_MPU_ENTRIES-1 code entries will be used. */ + if (local_code_size <= (32*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32 is best. */ + code_block_size = 32; + } + else if (local_code_size <= (64*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 64 is best. */ + code_block_size = 64; + } + else if (local_code_size <= (128*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 128 is best. */ + code_block_size = 128; + } + else if (local_code_size <= (256*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 256 is best. */ + code_block_size = 256; + } + else if (local_code_size <= (512*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 512 is best. */ + code_block_size = 512; + } + else if (local_code_size <= (1024*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1024 is best. */ + code_block_size = 1024; + } + else if (local_code_size <= (2048*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2048 is best. */ + code_block_size = 2048; + } + else if (local_code_size <= (4096*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4096 is best. */ + code_block_size = 4096; + } + else if (local_code_size <= (8192*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 8192 is best. */ + code_block_size = 8192; + } + else if (local_code_size <= (16384*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 16384 is best. */ + code_block_size = 16384; + } + else if (local_code_size <= (32768*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 32768 is best. */ + code_block_size = 32768; + } + else if (local_code_size <= (65536*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 65536 is best. */ + code_block_size = 65536; + } + else if (local_code_size <= (131072*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 131072 is best. */ + code_block_size = 131072; + } + else if (local_code_size <= (262144*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 262144 is best. */ + code_block_size = 262144; + } + else if (local_code_size <= (524288*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 524288 is best. */ + code_block_size = 524288; + } + else if (local_code_size <= (1048576*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 1048576 is best. */ + code_block_size = 1048576; + } + else if (local_code_size <= (2097152*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 2097152 is best. */ + code_block_size = 2097152; + } + else if (local_code_size <= (4194304*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1))) + { + /* Block size of 4194304 is best. */ + code_block_size = 4194304; + } + else + { + /* Just set block size to 32MB just to create an allocation error! */ + code_block_size = 33554432; + } + + /* Calculate the new code size. */ + local_code_size = code_block_size*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1); + + /* Determine if the code block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (code_block_size > local_code_alignment) + local_code_alignment = code_block_size; + + } + else + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2; + code_size_accum = local_code_alignment + local_code_alignment; + code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1); + code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum); + local_code_size = code_size_accum; + } + + /* Determine the best data block size, which in our case is the minimal alignment. */ + if (local_data_size <= (32*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32 is best. */ + data_block_size = 32; + } + else if (local_data_size <= (64*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 64 is best. */ + data_block_size = 64; + } + else if (local_data_size <= (128*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 128 is best. */ + data_block_size = 128; + } + else if (local_data_size <= (256*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 256 is best. */ + data_block_size = 256; + } + else if (local_data_size <= (512*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 512 is best. */ + data_block_size = 512; + } + else if (local_data_size <= (1024*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1024 is best. */ + data_block_size = 1024; + } + else if (local_data_size <= (2048*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2048 is best. */ + data_block_size = 2048; + } + else if (local_data_size <= (4096*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4096 is best. */ + data_block_size = 4096; + } + else if (local_data_size <= (8192*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 8192 is best. */ + data_block_size = 8192; + } + else if (local_data_size <= (16384*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 16384 is best. */ + data_block_size = 16384; + } + else if (local_data_size <= (32768*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 32768 is best. */ + data_block_size = 32768; + } + else if (local_data_size <= (65536*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 65536 is best. */ + data_block_size = 65536; + } + else if (local_data_size <= (131072*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 131072 is best. */ + data_block_size = 131072; + } + else if (local_data_size <= (262144*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 262144 is best. */ + data_block_size = 262144; + } + else if (local_data_size <= (524288*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 524288 is best. */ + data_block_size = 524288; + } + else if (local_data_size <= (1048576*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 1048576 is best. */ + data_block_size = 1048576; + } + else if (local_data_size <= (2097152*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 2097152 is best. */ + data_block_size = 2097152; + } + else if (local_data_size <= (4194304*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES)) + { + /* Block size of 4194304 is best. */ + data_block_size = 4194304; + } + else + { + /* Just set data block size to 32MB just to create an allocation error! */ + data_block_size = 33554432; + } + + /* Calculate the new data size. */ + data_size_accum = data_block_size; + while(data_size_accum < local_data_size) + { + data_size_accum += data_block_size; + } + local_data_size = data_size_accum; + + /* Determine if the data block size is greater than the current alignment. If so, use block size + as the alignment. */ + if (data_block_size > local_data_alignment) + { + local_data_alignment = data_block_size; + } + + /* Return all the information to the caller. */ + *code_size = local_code_size; + *code_alignment = local_code_alignment; + *data_size = local_data_size; + *data_alignment = local_data_alignment; + +#endif } diff --git a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 69% rename from ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_external_memory_enable.c index 3ac6b6fe..01c7a62c 100644 --- a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_external_memory_enable.c +++ b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_external_memory_enable.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_external_memory_enable Cortex-M7/MPU/IAR */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -69,7 +69,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in verison 6.1.7 */ /* */ /**************************************************************************/ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance, @@ -77,7 +79,7 @@ UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_ins ULONG length, UINT attributes) { - +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG block_size; ULONG region_size; ULONG srd_bits; @@ -186,4 +188,109 @@ ULONG attributes_check = 0; /* Return success. */ return(TX_SUCCESS); + +#else + +ULONG block_size; +ULONG region_size; +ULONG subregion_bits; +ULONG address; +UINT attributes_check = 0; +TXM_MODULE_PREAMBLE *module_preamble; + + /* Determine if the module manager has not been initialized yet. */ + if (_txm_module_manager_ready != TX_TRUE) + { + /* Module manager has not been initialized. */ + return(TX_NOT_AVAILABLE); + } + + /* Determine if the module is valid. */ + if (module_instance == TX_NULL) + { + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Get module manager protection mutex. */ + _tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER); + + /* Determine if the module instance is valid. */ + if (module_instance -> txm_module_instance_id != TXM_MODULE_ID) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Invalid module pointer. */ + return(TX_PTR_ERROR); + } + + /* Determine if the module instance is in the loaded state. */ + if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if the module is not ready. */ + return(TX_START_ERROR); + } + + /* Check if preamble shared mem and mem protection property bits are set. */ + module_preamble = module_instance -> txm_module_instance_preamble_ptr; + if((module_preamble -> txm_module_preamble_property_flags & (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + != (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return error if bit not set. */ + return(TXM_MODULE_INVALID_PROPERTIES); + } + + /* Start address and length must adhere to Cortex-M MPU. + The address must align with the block size. */ + + block_size = _txm_power_of_two_block_size(length); + address = (ULONG) start_address; + if(address != (address & ~(block_size - 1))) + { + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return alignment error. */ + return(TXM_MODULE_ALIGNMENT_ERROR); + } + + /* At this point, we have a valid address and block size. + Set up MPU registers. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] = address | TXM_MODULE_MANAGER_SHARED_MPU_REGION | 0x10; + + /* Calculate the region size. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + /* Calculate the subregion bits. */ + subregion_bits = _txm_module_manager_calculate_srd_bits(block_size, length); + + /* Check for valid attributes. */ + if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE) + { + attributes_check = TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT; + } + + /* Build register with attributes. */ + module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX+1] = region_size | subregion_bits | attributes_check | 0x12070001; + + /* Keep track of shared memory address and length in module instance. */ + module_instance -> txm_module_instance_shared_memory_address = address; + module_instance -> txm_module_instance_shared_memory_length = length; + + /* Recalculate MPU settings. */ + _txm_module_manager_mm_register_setup(module_instance); + + /* Release the protection mutex. */ + _tx_mutex_put(&_txm_module_manager_mutex); + + /* Return success. */ + return(TX_SUCCESS); + +#endif } diff --git a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 71% rename from ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c index d4cb11d9..f25f830a 100644 --- a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c +++ b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c @@ -231,7 +231,7 @@ UINT srd_bit_index; /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_mm_register_setup Cortex-M7/MPU/IAR */ -/* 6.1 */ +/* 6.1.7 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -259,6 +259,7 @@ UINT srd_bit_index; /* 14 Unused region */ /* 15 Unused region */ /* */ +/* If TXM_MODULE_MANAGER_8_MPU is defined, there are only 8 MPU slots. */ /* */ /* INPUT */ /* */ @@ -280,11 +281,14 @@ UINT srd_bit_index; /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* 06-02-2021 Scott Larson Added support for 8 MPU, */ +/* resulting in version 6.1.7 */ /* */ /**************************************************************************/ VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance) { +#ifndef TXM_MODULE_MANAGER_8_MPU ULONG code_address; ULONG code_size; @@ -452,10 +456,256 @@ UINT i; /* Increment MPU table index. */ mpu_table_index++; } + +#else + +ULONG code_address; +ULONG code_size; +ULONG data_address; +ULONG data_size; +ULONG start_stop_stack_size; +ULONG callback_stack_size; +ULONG block_size; +ULONG base_address_register; +ULONG base_attribute_register; +ULONG region_size; +ULONG srd_bits = 0; +UINT mpu_register = 0; +UINT mpu_table_index; +UINT i; + + + /* Setup the first region for the ThreadX trampoline code. */ + /* Set base register to user mode entry, which is guaranteed to be at least 32-byte aligned. */ + base_address_register = (ULONG) _txm_module_manager_user_mode_entry; + /* Mask address to proper range, region 0, set Valid bit. */ + base_address_register = (base_address_register & 0xFFFFFFE0) | mpu_register | 0x10; + module_instance -> txm_module_instance_mpu_registers[0] = base_address_register; + + /* Attributes: read only, write-back, shareable, size 32 bytes, region enabled. */ + module_instance -> txm_module_instance_mpu_registers[1] = 0x06070009; + + /* Initialize the MPU register. */ + mpu_register = 1; + + /* Initialize the MPU table index. */ + mpu_table_index = 2; + + /* Setup values for code area. */ + code_address = (ULONG) module_instance -> txm_module_instance_code_start; + code_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_code_size; + + /* Check if shared memory was set up. If so, only 3 entries are available for + code protection. If not set up, 4 code entries are available. */ + if(module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] == 0) + { + /* Determine code block sizes. Minimize the alignment requirement. + There are 4 MPU code entries available. The following is how the code size + will be distributed: + 1. 1/4 of the largest power of two that is greater than or equal to code size. + 2. 1/4 of the largest power of two that is greater than or equal to code size. + 3. Largest power of 2 that fits in the remaining space. + 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES; i++) + { + /* First two MPU blocks are 1/4 of the largest power of two + that is greater than or equal to code size. */ + if (i < 2) + { + block_size = _txm_power_of_two_block_size(code_size) >> 2; + } + + /* Third MPU block is the largest power of 2 that fits in the remaining space. */ + else if (i == 2) + { + /* Subtract (block_size*2) from code_size to calculate remaining space. */ + code_size = code_size - (block_size << 1); + block_size = _txm_power_of_two_block_size(code_size) >> 1; + } + + /* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */ + else + { + /* Calculate remaining space. */ + code_size = code_size - block_size; + block_size = _txm_power_of_two_block_size(code_size); + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base address register. */ + base_address_register = (code_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070001; + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + } + + /* Only 3 code entries available. */ + else + { + /* Calculate block size, one code entry taken up by shared memory. */ + block_size = _txm_power_of_two_block_size(code_size / (TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)); + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the code area. */ + for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1; i++) + { + /* Build the base address register. */ + base_address_register = code_address & ~(block_size - 1) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (code_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x06070000; + + /* Is there still some code? If so set the region enable bit. */ + if (code_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the code address. */ + code_address = code_address + block_size; + + /* Decrement the code size. */ + if (code_size > block_size) + { + code_size = code_size - block_size; + } + else + { + code_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Adjust indeces to pass over the shared memory entry. */ + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + + /* Setup values for data area. */ + data_address = (ULONG) module_instance -> txm_module_instance_data_start; + + /* Adjust the size of the module elements to be aligned to the default alignment. We do this + so that when we partition the allocated memory, we can simply place these regions right beside + each other without having to align their pointers. Note this only works when they all have + the same alignment. */ + + data_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_data_size; + start_stop_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_start_stop_stack_size; + callback_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_callback_stack_size; + + data_size = ((data_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + start_stop_stack_size = ((start_stop_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + callback_stack_size = ((callback_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT; + + /* Update the data size to include thread stacks. */ + data_size = data_size + start_stop_stack_size + callback_stack_size; + + block_size = _txm_power_of_two_block_size(data_size / TXM_MODULE_MANAGER_DATA_MPU_ENTRIES); + + /* Reset SRD bitfield. */ + srd_bits = 0; + + /* Calculate the region size information. */ + region_size = (_txm_module_manager_region_size_get(block_size) << 1); + + /* Now loop through to setup MPU protection for the data area. */ + for (i = 0; i < TXM_MODULE_MANAGER_DATA_MPU_ENTRIES; i++) + { + /* Build the base address register. */ + base_address_register = (data_address & ~(block_size - 1)) | mpu_register | 0x10; + + /* Check if SRD bits need to be set. */ + if (data_size < block_size) + { + srd_bits = _txm_module_manager_calculate_srd_bits(block_size, data_size); + } + + /* Build the base attribute register. */ + base_attribute_register = region_size | srd_bits | 0x13070000; + + /* Is there still some data? If so set the region enable bit. */ + if (data_size) + { + /* Set the region enable bit. */ + base_attribute_register = base_attribute_register | 0x1; + } + + /* Setup the MPU Base Address Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register; + + /* Setup the MPU Base Attribute Register. */ + module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register; + + /* Adjust the data address. */ + data_address = data_address + block_size; + + /* Decrement the data size. */ + if (data_size > block_size) + { + data_size = data_size - block_size; + } + else + { + data_size = 0; + } + + /* Move MPU table index. */ + mpu_table_index = mpu_table_index + 2; + + /* Increment the MPU register index. */ + mpu_register++; + } + +#endif } - +#ifndef TXM_MODULE_MANAGER_8_MPU /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -537,3 +787,4 @@ ALIGN_TYPE shared_memory_address_end; return(TX_FALSE); } +#endif diff --git a/ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_thread_stack_build.s b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_thread_stack_build.s similarity index 100% rename from ports_module/cortex-m7/iar/module_manager/src/txm_module_manager_thread_stack_build.s rename to ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_thread_stack_build.s diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module/.cproject b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module/.cproject similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module/.cproject rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module/.cproject diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module/.project b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module/.project similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module/.project rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module/.project diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module/.settings/language.settings.xml b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module/.settings/language.settings.xml similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module/.settings/language.settings.xml rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module/.settings/language.settings.xml diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module/sample_threadx_module.c b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module/sample_threadx_module.c rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module/sample_threadx_module.c diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module/semihosting.c b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module/semihosting.c similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module/semihosting.c rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module/semihosting.c diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module/txm_module_preamble.S b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module/txm_module_preamble.S similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module/txm_module_preamble.S rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module/txm_module_preamble.S diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/.cproject b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/.cproject similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/.cproject rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/.cproject diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/.project b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/.project similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/.project rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/.project diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/.settings/language.settings.xml b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/.settings/language.settings.xml similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/.settings/language.settings.xml rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/.settings/language.settings.xml diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/gic.c b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/gic.c similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/gic.c rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/gic.c diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/gic.h b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/gic.h similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/gic.h rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/gic.h diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/module_code.c b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/module_code.c similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/module_code.c rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/module_code.c diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/sample_threadx.scat diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.c diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/startup.S b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/startup.S similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/startup.S rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/startup.S diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/timer.c b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/timer.c similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/timer.c rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/timer.c diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/timer.h b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/timer.h similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/timer.h rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/timer.h diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/tx_initialize_low_level.S diff --git a/ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/txm_cortex_r4.launch b/ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/txm_cortex_r4.launch similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/sample_threadx_module_manager/txm_cortex_r4.launch rename to ports_module/cortex_r4/ac6/example_build/sample_threadx_module_manager/txm_cortex_r4.launch diff --git a/ports_module/cortex-r4/ac6/example_build/tx/.cproject b/ports_module/cortex_r4/ac6/example_build/tx/.cproject similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/tx/.cproject rename to ports_module/cortex_r4/ac6/example_build/tx/.cproject diff --git a/ports_module/cortex-r4/ac6/example_build/tx/.project b/ports_module/cortex_r4/ac6/example_build/tx/.project similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/tx/.project rename to ports_module/cortex_r4/ac6/example_build/tx/.project diff --git a/ports_module/cortex-r4/ac6/example_build/tx/.settings/language.settings.xml b/ports_module/cortex_r4/ac6/example_build/tx/.settings/language.settings.xml similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/tx/.settings/language.settings.xml rename to ports_module/cortex_r4/ac6/example_build/tx/.settings/language.settings.xml diff --git a/ports_module/cortex-r4/ac6/example_build/txm/.cproject b/ports_module/cortex_r4/ac6/example_build/txm/.cproject similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/txm/.cproject rename to ports_module/cortex_r4/ac6/example_build/txm/.cproject diff --git a/ports_module/cortex-r4/ac6/example_build/txm/.project b/ports_module/cortex_r4/ac6/example_build/txm/.project similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/txm/.project rename to ports_module/cortex_r4/ac6/example_build/txm/.project diff --git a/ports_module/cortex-r4/ac6/example_build/txm/.settings/language.settings.xml b/ports_module/cortex_r4/ac6/example_build/txm/.settings/language.settings.xml similarity index 100% rename from ports_module/cortex-r4/ac6/example_build/txm/.settings/language.settings.xml rename to ports_module/cortex_r4/ac6/example_build/txm/.settings/language.settings.xml diff --git a/ports_module/cortex-r4/ac6/inc/tx_port.h b/ports_module/cortex_r4/ac6/inc/tx_port.h similarity index 100% rename from ports_module/cortex-r4/ac6/inc/tx_port.h rename to ports_module/cortex_r4/ac6/inc/tx_port.h diff --git a/ports_module/cortex-r4/ac6/inc/txm_module_port.h b/ports_module/cortex_r4/ac6/inc/txm_module_port.h similarity index 100% rename from ports_module/cortex-r4/ac6/inc/txm_module_port.h rename to ports_module/cortex_r4/ac6/inc/txm_module_port.h diff --git a/ports_module/cortex-r4/ac6/module_lib/src/txm_module_initialize.S b/ports_module/cortex_r4/ac6/module_lib/src/txm_module_initialize.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_lib/src/txm_module_initialize.S rename to ports_module/cortex_r4/ac6/module_lib/src/txm_module_initialize.S diff --git a/ports_module/cortex-r4/ac6/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_r4/ac6/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-r4/ac6/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_r4/ac6/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_context_restore.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_context_restore.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_context_restore.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_context_restore.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_context_save.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_context_save.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_context_save.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_context_save.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_context_restore.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_context_restore.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_context_restore.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_context_restore.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_context_save.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_context_save.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_context_save.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_context_save.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_nesting_end.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_nesting_end.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_nesting_end.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_nesting_end.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_nesting_start.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_nesting_start.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_fiq_nesting_start.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_fiq_nesting_start.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_interrupt_control.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_interrupt_control.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_interrupt_control.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_interrupt_control.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_interrupt_disable.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_interrupt_disable.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_interrupt_disable.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_interrupt_disable.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_interrupt_restore.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_interrupt_restore.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_interrupt_restore.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_interrupt_restore.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_irq_nesting_end.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_irq_nesting_end.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_irq_nesting_end.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_irq_nesting_end.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_irq_nesting_start.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_irq_nesting_start.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_irq_nesting_start.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_irq_nesting_start.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_schedule.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_schedule.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_schedule.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_stack_build.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_stack_build.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_stack_build.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_stack_build.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_system_return.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_system_return.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_system_return.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_system_return.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_thread_vectored_context_save.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_thread_vectored_context_save.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_thread_vectored_context_save.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_thread_vectored_context_save.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/tx_timer_interrupt.S b/ports_module/cortex_r4/ac6/module_manager/src/tx_timer_interrupt.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/tx_timer_interrupt.S rename to ports_module/cortex_r4/ac6/module_manager/src/tx_timer_interrupt.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_alignment_adjust.c diff --git a/ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_external_memory_enable.c diff --git a/ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c diff --git a/ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_thread_stack_build.S b/ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_thread_stack_build.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_thread_stack_build.S rename to ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_thread_stack_build.S diff --git a/ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_user_mode_entry.S b/ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_user_mode_entry.S similarity index 100% rename from ports_module/cortex-r4/ac6/module_manager/src/txm_module_manager_user_mode_entry.S rename to ports_module/cortex_r4/ac6/module_manager/src/txm_module_manager_user_mode_entry.S diff --git a/ports_module/cortex-r4/iar/example_build/azure_rtos.eww b/ports_module/cortex_r4/iar/example_build/azure_rtos.eww similarity index 100% rename from ports_module/cortex-r4/iar/example_build/azure_rtos.eww rename to ports_module/cortex_r4/iar/example_build/azure_rtos.eww diff --git a/ports_module/cortex-r4/iar/example_build/cstartup.s b/ports_module/cortex_r4/iar/example_build/cstartup.s similarity index 100% rename from ports_module/cortex-r4/iar/example_build/cstartup.s rename to ports_module/cortex_r4/iar/example_build/cstartup.s diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx.c b/ports_module/cortex_r4/iar/example_build/sample_threadx.c similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx.c rename to ports_module/cortex_r4/iar/example_build/sample_threadx.c diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx.ewd b/ports_module/cortex_r4/iar/example_build/sample_threadx.ewd similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx.ewd rename to ports_module/cortex_r4/iar/example_build/sample_threadx.ewd diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx.ewp b/ports_module/cortex_r4/iar/example_build/sample_threadx.ewp similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx.ewp rename to ports_module/cortex_r4/iar/example_build/sample_threadx.ewp diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx.icf b/ports_module/cortex_r4/iar/example_build/sample_threadx.icf similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx.icf rename to ports_module/cortex_r4/iar/example_build/sample_threadx.icf diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module.c b/ports_module/cortex_r4/iar/example_build/sample_threadx_module.c similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module.c rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module.c diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module.ewd b/ports_module/cortex_r4/iar/example_build/sample_threadx_module.ewd similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module.ewd rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module.ewd diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module.ewp b/ports_module/cortex_r4/iar/example_build/sample_threadx_module.ewp similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module.ewp rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module.ewp diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module.icf b/ports_module/cortex_r4/iar/example_build/sample_threadx_module.icf similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module.icf rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module.icf diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.c b/ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.c similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.c rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.c diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.ewd b/ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.ewd similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.ewd rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.ewd diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.ewp b/ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.ewp similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.ewp rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.ewp diff --git a/ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.icf b/ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.icf similarity index 100% rename from ports_module/cortex-r4/iar/example_build/sample_threadx_module_manager.icf rename to ports_module/cortex_r4/iar/example_build/sample_threadx_module_manager.icf diff --git a/ports_module/cortex-r4/iar/example_build/settings/sample_threadx.dnx b/ports_module/cortex_r4/iar/example_build/settings/sample_threadx.dnx similarity index 100% rename from ports_module/cortex-r4/iar/example_build/settings/sample_threadx.dnx rename to ports_module/cortex_r4/iar/example_build/settings/sample_threadx.dnx diff --git a/ports_module/cortex-r4/iar/example_build/settings/sample_threadx_module_manager.dnx b/ports_module/cortex_r4/iar/example_build/settings/sample_threadx_module_manager.dnx similarity index 100% rename from ports_module/cortex-r4/iar/example_build/settings/sample_threadx_module_manager.dnx rename to ports_module/cortex_r4/iar/example_build/settings/sample_threadx_module_manager.dnx diff --git a/ports_module/cortex-r4/iar/example_build/tx.ewd b/ports_module/cortex_r4/iar/example_build/tx.ewd similarity index 100% rename from ports_module/cortex-r4/iar/example_build/tx.ewd rename to ports_module/cortex_r4/iar/example_build/tx.ewd diff --git a/ports_module/cortex-r4/iar/example_build/tx.ewp b/ports_module/cortex_r4/iar/example_build/tx.ewp similarity index 100% rename from ports_module/cortex-r4/iar/example_build/tx.ewp rename to ports_module/cortex_r4/iar/example_build/tx.ewp diff --git a/ports_module/cortex-r4/iar/example_build/tx_initialize_low_level.s b/ports_module/cortex_r4/iar/example_build/tx_initialize_low_level.s similarity index 100% rename from ports_module/cortex-r4/iar/example_build/tx_initialize_low_level.s rename to ports_module/cortex_r4/iar/example_build/tx_initialize_low_level.s diff --git a/ports_module/cortex-r4/iar/example_build/txm.ewp b/ports_module/cortex_r4/iar/example_build/txm.ewp similarity index 100% rename from ports_module/cortex-r4/iar/example_build/txm.ewp rename to ports_module/cortex_r4/iar/example_build/txm.ewp diff --git a/ports_module/cortex-r4/iar/example_build/txm_module_preamble.s b/ports_module/cortex_r4/iar/example_build/txm_module_preamble.s similarity index 100% rename from ports_module/cortex-r4/iar/example_build/txm_module_preamble.s rename to ports_module/cortex_r4/iar/example_build/txm_module_preamble.s diff --git a/ports_module/cortex-r4/iar/inc/tx_port.h b/ports_module/cortex_r4/iar/inc/tx_port.h similarity index 100% rename from ports_module/cortex-r4/iar/inc/tx_port.h rename to ports_module/cortex_r4/iar/inc/tx_port.h diff --git a/ports_module/cortex-r4/iar/inc/txm_module_port.h b/ports_module/cortex_r4/iar/inc/txm_module_port.h similarity index 100% rename from ports_module/cortex-r4/iar/inc/txm_module_port.h rename to ports_module/cortex_r4/iar/inc/txm_module_port.h diff --git a/ports_module/cortex-r4/iar/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_r4/iar/module_lib/src/txm_module_thread_shell_entry.c similarity index 100% rename from ports_module/cortex-r4/iar/module_lib/src/txm_module_thread_shell_entry.c rename to ports_module/cortex_r4/iar/module_lib/src/txm_module_thread_shell_entry.c diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_iar.c b/ports_module/cortex_r4/iar/module_manager/src/tx_iar.c similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_iar.c rename to ports_module/cortex_r4/iar/module_manager/src/tx_iar.c diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_context_restore.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_context_restore.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_context_restore.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_context_restore.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_context_save.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_context_save.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_context_save.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_context_save.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_interrupt_control.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_interrupt_control.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_interrupt_control.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_interrupt_control.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_interrupt_disable.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_interrupt_disable.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_interrupt_disable.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_interrupt_disable.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_interrupt_restore.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_interrupt_restore.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_interrupt_restore.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_interrupt_restore.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_irq_nesting_end.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_irq_nesting_end.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_irq_nesting_end.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_irq_nesting_end.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_irq_nesting_start.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_irq_nesting_start.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_irq_nesting_start.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_irq_nesting_start.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_schedule.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_schedule.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_schedule.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_stack_build.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_stack_build.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_stack_build.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_stack_build.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_system_return.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_system_return.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_system_return.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_system_return.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_thread_vectored_context_save.s b/ports_module/cortex_r4/iar/module_manager/src/tx_thread_vectored_context_save.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_thread_vectored_context_save.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_thread_vectored_context_save.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/tx_timer_interrupt.s b/ports_module/cortex_r4/iar/module_manager/src/tx_timer_interrupt.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/tx_timer_interrupt.s rename to ports_module/cortex_r4/iar/module_manager/src/tx_timer_interrupt.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_alignment_adjust.c b/ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_alignment_adjust.c similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_alignment_adjust.c rename to ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_alignment_adjust.c diff --git a/ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_external_memory_enable.c similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_external_memory_enable.c rename to ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_external_memory_enable.c diff --git a/ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c rename to ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_memory_fault_handler.c diff --git a/ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c b/ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c rename to ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_memory_fault_notify.c diff --git a/ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_mm_register_setup.c similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_mm_register_setup.c rename to ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_mm_register_setup.c diff --git a/ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_thread_stack_build.s b/ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_thread_stack_build.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_thread_stack_build.s rename to ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_thread_stack_build.s diff --git a/ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_user_mode_entry.s b/ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_user_mode_entry.s similarity index 100% rename from ports_module/cortex-r4/iar/module_manager/src/txm_module_manager_user_mode_entry.s rename to ports_module/cortex_r4/iar/module_manager/src/txm_module_manager_user_mode_entry.s diff --git a/utility/execution_profile_kit/tx_execution_profile.c b/utility/execution_profile_kit/tx_execution_profile.c new file mode 100644 index 00000000..2054dd15 --- /dev/null +++ b/utility/execution_profile_kit/tx_execution_profile.c @@ -0,0 +1,1039 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Execution Profile Kit */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define TX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "tx_api.h" +#include "tx_execution_profile.h" + +/* Note to developers upgrading from ThreadX version 5: In ThreadX 5, the instruction was to + modify TX_THREAD_EXTENSION_3, and to define the symbol TX_ENABLE_EXECUTION_CHANGE_NOTIFY. + + For ThreadX 6, user no long need to modify TX_THREAD_EXTENSION_3, and shall use the symbol + TX_EXECUTION_PROFILE_ENABLE instead of TX_ENABLE_EXECUTION_CHANGE_NOTIFY. + + For backward compatibiliy reasons, project upgraded from ThreadX 5 may still be able to use + Execution Profile without changes to existing project, users are strongly recommended to + make the change. */ + + +#if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE) + +/* The thread execution profile kit is designed to track thread execution time + based on the hardware timer defined by TX_EXECUTION_TIME_SOURCE and + TX_EXECUTION_MAX_TIME_SOURCE below. When the thread's total time reaches + the maximum value, it remains there until the time is reset to 0 via a call + to tx_thread_execution_time_reset. There are several assumptions to the + operation of this kit, as follows: + + 1. The TX_EXECUTION_TIME_SOURCE and TX_EXECUTION_MAX_TIME_SOURCE macros are + defined to utilize a local hardware time source. + + 2. ThreadX 5.4 (or later) is being used, with the assembly code enabled to + call the following routines from assembly code: + + VOID _tx_execution_thread_enter(void); + VOID _tx_execution_thread_exit(void); + VOID _tx_execution_isr_enter(void); + VOID _tx_execution_isr_exit(void); + + 3. The ThreadX library assembly code must be rebuilt with TX_EXECUTION_PROFILE_ENABLE so + that these macros are expanded in the TX_THREAD structure and so the assembly code macros + are enabled to call the execution profile routines. + + 4. Add tx_execution_profile.c to the application build. */ + + +/* Externally reference several internal ThreadX variables. */ + +extern ULONG _tx_thread_system_state; +extern UINT _tx_thread_preempt_disable; +extern TX_THREAD *_tx_thread_current_ptr; +extern TX_THREAD *_tx_thread_execute_ptr; +extern TX_THREAD *_tx_thread_created_ptr; +extern ULONG _tx_thread_created_count; + + +/* Define the total time for all threads. This is accumulated as each thread's total time is accumulated. */ + +EXECUTION_TIME _tx_execution_thread_time_total; + + +/* Define the ISR time gathering information. This is setup to track total ISR time presently, but + could easily be expanded to track different ISRs. Also, only ISRs that utilize _tx_thread_context_save + and _tx_thread_context_restore are tracked by this utility. */ + +EXECUTION_TIME _tx_execution_isr_time_total; +EXECUTION_TIME_SOURCE_TYPE _tx_execution_isr_time_last_start; + + +/* Define the system idle time gathering information. For idle time that exceeds the range of the timer + source, another timer source may be needed. In addition, the total thread execution time added to the + total ISR time, less the total system time is also a measure of idle time. */ + +EXECUTION_TIME _tx_execution_idle_time_total; +EXECUTION_TIME_SOURCE_TYPE _tx_execution_idle_time_last_start; + + +/* For Cortex-M targets, we need to keep track of nested interrupts internally. */ +#ifdef TX_CORTEX_M_EPK +ULONG _tx_execution_isr_nest_counter = 0; +#endif + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_thread_enter PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is called whenever thread execution starts. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_thread_schedule Thread scheduling */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID _tx_execution_thread_enter(void) +{ + +TX_THREAD *thread_ptr; +EXECUTION_TIME_SOURCE_TYPE last_start_time; +EXECUTION_TIME_SOURCE_TYPE current_time; +EXECUTION_TIME delta_time; +EXECUTION_TIME total_time; +EXECUTION_TIME new_total_time; + + + /* Pickup the current time. */ + current_time = TX_EXECUTION_TIME_SOURCE; + + /* Pickup the current thread control block. */ + thread_ptr = _tx_thread_current_ptr; + + /* This thread is being scheduled. Simply setup the last start time in the + thread control block. */ + thread_ptr -> tx_thread_execution_time_last_start = current_time; + + /* Pickup the last idle start time. */ + last_start_time = _tx_execution_idle_time_last_start; + + /* Determine if idle time is being measured. */ + if (last_start_time) + { + + /* Determine how to calculate the difference. */ + if (current_time >= last_start_time) + { + + /* Simply subtract. */ + delta_time = (EXECUTION_TIME) (current_time - last_start_time); + } + else + { + + /* Timer wrapped, compute the delta assuming incrementing time counter. */ + delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time)); + } + + /* Pickup the total time. */ + total_time = _tx_execution_idle_time_total; + + /* Now compute the new total time. */ + new_total_time = total_time + delta_time; + + /* Determine if a rollover on the total time is present. */ + if (new_total_time < total_time) + { + + /* Rollover. Set the total time to max value. */ + new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE; + } + + /* Now store back the total idle time. */ + _tx_execution_idle_time_total = new_total_time; + + /* Disable the idle time measurement. */ + _tx_execution_idle_time_last_start = 0; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_thread_exit PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is called whenever a thread execution ends. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_thread_system_return Thread exiting */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID _tx_execution_thread_exit(void) +{ + +TX_THREAD *thread_ptr; +EXECUTION_TIME total_time; +EXECUTION_TIME new_total_time; +EXECUTION_TIME_SOURCE_TYPE last_start_time; +EXECUTION_TIME_SOURCE_TYPE current_time; +EXECUTION_TIME delta_time; + + + /* Pickup the current thread control block. */ + thread_ptr = _tx_thread_current_ptr; + + /* Determine if there is a thread. */ + if (thread_ptr) + { + + /* Pickup the current time. */ + current_time = TX_EXECUTION_TIME_SOURCE; + + /* Pickup the last start time. */ + last_start_time = thread_ptr -> tx_thread_execution_time_last_start; + + /* Determine if there is an actual start time. */ + if (last_start_time) + { + + /* Clear the last start time. */ + thread_ptr -> tx_thread_execution_time_last_start = 0; + + /* Determine how to calculate the difference. */ + if (current_time >= last_start_time) + { + + /* Simply subtract. */ + delta_time = (EXECUTION_TIME) (current_time - last_start_time); + } + else + { + + /* Timer wrapped, compute the delta assuming incrementing time counter. */ + delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time)); + } + + /* Pickup the total time. */ + total_time = thread_ptr -> tx_thread_execution_time_total; + + /* Now compute the new total time. */ + new_total_time = total_time + delta_time; + + /* Determine if a rollover on the total time is present. */ + if (new_total_time < total_time) + { + + /* Rollover. Set the total time to max value. */ + new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE; + } + + /* Store back the new total time. */ + thread_ptr -> tx_thread_execution_time_total = new_total_time; + + /* Now accumulate this thread's execution time into the total thread execution time. */ + new_total_time = _tx_execution_thread_time_total + delta_time; + + /* Determine if a rollover on the total time is present. */ + if (new_total_time < _tx_execution_thread_time_total) + { + + /* Rollover. Set the total time to max value. */ + new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE; + } + + /* Store back the new total time. */ + _tx_execution_thread_time_total = new_total_time; + } + + /* Is the system now idle? */ + if (_tx_thread_execute_ptr == TX_NULL) + { + + /* Yes, idle system. Pickup the start of idle time. */ + _tx_execution_idle_time_last_start = TX_EXECUTION_TIME_SOURCE; + } + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_isr_enter PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is called whenever ISR processing starts. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_thread_context_save ISR context save */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID _tx_execution_isr_enter(void) +{ + +TX_THREAD *thread_ptr; +EXECUTION_TIME_SOURCE_TYPE current_time; +EXECUTION_TIME total_time; +EXECUTION_TIME new_total_time; +EXECUTION_TIME_SOURCE_TYPE last_start_time; +EXECUTION_TIME delta_time; + +#ifdef TX_CORTEX_M_EPK + /* Increment the nested interrupt counter. */ + _tx_execution_isr_nest_counter++; +#endif + + /* Determine if this is the first interrupt. Nested interrupts are all treated as + general interrupt processing. */ +#ifdef TX_CORTEX_M_EPK + if ((TX_THREAD_GET_SYSTEM_STATE()) && (_tx_execution_isr_nest_counter == 1)) +#else + if (TX_THREAD_GET_SYSTEM_STATE() == 1) +#endif + { + /* Pickup the current time. */ + current_time = TX_EXECUTION_TIME_SOURCE; + + /* Pickup the current thread control block. */ + thread_ptr = _tx_thread_current_ptr; + + /* Determine if a thread was interrupted. */ + if (thread_ptr) + { + + /* Pickup the last start time. */ + last_start_time = thread_ptr -> tx_thread_execution_time_last_start; + + /* Determine if there is an actual start time. */ + if (last_start_time) + { + + /* Clear the last start time. */ + thread_ptr -> tx_thread_execution_time_last_start = 0; + + /* Determine how to calculate the difference. */ + if (current_time >= last_start_time) + { + + /* Simply subtract. */ + delta_time = (EXECUTION_TIME) (current_time - last_start_time); + } + else + { + + /* Timer wrapped, compute the delta assuming incrementing time counter. */ + delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time)); + } + + /* Pickup the total time. */ + total_time = thread_ptr -> tx_thread_execution_time_total; + + /* Now compute the new total time. */ + new_total_time = total_time + delta_time; + + /* Determine if a rollover on the total time is present. */ + if (new_total_time < total_time) + { + + /* Rollover. Set the total time to max value. */ + new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE; + } + + /* Store back the new total time. */ + thread_ptr -> tx_thread_execution_time_total = new_total_time; + + /* Now accumulate this thread's execution time into the total thread execution time. */ + new_total_time = _tx_execution_thread_time_total + delta_time; + + /* Determine if a rollover on the total time is present. */ + if (new_total_time < _tx_execution_thread_time_total) + { + + /* Rollover. Set the total time to max value. */ + new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE; + } + + /* Store back the new total time. */ + _tx_execution_thread_time_total = new_total_time; + } + } + + /* Has idle time started? */ + else if (_tx_execution_idle_time_last_start) + { + + /* Pickup the last idle start time. */ + last_start_time = _tx_execution_idle_time_last_start; + + /* Determine how to calculate the difference. */ + if (current_time >= last_start_time) + { + + /* Simply subtract. */ + delta_time = (EXECUTION_TIME) (current_time - last_start_time); + } + else + { + + /* Timer wrapped, compute the delta assuming incrementing time counter. */ + delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time)); + } + + /* Pickup the total time. */ + total_time = _tx_execution_idle_time_total; + + /* Now compute the new total time. */ + new_total_time = total_time + delta_time; + + /* Determine if a rollover on the total time is present. */ + if (new_total_time < total_time) + { + + /* Rollover. Set the total time to max value. */ + new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE; + } + + /* Now store back the total idle time. */ + _tx_execution_idle_time_total = new_total_time; + + /* Disable the idle time measurement. */ + _tx_execution_idle_time_last_start = 0; + } + + /* Save the ISR start time. */ + _tx_execution_isr_time_last_start = current_time; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_isr_exit PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is called whenever ISR processing ends. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_thread_context_restore Thread de-scheduling */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID _tx_execution_isr_exit(void) +{ + +TX_THREAD *thread_ptr; +EXECUTION_TIME total_time; +EXECUTION_TIME new_total_time; +EXECUTION_TIME_SOURCE_TYPE last_start_time; +EXECUTION_TIME_SOURCE_TYPE current_time; +EXECUTION_TIME delta_time; + + + /* Determine if this is the first interrupt. Nested interrupts are all treated as + general interrupt processing. */ +#ifdef TX_CORTEX_M_EPK + if ((TX_THREAD_GET_SYSTEM_STATE()) && (_tx_execution_isr_nest_counter == 1)) +#else + if (TX_THREAD_GET_SYSTEM_STATE() == 1) +#endif + { + + /* Pickup the current time. */ + current_time = TX_EXECUTION_TIME_SOURCE; + + /* Pickup the last start time. */ + last_start_time = _tx_execution_isr_time_last_start; + + /* Determine how to calculate the difference. */ + if (current_time >= last_start_time) + { + + /* Simply subtract. */ + delta_time = (EXECUTION_TIME) (current_time - last_start_time); + } + else + { + + /* Timer wrapped, compute the delta assuming incrementing time counter. */ + delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time)); + } + + /* Pickup the total time. */ + total_time = _tx_execution_isr_time_total; + + /* Now compute the new total time. */ + new_total_time = total_time + delta_time; + + /* Determine if a rollover on the total time is present. */ + if (new_total_time < total_time) + { + + /* Rollover. Set the total time to max value. */ + new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE; + } + + /* Store back the new total time. */ + _tx_execution_isr_time_total = new_total_time; + + /* Pickup the current thread control block. */ + thread_ptr = _tx_thread_current_ptr; + + /* Was a thread interrupted? */ + if (thread_ptr) + { + + /* Now determine if the thread will execution is going to occur immediately. */ + if ((thread_ptr == _tx_thread_execute_ptr) || (_tx_thread_preempt_disable)) + { + + /* Yes, setup the thread last start time in the thread control block. */ + thread_ptr -> tx_thread_execution_time_last_start = current_time; + } + } + + /* Determine if the system is now idle. */ + if (_tx_thread_execute_ptr == TX_NULL) + { + + /* Yes, idle system. Pickup the start of idle time. */ + _tx_execution_idle_time_last_start = TX_EXECUTION_TIME_SOURCE; + } + } + +#ifdef TX_CORTEX_M_EPK + /* Decrement the nested interrupt counter. */ + _tx_execution_isr_nest_counter--; +#endif +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_thread_time_reset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the execution time of the specified thread. */ +/* */ +/* INPUT */ +/* */ +/* thread_ptr Pointer to thread */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_thread_time_reset(TX_THREAD *thread_ptr) +{ + + /* Reset the total time to 0. */ + thread_ptr -> tx_thread_execution_time_total = 0; + + /* Return success. */ + return(TX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_thread_total_time_reset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the total thread execution time. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_thread_total_time_reset(void) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *thread_ptr; +UINT total_threads; + + + /* Disable interrupts. */ + TX_DISABLE + + /* Reset the total time to 0. */ + _tx_execution_thread_time_total = 0; + + /* Loop through threads to clear their accumulated time. */ + total_threads = _tx_thread_created_count; + thread_ptr = _tx_thread_created_ptr; + while (total_threads--) + { + thread_ptr -> tx_thread_execution_time_total = 0; + thread_ptr = thread_ptr -> tx_thread_created_next; + } + + /* Restore interrupts. */ + TX_RESTORE + + /* Return success. */ + return(TX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_isr_time_reset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the execution time of the ISR calculation. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_isr_time_reset(void) +{ + + /* Reset the total time to 0. */ + _tx_execution_isr_time_total = 0; + + /* Return success. */ + return(TX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_idle_time_reset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the idle execution time calculation. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_idle_time_reset(void) +{ + + /* Reset the total time to 0. */ + _tx_execution_idle_time_total = 0; + + /* Return success. */ + return(TX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_thread_time_get PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the execution time of the specified thread. */ +/* */ +/* INPUT */ +/* */ +/* thread_ptr Pointer to the thread */ +/* total_time Destination for total time */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_thread_time_get(TX_THREAD *thread_ptr, EXECUTION_TIME *total_time) +{ + + /* Return the total time. */ + *total_time = thread_ptr -> tx_thread_execution_time_total; + + /* Return success. */ + return(TX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_thread_total_time_get PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the execution time of the specified thread. */ +/* */ +/* INPUT */ +/* */ +/* total_time Destination for total time */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_thread_total_time_get(EXECUTION_TIME *total_time) +{ + + /* Return the total time. */ + *total_time = _tx_execution_thread_time_total; + + /* Return success. */ + return(TX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_isr_time_get PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the execution time of ISRs. */ +/* */ +/* INPUT */ +/* */ +/* total_time Destination for total time */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_isr_time_get(EXECUTION_TIME *total_time) +{ + + /* Return the total time. */ + *total_time = _tx_execution_isr_time_total; + + /* Return success. */ + return(TX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_execution_idle_time_get PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the execution time of ISRs. */ +/* */ +/* INPUT */ +/* */ +/* total_time Destination for total time */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _tx_execution_idle_time_get(EXECUTION_TIME *total_time) +{ + + /* Return the total time. */ + *total_time = _tx_execution_idle_time_total; + + /* Return success. */ + return(TX_SUCCESS); +} + + +#endif /* #if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE) */ diff --git a/utility/execution_profile_kit/tx_execution_profile.h b/utility/execution_profile_kit/tx_execution_profile.h new file mode 100644 index 00000000..09ca91a9 --- /dev/null +++ b/utility/execution_profile_kit/tx_execution_profile.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Execution Profile Kit */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +#ifndef TX_EXECUTION_PROFILE_H +#define TX_EXECUTION_PROFILE_H + + +/* The thread execution profile kit is designed to track thread execution time + based on the hardware timer defined by TX_EXECUTION_TIME_SOURCE and + TX_EXECUTION_MAX_TIME_SOURCE below. When the thread's total time reaches + the maximum value, it remains there until the time is reset to 0 via a call + to tx_thread_execution_time_reset. There are several assumptions to the + operation of this kit, as follows: + + 1. The TX_EXECUTION_TIME_SOURCE and TX_EXECUTION_MAX_TIME_SOURCE macros are + defined to utilize a local hardware time source. + + 2. The following routines are called from assembly code: + VOID _tx_execution_thread_enter(void); + VOID _tx_execution_thread_exit(void); + VOID _tx_execution_isr_enter(void); + VOID _tx_execution_isr_exit(void); + + 3. The ThreadX library must be rebuilt with TX_EXECUTION_PROFILE_ENABLE so + the assembly code macros are enabled to call the execution profile routines. + + 4. Add tx_execution_profile.c to the application build. */ + +/* Define the basic time typedefs for 64-bit accumulation and a 32-bit timer source, which is the + most common configuration. */ + +typedef unsigned long long EXECUTION_TIME; +typedef unsigned long EXECUTION_TIME_SOURCE_TYPE; +/* For 64-bit time source, the typedef would be: */ +/* typedef unsigned long long EXECUTION_TIME_SOURCE_TYPE; */ + +/* Define basic constants for the execution profile kit. */ + +/* Example for Cortex-M targets: */ +#ifndef TX_EXECUTION_TIME_SOURCE +#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME_SOURCE_TYPE) *((ULONG *) 0xE0001004) +#endif +#ifndef TX_EXECUTION_MAX_TIME_SOURCE +#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFF +#endif + +/* For 64-bit time source, the constant would be: */ +/*#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME_SOURCE_TYPE) *((unsigned long long *) 0xE0001004) */ +/*#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF */ + + +/* Define APIs of the execution profile kit. */ + +struct TX_THREAD_STRUCT; +VOID _tx_execution_thread_enter(void); +VOID _tx_execution_thread_exit(void); +VOID _tx_execution_isr_enter(void); +VOID _tx_execution_isr_exit(void); +UINT _tx_execution_thread_time_reset(struct TX_THREAD_STRUCT *thread_ptr); +UINT _tx_execution_thread_total_time_reset(void); +UINT _tx_execution_isr_time_reset(void); +UINT _tx_execution_idle_time_reset(void); +UINT _tx_execution_thread_time_get(struct TX_THREAD_STRUCT *thread_ptr, EXECUTION_TIME *total_time); +UINT _tx_execution_thread_total_time_get(EXECUTION_TIME *total_time); +UINT _tx_execution_isr_time_get(EXECUTION_TIME *total_time); +UINT _tx_execution_idle_time_get(EXECUTION_TIME *total_time); + +#endif diff --git a/utility/rtos_compatibility_layers/OSEK/demo_osek.c b/utility/rtos_compatibility_layers/OSEK/demo_osek.c new file mode 100644 index 00000000..625282eb --- /dev/null +++ b/utility/rtos_compatibility_layers/OSEK/demo_osek.c @@ -0,0 +1,157 @@ + +#include + +/************************************************/ +/* Azure RTOS Implementation Specific */ +/************************************************/ + +/* Osek application definition. */ +APPLICATION_INFO Application1; + +/* Task definition. */ +TaskType Task1; + +/* Alarm definition. */ +AlarmType Alarm1; + +/* Resource definition. */ +ResourceType Resource1; + +/* Event definition. */ +EventMaskType Event1; + +/* Counter definition. */ +CounterType SystemTimer; + +/* Demo ISR definition. */ +ISRType DemoISR; + +/* Task body declaration. */ +DeclareTask(Task1); + +/* Demo ISR body declaration. */ +DeclareISR(DemoISR); + +/* User hooks declarations. */ +static void ShutdownHook(StatusType Error); + +static void PreTaskHook(void); + +static void PostTaskHook(void); + +static void StartupHook(void); + +static void ErrorHook(StatusType Error); + + +/* ThreadX timer for demo ISR. */ +TX_TIMER demo_isr_timer; + +/* Entry function for the ThreadX timer. */ +VOID demo_isr_timer_entry(ULONG arg); + + +/* Main function. */ +int main() +{ + + tx_kernel_enter(); + +} +ULONG free_memory[64*1024 / sizeof(ULONG)]; + +VOID tx_application_define(VOID * first_unused_memory) +{ + +CHAR * pointer; + + /* Put the first available address into character pointer. */ + pointer = (CHAR * )free_memory; + + /* Setup hook pointers (optional). */ + Application1.shutdown_hook_handler = ShutdownHook; + Application1.pretask_hook_handler = PreTaskHook; + Application1.posttask_hook_handler = PostTaskHook; + Application1.startup_hook_handler = StartupHook; + Application1.error_hook_handler = ErrorHook; + + /* Initialize a pointer. */ + osek_initialize(pointer,&Application1); + + /* Create the system counter */ + SystemTimer = CreateCounter("SystemTimer", 0x7FFFFFFF, 2, 2, 0); + DefineSystemCounter(SystemTimer); + + /* Create the first Task. */ + Task1 = CreateTask("Task1", TaskEntry(Task1), 3, 1, 1024, NON, TRUE, EXTENDED, 0); + + /* Create an event. */ + Event1 = CreateEvent(); + + /* Register Event1 to Task1. */ + RegisterEventtoTask(Event1 , Task1); + + /* Create a resource. */ + Resource1 = CreateResource("Resource1", STANDARD, 0); + + /* Register Resource1 to Task1. */ + RegisterTasktoResource(Resource1, Task1); + + /* Create a demo ISR triggered by a ThreadX timer. */ + DemoISR = CreateISR("Demo ISR", ISREntry(DemoISR), CATEGORY2, 1024); + + /* Create a ThreadX timer to simulate an ISR. */ + tx_timer_create(&demo_isr_timer, "Demo ISR timer", demo_isr_timer_entry, DemoISR, + 1000, 1000, TX_AUTO_ACTIVATE); + + /* Start OSEK */ + StartOS(OSDEFAULTAPPMODE); + +} + +/* Task body. */ +TASK(Task1) +{ + /* Task body. */ + while(1) + { + } +} + +/* Demo category 2 ISR function body. */ +ISR(DemoISR) +{ + /* ISR body. */ +} + +static void ShutdownHook(StatusType Error) +{ + /* Hook body. */ +} + +static void PreTaskHook(void) +{ + /* Hook body. */ +} + +static void PostTaskHook(void) +{ + /* Hook body. */ +} + +static void StartupHook(void) +{ + /* Hook body. */ +} + +static void ErrorHook(StatusType Error) +{ + /* Hook body. */ +} + +/* ThreadX timer handler to simulate an ISR. */ +VOID demo_isr_timer_entry(ULONG arg) +{ + /* Call OSEK to process the ISR. */ + process_ISR2(arg); +} diff --git a/utility/rtos_compatibility_layers/OSEK/os.h b/utility/rtos_compatibility_layers/OSEK/os.h new file mode 100644 index 00000000..f4c9e96f --- /dev/null +++ b/utility/rtos_compatibility_layers/OSEK/os.h @@ -0,0 +1,941 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** OSEK IMPLEMENTATION */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKV DEFINITIONS RELEASE */ +/* */ +/* os.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc. needed for the */ +/* OSEK implementation. */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef TX_OSEK_H +#define TX_OSEK_H + +#include + +#include "osek_user.h" + +#ifdef TRUE +#undef TRUE +#endif + +#ifdef FALSE +#undef FALSE +#endif + + +/**************************************************************************/ +/* System Macros. */ +/**************************************************************************/ + +#define TASK(Taskname) void Func ## Taskname() +#define TaskEntry(Taskname) Func ## Taskname +#define ALARM(Alarmname) void Func ## Alarmname() +#define ISR(ISRname) void ISR_ ## ISRname() +#define ISREntry(ISRname) ISR_ ## ISRname + +#define ALARMCALLBACK(Alarmcallbackfunction) void Func ## Alarmcallbackfunction() +#define ALARMCALLBACKEntry(Alarmcallbackfunction) Func ## Alarmcallbackfunction +#define DeclareALARMCALLBACK(Alarmcallbackfunction) ALARMCALLBACK(Alarmcallbackfunction) + +#define DeclareISR(ISRname) ISR(ISRname) +#define DeclareResource(Resource_name) +#define DeclareEvent(Event_name) +#define DeclareAlarm(Alarmname) ALARM(Alarmname) +#define DeclareTask(Taskname) TASK(Taskname) + +#define CALL_ISR(ISRname) ISR_ ## ISRname() + +#define OSErrorGetServiceId() service_GetServiceId.id +#define OSError_ActivateTask_TaskID() service_ActivateTask.TaskID +#define OSError_ChainTask_TaskID() service_ChainTask.TaskID +#define OSError_GetAlarm_AlarmID() service_GetAlarm.AlarmID +#define OSError_CancelAlarm_AlarmID() service_CancelAlarm.AlarmID +#define OSError_SetAbsAlarm_AlarmID() service_SetAbsAlarm.AlarmID +#define OSError_SetRelAlarm_AlarmID() service_SetRelAlarm.AlarmID +#define OSError_GetResource_ResID() service_GetResource.ResID +#define OSError_ReleaseResource_ResID() service_ReleaseResource.ResID +#define OSError_SetEvent_TaskID() service_SetEvent.TaskID +#define OSError_GetEvent_TaskID() service_SetEvent.TaskID +#define OSError_WaitEvent_EventID() service_SetEvent.EventID +#define OSError_ClearEvent_EventID() service_ClearEvent.EventID + +/**************************************************************************/ +/* OSEK data Types */ +/**************************************************************************/ + +typedef ULONG STATUS; +typedef void *VP; +typedef void (* FP)(); +typedef ULONG PRI; +typedef ULONG CounterType; +typedef ULONG TaskType; +typedef TaskType ISRType; /* TaskType and ISRType must be same as both often used interchangeably. */ +typedef ULONG TaskStateType; +typedef ULONG *TaskStateRefType; +typedef ULONG *TaskRefType; +typedef ULONG TickType; +typedef ULONG *TickRefType; +typedef ULONG AppModeType; +typedef ULONG AlarmType; +typedef ULONG StatusType; +typedef ULONG OsServiceIdType; +typedef ULONG ResourceType; +typedef ULONG *ResourceRefType; +typedef ULONG EventMaskType; +typedef ULONG *EventMaskRefType; +typedef ULONG EventType; +typedef ULONG *EventRefType; + + +/**************************************************************************/ +/* OSEK Error Codes */ +/**************************************************************************/ + +#define E_OK (0U) +#define E_OS_ACCESS (1U) +#define E_OS_CALLEVEL (2U) +#define E_OS_ID (3U) +#define E_OS_LIMIT (4U) +#define E_OS_NOFUNC (5U) +#define E_OS_RESOURCE (6U) +#define E_OS_STATE (7U) +#define E_OS_VALUE (8U) + + +/* Additional error codes defined for this Implementation. */ + +#define E_OS_EVENT (9U) +#define E_OS_EXIST (10U) /* identical task name are found. */ +#define E_OS_SYSTEM (11U) /* Error for the OSEK system. */ +#define E_OS_SYS_STACK (12U) /* Error For OSEK Memory. */ + +/* osek_internal_error() error codes. */ + +#define THREADX_OBJECT_CREATION_ERROR (1U) +#define THREADX_THREAD_RESUME_IN_ACTIVATE_TASK (2U) +#define THREADX_PREEMPTION_CHANGE_GETRESOURCE (3U) +#define THREADX_PREEMPTION_CHANGE_RLSRESOURCE (4U) +#define THREADX_THREAD_TERMINATE_TERMINATETASK (5U) +#define THREADX_THREAD_DELETE_TERMINATETASK (6U) +#define THREADX_THREAD_TERMINATE_CHAINTASK (7U) +#define THREADX_THREAD_DELETE_CHAINTASK (8U) +#define THREADX_THREAD_DELETE_DELETETASK (9U) +#define THREADX_THREAD_TERMINATE_DELETETASK (10U) +#define THREADX_PREEMPTION_CHANGE_WRAPPER (11U) +#define THREADX_THREAD_RELINQUISH_SCHEDULE (12U) +#define THREADX_MUTEX_CREATERESOURCE (13U) +#define THREADX_EVENT_SETEVENT (14U) +#define THREADX_EVENT_CLEAREVENT (15U) +#define THREADX_EVENT_FLAG_GETEVENT (16U) +#define THREADX_EVENT_FLAG_WAITEVENT (17U) +#define QUEUE_DELETETASK (18U) +#define NO_FREE_EVENT (20U) +#define SYSMGR_FATAL_ERROR (21U) +#define EVENT_DELETETASK (22U) +#define ERROR_FREEING_MEMORY (23U) +#define SYS_MGR_SEND_CHAINTASK (24U) +#define SYS_MGR_SEND_TERMINATETASK (25U) +#define INVALID_ALARMID_TIMERWRAPPER (26U) +#define TASK_ENDING_WITHOUT_CHAIN_OR_TERMINATE (27U) +#define SYSMGR_QUEUE_SEND (28U) +#define INVALID_OBJECT_CREATION_CALL (29U) +#define SYS_MGR_START_OS (30U) +#define SYS_MGR_SEND_ACTIVATETASK (31U) +#define ERROR_OBJECT_CREATION (32U) + + +/**************************************************************************/ +/* OSEM SYSTEM SERVICES IDs */ +/**************************************************************************/ + +#define OSServiceId_ActivateTask (1U) +#define OSServiceId_TerminateTask (2U) +#define OSServiceId_ChainTask (3U) +#define OSServiceId_Schedule (4U) +#define OSServiceId_GetTaskID (5U) +#define OSServiceId_GetTaskState (6U) +#define OSServiceId_DisableAllInterrupts (7U) +#define OSServiceId_EnableAllInterrupts (8U) +#define OSServiceId_SuspendAllInterrupts (9U) +#define OSServiceId_ResumeAllInterrupts (10U) +#define OSServiceId_SuspendOSInterrupts (11U) +#define OSServiceId_ResumeOSInterrupts (12U) +#define OSServiceId_GetResource (13U) +#define OSServiceId_ReleaseResource (14U) +#define OSServiceId_SetEvent (15U) +#define OSServiceId_ClearEvent (16U) +#define OSServiceId_GetEvent (17U) +#define OSServiceId_WaitEvent (18U) +#define OSServiceId_GetAlarmBase (19U) +#define OSServiceId_GetAlarm (20U) +#define OSServiceId_SetRelAlarm (21U) +#define OSServiceId_SetAbsAlarm (22U) +#define OSServiceId_CancelAlarm (23U) +#define OSServiceId_GetActiveApplicationMode (24U) +#define OSServiceId_StartOS (25U) +#define OSServiceId_ShutdownOS (26U) + + +/**************************************************************************/ +/* Implementation Specific OSEK operating modes */ +/* */ +/**************************************************************************/ + +#define NORMAL_EXECUTION_MODE (0U) +#define STARTUPHOOK_MODE (1U) +#define SHUTDOWNHOOK_MODE (2U) +#define PRETASKHOOK_MODE (3U) +#define POSTTASKHOOK_MODE (4U) +#define ERRORHOOK_MODE (5U) +#define ISR1_MODE (6U) +#define ISR2_MODE (7U) +#define TIMER_MODE (8U) +#define INITSYSTEM_MODE (9U) +#define ALARM_CALLBACK_MODE (10U) +#define OSEK_INIT_NOT_DONE (99U) + + +/**************************************************************************/ +/* OSEK Constants and Definitions */ +/**************************************************************************/ + +/* OS APPLICATION MODES */ + +#define OSDEFAULTAPPMODE (1U) + + +/* OSEK Task Types */ + +#define EXTENDED (1U) +#define BASIC (0U) +#define TRUE (1U) +#define FALSE (0U) + + +/* OSEK Task States */ + +#define RUNNING (0U) +#define WAITING (1U) +#define READY (2U) +#define SUSPENDED (3U) +#define THREADX_STATE (4U) + +/* Invalid task id */ +#define INVALID_TASK (0U) + + +/* ALARM OPERATION MODES */ + +#define ABSOLUTE_ALARM (1U) +#define RELATIVE_ALARM (0U) +#define AUTO_START (1U) +#define NO_START (0U) + + +/* RESOURCE TYPE */ + +#define STANDARD (0U) +#define INTERNAL (1U) +#define LINKED (2U) + +typedef enum {NON, FULL} SCHEDULE; +typedef enum {ACTIVATETASK, SETEVENT, CALLBACK, NONE} ACTION; +typedef ULONG ACCR_TYPE; +typedef ULONG TASK_TYPE; +typedef ULONG COPY; +typedef ULONG AUTOSTART; + + +/* ISR types */ + +#define CATEGORY1 (1U) +#define CATEGORY2 (2U) + + +/**************************************************************************/ +/* SYSTEM CONFIGURATION PARAMETERS */ +/**************************************************************************/ + +/* OSEK Priority Definitions */ + +#define THREADX_MAX_PRIORITY (31U) +#define THREADX_HIGHEST_PRIORITY (0U) +#define THREADX_LOWEST_PRIORITY (31U) + +#define OSEK_MAX_PRIORITY (23U) +#define OSEK_HIGHEST_PRIORITY (OSEK_MAX_PRIORITY) +#define OSEK_LOWEST_PRIORITY (0U) + +#define OSEK_NON_SCHEDULE_PRIORITY (OSEK_HIGHEST_PRIORITY + 1u) /* 24 */ +#define OSEK_ISR2_PRIORITY (OSEK_NON_SCHEDULE_PRIORITY + 1u) /* 25 */ +#define OSEK_ISR1_PRIORITY (OSEK_ISR2_PRIORITY + 1u) /* 26 */ + + +/* Define maximum queued activation per task */ + +#define OSEK_MAX_ACTIVATION (8U) + +/* Define maximum time count for Counters / Alarms */ + +#define MAXALLOWEDVALUE (0x7FFFFFFFUL) + +#define OSEK_STACK_PADDING (128U) +#define OSEK_SYSTEM_STACK_SIZE (1024U) + + +/* Requests/commands to SysMgr task. */ + +#define SYSMGR_START_OS (0U) +#define SYSMGR_TERMINATE_TASK (1U) +#define SYSMGR_CHAIN_TASK (2U) +#define SYSMGR_ACTIVATE_TASK (3U) +#define SYSMGR_SCHEDULE (4U) +#define SYSMGR_WAITEVENT (5U) +#define SYSMGR_RELEASE_RESOURCE (6U) +#define SYSMGR_SETEVENT (7U) +#define SYSMGR_SHUTDOWN_OS (8U) +#define SYSMGR_ERRORHOOK (9U) +#define SYSMGR_GET_RESOURCE (10U) + +/**************************************************************************/ +/* Define size of Region 0 memory segment. */ +/* NOTE: This region should be large enough to supply the memory */ +/* for all task stacks, TCBs, thread control blocks in the system. */ +/**************************************************************************/ + +#define TX_REGION0_SIZE (OSEK_MEMORY_SIZE) +#define TX_REGION0_SIZE_IN_BYTES (TX_REGION0_SIZE) + + +/**********************************************************************************/ +/* OSEK System Object maximum numbers */ +/* NOTE: These are only suggested values, user may modify them as needed. */ +/* Memory is the only limiting factor. */ +/**********************************************************************************/ + +/* Define the maximum number of simultaneous OSEK tasks supported. */ +/* Interrupt Service Routines are also treated as a task. */ +/* Total 8 Interrupt sources are supported. */ +/* That gives 24 max OSEK tasks. */ + +#define OSEK_MAX_TASKS (32U) + +/* Define the maximum number of simultaneous Internal OSEK Resources supported. */ + +#define OSEK_MAX_INTERNAL_RES (8U) + + +/* Define the maximum number of simultaneous External OSEK Resources supported. */ + +#define OSEK_MAX_EXTERNAL_RES (16U) + + +/* Define the maximum number of simultaneous OSEK Resources (Internal & External Combined) supported. */ + +#define OSEK_MAX_RES (OSEK_MAX_INTERNAL_RES + OSEK_MAX_EXTERNAL_RES) + + +/* Define the maximum number of simultaneous OSEK alarms supported. */ + +#define OSEK_MAX_ALARMS (16U) + + +/* Define the maximum number of simultaneous OSEK counters supported. */ +/* This includes a counter to be assigned as a SystemTimer. */ +/* A system can have 8 alarms so 8 counters (one counter for each alarm) would be enough. */ + +#define OSEK_MAX_COUNTERS (16U) + + +/* Define the maximum number of simultaneous OSEK events supported. */ +/* An event is just a bit , so a ULONG (32 bit data type) is used. */ + +#define OSEK_MAX_EVENTS (32U) + + +/* Define the maximum number of OSEK ISR sources supported. */ + +#define OSEK_MAX_ISR (8U) + + +/* Define OSEK Internal Task Queue depth per priority. */ +/* There is one such queue for each priority level. */ +/* What is the maximum number of tasks that can go in a queue? */ +/* Assuming that all tasks are of same priority and each task is activated to maximum */ +/* allowable limits (OSEK_MAX_ACTIVATION) it should be OSEK_MAX_ACTIVATION * OSEK_MAX_TASKS */ +/* but sometimes (READY)tasks are moved from queue to queue based on its changed ceiling priority */ +/* and that number could be equal to to maximum number of tasks supported. */ + +#define TASK_QUEUE_DEPTH1 (OSEK_MAX_ACTIVATION * OSEK_MAX_TASKS) +#define TASK_QUEUE_DEPTH (TASK_QUEUE_DEPTH1 + OSEK_MAX_TASKS) + +#define SYSMGR_QUEUE_MSG_LENGTH (4U) +#define SYSMGR_QUEUE_MSG_COUNT (OSEK_MAX_ALARMS) +#define SYSMGR_QUEUE_DEPTH ((sizeof(ULONG)) * SYSMGR_QUEUE_MSG_COUNT) + +#define SYSMGR_PRIORITY (0U) +#define SYSMGR_THRESHOLD (0U) + + +/**********************************************************************************/ +/* OSEK System Object identifier this is placed in the object's control structure */ +/**********************************************************************************/ + +#define OSEK_TASK_ID (0x1234ABCDUL) +#define OSEK_ALARM_ID (0x4567ABCDUL) +#define OSEK_COUNTER_ID (0xABCD1234UL) +#define OSEK_EVENT_ID (0x1234FEDCUL) +#define OSEK_RES_ID (0x5678CDEFUL) +#define OSEK_APPLICATION_ID (0x789ABCDEUL) +#define OSEK_ISR_ID (0x3456CDEFUL) + + +/**************************************************************************/ +/* OSEK SYSTEM OBJECT CONTROL STRUCTURES */ +/**************************************************************************/ + + +/* OSEK SERVICES */ + +struct Service_ActivateTask +{ + StatusType TaskID; +}; + +struct Service_TerminateTask +{ + StatusType TaskID; +}; + +struct Service_ChainTask +{ + StatusType TaskID; +}; + +struct Service_Schedule +{ + StatusType TaskID; +}; + +struct Service_GetTaskID +{ + TaskRefType TaskID; +}; + +struct Service_GetTaskState +{ + StatusType TaskID; +}; + +struct Service_DisableAllInterrupts +{ + StatusType TaskID; +}; + +struct Service_EnableAllInterrupts +{ + StatusType TaskID; +}; + +struct Service_SuspendAllInterrupts +{ + StatusType TaskID; +}; + +struct Service_ResumeAllInterrupts +{ + StatusType TaskID; +}; + +struct Service_SuspendOSInterrupts +{ + StatusType TaskID; +}; + +struct Service_ResumeOSInterrupts +{ + StatusType TaskID; +}; + +struct Service_GetResource +{ + ResourceType ResID; +}; + +struct Service_ReleaseResource +{ + ResourceType ResID; +}; + +struct Service_SetEvent +{ + StatusType EventID; + TaskType TaskID; +}; + +struct Service_ClearEvent +{ + EventMaskType EventID; +}; + +struct Service_GetEvent +{ + StatusType EventID; + TaskType TaskID; +}; + +struct Service_WaitEvent +{ + EventMaskType EventID; +}; + +struct Service_GetAlarmBase +{ + AlarmType AlarmID; +}; + +struct Service_GetAlarm +{ + AlarmType AlarmID; +}; + +struct Service_SetRelAlarm +{ + AlarmType AlarmID; + TickType increment; + TickType cycle; +}; + +struct Service_SetAbsAlarm +{ + AlarmType AlarmID; + TickType start; + TickType cycle; +}; + +struct Service_CancelAlarm +{ + AlarmType AlarmID; +}; + +struct Service_GetActiveApplicationMode +{ + StatusType TaskID; +}; + +struct Service_StartOS +{ + StatusType TaskID; +}; + +struct Service_ShutdownOS +{ + StatusType TaskID; +}; + +struct Service_GetServiceId +{ + OsServiceIdType id; +}; + + +/**************************************************************************/ +/* OSEK Resource */ +/**************************************************************************/ + +typedef struct osek_resource_struct +{ + /* Name. */ + const CHAR *name; + + /* This Resource is in use. */ + ULONG res_in_use; + + /* Ceiling priority of the resource. */ + UINT c_priority; + + /* Task occupying this resource. */ + TaskType taskid; + + /* Type. */ + StatusType type; /* Internal, External, Linked. */ + + /* Linked Resource. */ + + ResourceType linked_res; /* id of the resource , Linked with this res. */ + + ResourceType resolved_res; /* Id of the res linked to this , after all chained links. */ + + /* Resource Object id. */ + ULONG osek_res_id; + +} OSEK_RESOURCE; + + +/**************************************************************************/ +/* Task structure */ +/**************************************************************************/ + +typedef struct osek_tcb_struct +{ + /* This task's ThreadX TCB. */ + TX_THREAD task; + + /* Name. */ + const CHAR *name; + + /* This field indicates if this task is in use. */ + ULONG tcb_in_use; + + /* Task type BASIC or EXTENDED. */ + UINT task_type; + + /* Task AUTOSTART mode. */ + UINT task_autostart; + + /* Design time Scheduling policy of this Task. */ + SCHEDULE policy; + + /* Task start address (entry point). */ + FP task_entry; + + /* Design time task priority. */ + UINT org_prio; + + + /* Current ThreadX thread preemption threshold. */ + UINT cur_threshold; + + /* task stack size. */ + ULONG stack_size; + + /* start address of the task stack. */ + CHAR *pStackBase; + + + /* Task status Suspended/ Ready(Running). */ + ULONG suspended; + + /* Wait status */ + ULONG waiting; + + /* Task to be activated when this task calls ChainTask(). */ + TaskType task_to_chain; + + /* Counter to indicate how many Resources are occupied. */ + ULONG res_ocp; + + /* Maximum multiple activation allowed for this task. */ + UINT max_active; + + /* Current (recorded) multiple activation requests. */ + UINT current_active; + + /* List of Event assigned to this task. */ + EventMaskType events; + + EventMaskType waiting_events; + + EventMaskType set_events; + + /* List of External resources assigned (Design time) to this task. */ + ResourceType external_resource_list[OSEK_MAX_EXTERNAL_RES]; + + /* List of External Resources currently occupied (Run time) by this task. */ + ResourceType external_resource_occuplied_list[OSEK_MAX_EXTERNAL_RES]; + + /* List of Internal resources assigned (Design Time) to this task. */ + ResourceType internal_resource_list[OSEK_MAX_INTERNAL_RES]; + + /* List of Internal Resources currently occupied (Run Time) by this task. */ + ResourceType internal_resource_occuplied_list[OSEK_MAX_INTERNAL_RES]; + + /* Internal Resource assigned or not. */ + UINT internal_res; + + /* RES_SCHEDULER taken or not. */ + UINT resource_scheduler; + + AppModeType task_Appl_Mode; + + /* Task Object id. */ + ULONG osek_task_id; + +} OSEK_TCB; + + +/**************************************************************************/ +/* Counter */ +/**************************************************************************/ + +typedef struct OSEK_COUNTER_STRUCT +{ + + /* Max. allowable value. */ + TickType maxallowedvalue; + + /* Tick base multiplier. */ + TickType ticksperbase; + + /* Minimum cyclic numbers of counter ticks allowed for a cyclic alarm. */ + TickType mincycle; + + /* Name. */ + const CHAR* name; + + /* This field indicates if this counter is in use. */ + UINT cntr_in_use; + + /* Pre-count needed to increment main count by 1. */ + TickType sub_count; + + /* Current counter value in ticks. */ + TickType counter_value; + + /* Whether attached to system timer. */ + UINT system_timer; + + /* List of all alarms attached to this counter. */ + AlarmType alarm_list[OSEK_MAX_ALARMS]; + + /* Counter object id. */ + ULONG osek_counter_id; + + +}OSEK_COUNTER; + + +/**************************************************************************/ +/* ALARM */ +/**************************************************************************/ + +typedef struct OSEK_ALARM_STRUCT +{ + + /* Name. */ + const CHAR* name; + + /* This field indicates if this entry is in use. */ + UINT alarm_in_use; + + UINT occupied; + + /* Max allowed value of count for this alarm depends on the counter to which this alarm is attached. */ + TickType max_allowed_value; + + /* Cycles programmed depends on the counter to which this alarm is attached. */ + TickType min_cyc; + + /* Tick base multiplier. */ + TickType ticks_per_base; + + /* Cycles programmed for this alarm. */ + TickType cycle; + + /* alarm expiration count. */ + + TickType expiration_count; + + /* Alarm Callback function. */ + void (*alarm_callback)(); + + /* Alarm Activation. */ + UINT armed; + + /* Alarm Action. */ + UINT action; + + /* Attach task here. */ + OSEK_TCB* task; + + /* Attach the counter. */ + OSEK_COUNTER *cntr; + + /* Event to set in case of SET_EVENT action. The event bits should be 1 + to SET that EVENT of the task. */ + EventMaskType events; + + /* Start up action. */ + UINT auto_start; + + /* ALARM armed in relative mode or abs mode. */ + UINT rel_abs_mode; + + /* Counter roll back flag for absolute alarm mode. */ + UINT counter_rollback; + + /* Alarm object id. */ + ULONG osek_alarm_id; + +} OSEK_ALARM; + + +typedef struct USER_ALARM_STRUCT +{ + + /* Max allowed value of count. */ + TickType maxallowedvalue; + + /* Cycles. */ + TickType mincycle; + + /* Tick base multiplier. */ + TickType ticksperbase; + +}AlarmBaseType; + +typedef AlarmBaseType *AlarmBaseRefType; + + +typedef struct REGISTER_APPLICATION_STRUCT +{ + + AppModeType application_mode; + + /* ErrorHook. */ + void (*error_hook_handler)(StatusType); + /* Startup hook. */ + void (*startup_hook_handler)(); + /* Shutdown Hook. */ + void (*shutdown_hook_handler)(StatusType); + + void (*pretask_hook_handler)(void); + + void (*posttask_hook_handler)(void); + + /* Any errors generated while creating the application. */ + StatusType osek_object_creation_error; + + + /* Application object ID. */ + ULONG osek_application_id; + + +}APPLICATION_INFO; + +typedef APPLICATION_INFO *APPLICATION_INFO_PTR; + + +/**************************************************************************/ +/* OSEK API CALLS */ +/**************************************************************************/ + + +/* TASK MANAGEMENT */ + +StatusType ActivateTask(TaskType TaskId); +StatusType GetTaskID(TaskType *TaskID); +StatusType TerminateTask(void); +StatusType ChainTask(TaskType TaskID); +StatusType GetTaskState(TaskType TaskID, TaskStateRefType State); +TaskType CreateTask(const CHAR *name, void(*entry_function)(), UINT priority, UINT max_activation, + ULONG stack_size, SCHEDULE policy, AUTOSTART start, UINT, AppModeType mode); +StatusType Schedule (void); + + +/* RESOURCE MANAGEMENT */ + +ResourceType CreateResource(const CHAR *name, StatusType type, ResourceType linked_res); +StatusType GetResource(ResourceType id); +StatusType ReleaseResource(ResourceType id); +StatusType RegisterTasktoResource(ResourceType Resource, TaskType TaskID); + +/* EVENT MANAGEMENT */ + +StatusType SetEvent(TaskType task_id, EventMaskType mask); +StatusType ClearEvent(EventMaskType mask); +StatusType GetEvent(TaskType task_id, EventMaskRefType event); +StatusType WaitEvent(EventMaskType mask); +EventMaskType CreateEvent(void); +StatusType RegisterEventtoTask(EventType eventid, TaskType TaskID); + +/* INTERUUPT MANAGEMENT */ + +StatusType EnableInterrupt(void); +StatusType DisableInterrupt(void); + +StatusType GetInterruptDescriptor(UINT *mask); + +void SuspendAllInterrupts(void); +void ResumeAllInterrupts(void); + +void SuspendOSInterrupts(void); +void ResumeOSInterrupts(void); + +void DisableAllInterrupts(void); +void EnableAllInterrupts(void); + +ISRType CreateISR(const CHAR *name, void(*entry_function)(), UINT category, ULONG stack_size); +StatusType RegisterISRtoResource(ResourceType Resource, ISRType ISRID); + + +/* COUNTER MANAGEMENT */ + +StatusType GetCounterValue(OSEK_COUNTER *counter_ptr, TickRefType ticks); +CounterType CreateCounter(const CHAR *name, TickType max_allowed_value, TickType ticks_per_base, + TickType min_cycle, TickType start_value); +StatusType IncrCounter(CounterType cntr); +StatusType DefineSystemCounter(CounterType cntr); + +/* ALARM MANAGEMENT */ + +StatusType GetAlarmBase(AlarmType AlarmID, AlarmBaseRefType info); +StatusType SetAbsAlarm(AlarmType AlarmID, TickType start, TickType cycle); +StatusType SetRelAlarm(AlarmType AlarmID, TickType increment, TickType cycle); +StatusType CancelAlarm(AlarmType AlarmID); +StatusType GetAlarm(AlarmType AlarmID, TickRefType tick_ptr); +AlarmType CreateAlarm(const CHAR *name, CounterType cntr, UINT action, ULONG events, + TaskType task, void (*callback)(), UINT Startup, TickType Alarmtime, TickType Cycle); + +/* OS MANAGEMENT */ + +UCHAR *osek_initialize(void *osek_memory, APPLICATION_INFO_PTR application1); +UINT osek_cleanup(APPLICATION_INFO_PTR application1); +void ShutdownOS(StatusType error); +void StartOS(StatusType os_mode); +AppModeType GetActiveApplicationMode(void); + + +void process_ISR2(ISRType isrname); + +#endif + + +/******************************* End of file ************************/ diff --git a/utility/rtos_compatibility_layers/OSEK/osek_user.h b/utility/rtos_compatibility_layers/OSEK/osek_user.h new file mode 100644 index 00000000..6209a16e --- /dev/null +++ b/utility/rtos_compatibility_layers/OSEK/osek_user.h @@ -0,0 +1,54 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** OSEK User Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKV DEFINITIONS RELEASE */ +/* */ +/* osek_user.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This files contains user configurable compile time paramteres for */ +/* the OSEK implementation. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef OSEK_USER_H +#define OSEK_USER_H + +/* Set the size of the OSEK memory available for creating OSEK objects and tasks. */ +#define OSEK_MEMORY_SIZE (64U*1024U) + +#endif + +/******************************* End of file ************************/ diff --git a/utility/rtos_compatibility_layers/OSEK/threadx_osek_readme.txt b/utility/rtos_compatibility_layers/OSEK/threadx_osek_readme.txt new file mode 100644 index 00000000..dd1e1209 --- /dev/null +++ b/utility/rtos_compatibility_layers/OSEK/threadx_osek_readme.txt @@ -0,0 +1,277 @@ + Azure RTOS' OSEK compatibility layer for ThreadX + +1. Installation + +The OSEK compatibility layer for ThreadX is comprised of two files tx_osek.c and os.h +which should be copied at a suitable location for inclusion into a ThreadX project. Refer +to the ThreadX readme file for installation instructions for ThreadX. + + +2. Building + +Building the OSEK layer should be as simple as including the tx_osek.c and os.h file to +an existing ThreadX project, making sure that the location of the os.h header is in the +include paths. The OSEK layer requires that the ThreadX headers such as tx_api.h are +reachable in the include paths as well. + + +3. Initialization + +The OSEK layer initialization can be performed either from the tx_application_define() +during the ThreadX initialization or from a running ThreadX thread. It is strongly +recommended to initialize and start the OSEK layer as soon as possible. Once started +other ThreadX tasks and API call should not be used to prevent resource conflicts with +OSEK. + +The OSEK initialization has three phases. First the osek internal initialization which +must be performed before calling any other OSEK API functions, by calling +osek_initialize() passing it a pointer to the OSEK memory and the application structure. +The size of the memory region passed to osek_initialize() must be set at compile time +by adjusting the OSEK_MEMORY_SIZE define in osek_uart.h. + +After having initialized the OSEK internally, the application can now create OSEK objects +and link or assigned them as needed. See below for a list of object creation functions. + +Finally, after all the objects are created and configured the OSEK layer can be started +using StartOS(). Once started it is no longer possible to create or change any OSEK +objects. + + +4. OSEK shutdown and restart + +The OSEK layer can be shutdown using the standard OSEK API ShutdownOS(). As an extension +to the OSEK layer offers an osek_cleanup() function which can be used to cleanup and +reset the OSEK layer allowing a subsequent restart without having to reset the CPU. This +is primarily intended for testing. + + +5. Hooks + +The various hook routines available within OSEK can be set during initialization by +setting the various handler members of the APPLICATION_INFO structure passed to +osek_initialize(). See the OSEK documentation for the signature of those hook functions. + +For example: + + app.error_hook_handler = ErrorHook; + app.startup_hook_handler = StartupHook; + app.shutdown_hook_handler = ShutdownHook; + app.pretask_hook_handler = PreTaskHook; + app.posttask_hook_handler = PostTaskHook; + + +6. Interrupts + +As per the OSEK specification, category 1 ISRs are not affected by the OSEK layer +execution and are not allowed to call any of the OSEK API. Those ISR are configured and +processed just like any other interrupts under ThreadX. Category 2 ISR have to be +created using CreateISR() as well as being registered and enable like a category 1 ISR. +In the body of the low level ISR process_ISR2() must be called with the return value of +the corresponding CreateISR() in argument. This will instruct the OSEK layer to schedule +the category 2 ISR as soon as possible. + +A category 2 ISR is made of two handlers, the one that process the hardware interrupt +and the OSEK ISR body. + +To define a category 2 ISR body use the standard ISR() macro as follows: + + +ISRType DemoISR; /* ISR declaration. */ + +/* ISR body definition. */ +ISR(DemoISR) +{ + /* ISR body. */ +} + + +This ISR should be created during system initialization: + + +DemoISR = CreateISR("Demo ISR", ISREntry(DemoISR), CATEGORY2, 1024); + + +Once properly initialized the ISR can be triggered by calling process_ISR2 with the ISR +name in argument from within the hardware ISR handler. + + +void demo_isr_hardware_handler(void) +{ + /* Call OSEK to process the ISR. */ + process_ISR2(DemoISR); +} + + +7. Implementation specific information + +Since OSEK requires a static allocation methodology, the number of available OSEK object +has to be limited at compile time. By default the following limits apply: + +Maximum number of tasks: 32 +Maximum number of internal resources: 8 +Maximum number of external resources: 16 +Maximum number of alarms: 16 +Maximum number of counters: 16 +Maximum number of events: 32 +Maximum number of category 2 ISRs: 8 +Minimum OSEK task priority: 0 +Maximum OSEK task priority: 23 +Maximum alarm counter value: 0x7FFFFFFFUL +Maximum task activation count: 8 + +8. Supported OSEK API + +The ThreadX OSEK layer supports all the mandatory APIs specified in version 2.2.3 of +the OSEK/VDK Operating System Specification. + +Summary of the supported API, see the OSEK specification and tx_osek.c for the full +details of each API. + +TASK MANAGEMENT + +DeclareTask +ActivateTask +TerminateTask +ChainTask +Schedule +GetTaskID +GetTaskState + +INTERRUPT HANDLING + +EnableAllInterrupts +DisableAllInterrupts +ResumeAllInterrupts +SuspendAllInterrupts +ResumeOSInterrupts +SuspendOSInterrupts + +RESOURCE MANAGEMENT + +DeclareResource +GetResource +ReleaseResource + +EVENT CONTROL + +DeclareEvent +SetEvent +ClearEvent +GetEvent +WaitEvent + +ALARMS + +DeclareAlarm +GetAlarmBase +GetAlarm +SetRelAlarm +SetAbsAlarm +CancelAlarm + +EXECUTION CONTROL + +GetActiveApplicationMode +StartOS +ShutdownOS + +Hook Routines + +ErrorHook +PreTaskHook +PostTaskHook +StartupHook +ShutdownHook + +9. Object creation API + +The various object creation and registration functions are as follows. See tx_osek.c for a +detailed description of each function. + +---- +CreateTask – Creates an OSEK task, the task is returned if successful. + + TaskType CreateTask(CHAR *name, + void(*entry_function)(), + UINT priority, + UINT max_activation, + ULONG stack_size, + SCHEDULE policy, + AUTOSTART start, + UINT type, + AppModeType mode); + + +---- +CreateResource - Creates an OSEK resource, the resource is returned if successful. + + ResourceType CreateResource(const CHAR *name, + StatusType type, + ResourceType linked_res); + + +---- +RegisterTasktoResource - Registers a task to a resource. The resource will be accessible +by the registered task. + + StatusType RegisterTasktoResource(ResourceType Resource, + TaskType TaskID); + + +---- +CreateEvent - Creates an event, the created event is returned if successful. Note that +per the OSEK specification an absolute maximum of 32 events can be created. + + EventMaskType CreateEvent(void); + + +---- +RegisterEventtoTask - Register an event to a task. The event is now usable from that +task. Note that an event can only be registered to a single task. + + StatusType RegisterEventtoTask(EventType eventid, + TaskType TaskID); + + +---- +CreateISR - Creates an ISR. + + ISRType CreateISR(const CHAR *name, + void(*entry_function)(), + UINT category, + ULONG stack_size); + + +---- +RegisterISRtoResource - Register an ISR to a resource. Note that ISR cannot be registered +to category 1 ISRS. + + StatusType RegisterISRtoResource(ResourceType Resource, + ISRType ISRID); + + +---- +CreateCounter - Creates a new counter. + + CounterType CreateCounter(CHAR *name, + TickType max_allowed_value, + TickType ticks_per_base, + TickType min_cycle, + TickType start_value); + +---- +DefineSystemCounter - Assign a counter to be used as the system counter. + + StatusType DefineSystemCounter(CounterType cntr); + +--- +CreateAlarm - Creates an alarm. + +AlarmType CreateAlarm(CHAR *name, + CounterType cntr, + UINT action, + ULONG events, + TaskType task, + void (*callback)(), + UINT Startup, TickType Alarmtime, + TickType Cycle); diff --git a/utility/rtos_compatibility_layers/OSEK/tx_osek.c b/utility/rtos_compatibility_layers/OSEK/tx_osek.c new file mode 100644 index 00000000..4ac360b0 --- /dev/null +++ b/utility/rtos_compatibility_layers/OSEK/tx_osek.c @@ -0,0 +1,9113 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** OSEK IMPLEMENTATION */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary files. */ + +#include "os.h" + +/* Include some required internal headers. */ + +#include +#include +#include + + +/* Declare a structure to hold application information. */ + +APPLICATION_INFO_PTR Application; + + +/* Define a global variable to hold operating mode of this wrapper. */ + +static UINT osek_wrapper_operation_mode = OSEK_INIT_NOT_DONE; + + +/* Define the threads for the System Manager. */ + +TX_THREAD osek_system_manager; + + +/* Define ThreadX message queues for System Manager. */ + +TX_QUEUE osek_work_queue; + + +/* Define a byte pool control block for the osek region0 memory used. */ + +TX_BYTE_POOL osek_region0_byte_pool; + + +/* Define ThreadX timer to act as a system timer. */ + +TX_TIMER osek_system_timer; + + +/************ OSEK System objects Definitions **************/ + +/* Define a static pool of Task structures. */ + +static OSEK_TCB osek_tcb_pool[OSEK_MAX_TASKS]; + + +/* Define a static pool of resource structures. */ + +static OSEK_RESOURCE osek_res_pool[OSEK_MAX_RES]; + + +/* Defines a static pool of alarm structures. */ + +static OSEK_ALARM osek_alarm_pool[OSEK_MAX_ALARMS]; + + +/* Defines a static pool of counter structures. */ + +static OSEK_COUNTER osek_counter_pool[OSEK_MAX_COUNTERS]; + + +/* Define a Task Ready Queue. */ +/* For each OSEK priority there is a sub queue, each queue entry holds an id of a task ready to run. */ + +TaskType task_table [OSEK_ISR1_PRIORITY + 1u][TASK_QUEUE_DEPTH]; + + +/* A global variable holding all 32 events (bit flags) for this OS implementation. */ + +EventMaskType global_events; +EventMaskType global_event_count; + + +/* Define some default system objects. */ + +ResourceType RES_SCHEDULER; +CounterType SYS_TIMER; + + +/* Variables to store current and last executed task details. */ + +ULONG last_run_task; +ULONG system_start; /* If TX_TRUE indicates a fresh system start. */ +UINT task_terminated; + + +/* Define ISR2 controlling flags. */ +/* disable_ISR2 is the global enable/disable flag , if this flag is set no ISR2 is allowed or even kept pending. */ +/* suspend_ISR2 is NON Zero then any ISR2 is kept pending (provided that disable_ISR2 must be zero before hand). */ + +/* disable_ISR2 = TX_FALSE & suspend_ISR2 = TX_FALSE :: process ISR2 immediately + disable_ISR2 = TX_FALSE & suspend_ISR2 = TX_TRUE :: log ISR2 but don't process till suspend_ISR2 becomes TX_FALSE + disable_ISR2 = TX_TRUE & suspend_ISR2 DON't care :: No ISR2 logged and executed */ + +UINT disable_ISR2 = TX_TRUE; /* This flag must be TX_FALSE to allow ISR 2. */ +UINT suspend_ISR2 = TX_TRUE; /* This flag must be TX_FALSE to register and execute ISR2. */ +UINT ISR2_pending = TX_FALSE; + +/* Track initialization status. */ + +static UINT osek_init_state; /* Set to 0 for uninitialized, 1 for initialized by not yet started and 2 if started. */ + +#define OSEK_NOT_INIT (0U) +#define OSEK_INIT (1U) +#define OSEK_STARTED (2U) + +#define OSEK_MAX_LINK_DEPTH (1024U) /* Maximum depth of linked resource, to prevent infinite loops in case of a corrupted list. */ + +/* OSEK API Services and associated structures. */ + +struct Service_ActivateTask service_ActivateTask; +struct Service_TerminateTask service_TerminateTask; +struct Service_ChainTask service_ChainTask; +struct Service_Schedule service_Schedule; +struct Service_GetTaskID service_GetTaskID; +struct Service_GetTaskState service_GetTaskState; + +struct Service_DisableAllInterrupts service_DisableAllInterrupts; +struct Service_EnableAllInterrupts service_EnableAllInterrupts; +struct Service_SuspendAllInterrupts service_SuspendAllInterrupts; +struct Service_ResumeAllInterrupts service_ResumeAllInterrupts; +struct Service_SuspendOSInterrupts service_SuspendOSInterrupts; +struct Service_ResumeOSInterrupts service_ResumeOSInterrupts; + +struct Service_GetResource service_GetResource; +struct Service_ReleaseResource service_ReleaseResource; + +struct Service_SetEvent service_SetEvent; +struct Service_ClearEvent service_ClearEvent; +struct Service_GetEvent service_GetEvent; +struct Service_WaitEvent service_WaitEvent; + +struct Service_GetAlarmBase service_GetAlarmBase; +struct Service_GetAlarm service_GetAlarm; +struct Service_SetRelAlarm service_SetRelAlarm; +struct Service_SetAbsAlarm service_SetAbsAlarm; +struct Service_CancelAlarm service_CancelAlarm; + +struct Service_GetActiveApplicationMode service_GetActiveApplicationMode; +struct Service_StartOS service_StartOS; +struct Service_ShutdownOS service_ShutdownOS; + +struct Service_GetServiceId service_GetServiceId; + + +/**************************************************************************/ +/* OSEK internal functions prototypes */ +/**************************************************************************/ + + +/* Entry functions for various ThreadX threads used for OS management. */ + +static void osek_system_manager_entry(ULONG input); +static void osek_system_timer_entry(ULONG input); +static void osek_task_wrapper(ULONG tcb); + + +/* Initialization and reset for OSEK system objects. */ + +static UINT osek_memory_init (void *region0_ptr); +static void osek_alarm_init(void); +static void osek_tcb_init(void); +static void osek_resource_init(void); +static void osek_counter_init(void); + +static void osek_reset_alarm(OSEK_ALARM *alarm_ptr); +static void osek_reset_counter(OSEK_COUNTER *counter_ptr); +static void osek_reset_tcb(OSEK_TCB *tcb_ptr); +static void osek_reset_res(OSEK_RESOURCE *res_ptr); + +/* Some utilities. */ + +static ULONG osek_task_independent_area(void); +static OSEK_TCB *osek_thread2tcb(TX_THREAD *thread_ptr); +static UINT osek_remap_priority(UINT osek_priority); + +/* Functions to obtain OSEK objects from predefined pools. */ + +static UINT osek_memory_allocate(ULONG size, void **memory_ptr); +static UINT osek_get_alarm(void); +static CounterType osek_get_counter(void); +static ResourceType osek_get_resource(void); +static EventMaskType osek_get_event(void); +static ULONG osek_allocate_tcb(ULONG stack_size, OSEK_TCB **tcb_ptr); + +/* Internal operation functions. */ + +static StatusType osek_do_task_terminate(OSEK_TCB *tcb_ptr); +static StatusType osek_do_activate_task (OSEK_TCB *tcb_ptr); +static StatusType osek_create_task(OSEK_TCB *tcb_ptr); +static StatusType get_internal_resource(OSEK_TCB *tcb_ptr); +static StatusType release_internal_resource(OSEK_TCB *tcb_ptr); +static StatusType check_external_resource(OSEK_TCB *tcb_ptr); +static StatusType TerminateISR(void); + + +/* OSEK internal error function and Hook routine executors. */ + +static void osek_internal_error(ULONG error_code); +static void exec_ErrorHook (StatusType error); +static void exec_PreTaskHook(void); +static void exec_PostTaskHook(void); + + +/*OSEK Scheduler helper functions. */ + +static void add_task_to_table(OSEK_TCB *tcb_ptr); +static void start_osek_tasks(void); +static void push_task_to_table(OSEK_TCB *tcb_ptr); +static void pop_task_from_table(OSEK_TCB *tcb_ptr); +static UINT check_task_to_run (OSEK_TCB *tcb_ptr ); +static void check_linked_resources(void); +static StatusType ActivateISR(ISRType ISRID); + + +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* StartOS PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function starts the OS. If StartOSHook is defined it is */ +/* called. */ +/* */ +/* INPUT */ +/* */ +/* StatusType Application mode */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* StartupHook If defined */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void StartOS(StatusType os_mode) +{ + +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +StatusType status; + + check_linked_resources(); + + Application->application_mode = OSDEFAULTAPPMODE; + + /* Check for any startup hook routine. */ + if (Application->startup_hook_handler != TX_NULL) + { + /* Change operation mode for to startuphook mode. */ + osek_wrapper_operation_mode = STARTUPHOOK_MODE; + (Application->startup_hook_handler)(os_mode); + } + + /* Change back to default operations mode. */ + osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE; + + /* Now send message to system thread to start the task scheduler. */ + + /* Build the request. */ + request[0] = SYSMGR_START_OS; /* Request type. */ + request[1] = 0u; /* Dummy. */ + request[2] = 0u; /* Dummy. */ + request[3] = 0u; /* Dummy. */ + + /* Now send a message to the SysMgr supervisor thread. */ + /* to start OS task scheduler. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* CreateTask PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a new task with specified attributes. */ +/* This call is allowed only during Application Initialization. */ +/* This is not a standard OSEK API call. */ +/* */ +/* INPUT */ +/* */ +/* priority Priority of the Task */ +/* stack_size Stack size of the Task */ +/* entry_function Task entry function pointer */ +/* policy Scheduling policy for this Task */ +/* active_no Maximum activation number */ +/* start Starting state of the task */ +/* type Task type: Basic/Extended */ +/* */ +/* OUTPUT */ +/* */ +/* TaskId Task Id if successful */ +/* TX_NULL Error while creating the task */ +/* */ +/* CALLS */ +/* */ +/* osek_allocate_tcb Get a TCB from the pool */ +/* osek_create_task Create an OSEK Task */ +/* */ +/* CALLED BY */ +/* */ +/* Initialization code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +TaskType CreateTask(const CHAR *name, void(*entry_function)(), UINT priority, UINT max_activation, + ULONG stack_size, SCHEDULE policy, AUTOSTART start, UINT type, AppModeType mode) +{ + +OSEK_TCB *tcb_ptr; /* Pointer to task control block. */ +ULONG temp32; +ULONG status; + + + /* Check whether we are called during initialization. */ + /* This will ensure that no one calls this function after system is started. */ + if (osek_init_state != OSEK_INIT) + { + Application->osek_object_creation_error++; + + /* Return OSEK internal error. NOTE: This is not a standard OSEK error. */ + return ((TaskType)TX_NULL); + } + + /* Now check the validity of all input parameters. */ + + /* Entry point function. */ + if (entry_function == TX_NULL) + { + /* Entry function not specified! Return an error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Task priority. */ + if (priority > OSEK_HIGHEST_PRIORITY) + { + /* Return an internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* The max_activation parameter must be within limit, that is a non zero value but less + than OSEK_MAX_ACTIVATION. */ + if ((max_activation > OSEK_MAX_ACTIVATION) || (max_activation == 0u)) + { + /* Return an internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Adjust the input stack size and check. */ + /* Force stack size to a multiple of 4 bytes, round up if needed. */ + temp32 = ((stack_size + 3u) & ~0x3u); + + /* Add a little extra padding to stack. */ + temp32 += OSEK_STACK_PADDING; + + /* Is task stack big enough? ThreadX needs a minimum stack size for each task. */ + if (temp32 < TX_MINIMUM_STACK) + { + /* Return an error as there is no enough stack. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Scheduling Policy */ + if ((policy != FULL) && (policy != NON)) + { + /* Return an error as policy supplied is unknown. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Task Type */ + if ((type != BASIC) && (type != EXTENDED)) + { + /* Return an error as task type supplied is unknown. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* AUTO START option. */ + if ((start != TRUE) && (start != FALSE)) + { + /* Return an error as Start type is unknown.This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Got all input parameters within limits, now try to get a free Task Control Block (TCB) for this new task. */ + tcb_ptr = TX_NULL; + status = osek_allocate_tcb(temp32, &tcb_ptr); + + /* Make sure we got a TCB. */ + if((status != TRUE) || (tcb_ptr == TX_NULL)) + { + /* Return an error since no memory is available. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Now fill up the TCB with all supplied parameters. */ + + /* Store TASK object ID this is same for all TCB, this helps in checking whether the data + structure is really a TASK CONTROL BLOCK. */ + tcb_ptr->osek_task_id = OSEK_TASK_ID; + + /* Store task's name and type. */ + tcb_ptr->name = name; + tcb_ptr->task_type = type; + + /* Store the statically assigned (design time) priority and same would be RUN time priority. */ + tcb_ptr->org_prio = priority; + tcb_ptr->cur_threshold = priority; + + /* Store the task entry point. This is where the task will begin upon activation or chaining. */ + tcb_ptr->task_entry = entry_function; + + /* Store current task activation number as well as the maximum activations defined for this task. */ + tcb_ptr->max_active = max_activation; + tcb_ptr->current_active = 0u; + tcb_ptr->internal_res = TX_FALSE; + + /* Store the scheduling policy defined for the task. */ + tcb_ptr->policy = policy; + + /* Store the start up condition of the task. */ + tcb_ptr->task_autostart = start; + + /* A task is always created in suspended state even though it is defined as an AUTO START. */ + tcb_ptr->suspended = TX_TRUE; + tcb_ptr->waiting = TX_FALSE; + + /* Store task's application mode. */ + tcb_ptr->task_Appl_Mode = mode; + + /* Now create the ThreadX thread which actually runs this task. */ + status = osek_create_task(tcb_ptr); + + /* Check whether we encounter any error during ThreadX thread creation. */ + if (status == E_OS_SYSTEM) + { + /* Can't create a task? This is not a standard OSEK error.*/ + Application->osek_object_creation_error++; + return ((TaskType) TX_NULL); + } + + /* Everything worked fine so far. Return TaskID. This TaskID is nothing but a TCB structure + type casted to TaskType UDT. */ + return ((TaskType)tcb_ptr); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* CreateISR PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a new task which will execute an ISR. */ +/* This call is allowed only during Application Initialization. */ +/* This is not a standard OSEK API call. */ +/* */ +/* INPUT */ +/* */ +/* priority Priority of the ISR */ +/* stack_size Stack size of the ISR */ +/* entry_function Task entry function pointer */ +/* policy Scheduling policy for this task */ +/* active_no Maximum activation number */ +/* start Starting state of the task */ +/* type Task type: Basic/Extended */ +/* */ +/* OUTPUT */ +/* */ +/* TaskId Task Id if successful */ +/* TX_NULL Error while creating the ISR */ +/* */ +/* CALLS */ +/* */ +/* osek_allocate_tcb Get a TCB from the pool */ +/* osek_create_task Create an OSEK Task */ +/* */ +/* CALLED BY */ +/* */ +/* Initialization code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +ISRType CreateISR(const CHAR *name, void (*entry_function)(), UINT category, ULONG stack_size) +{ + +OSEK_TCB *tcb_ptr; /* Pointer to task control block. */ +ULONG temp32; +ULONG status; + + + /* Check if we are called during initialization. */ + if((osek_init_state != OSEK_INIT) || /* Not in initialization. */ + (_tx_thread_current_ptr == &_tx_timer_thread)) + { + /* Return default error. */ + Application->osek_object_creation_error++; + + return((ResourceType)TX_NULL); + } + + /* Scheduling policy. */ + if ((category != CATEGORY1) && (category != CATEGORY2)) + { + /* Return an error as policy supplied is unknown. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Entry point function. */ + if(entry_function == NULL) + { + /* Entry function not specified! Return an error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Adjust the input stack size and check. */ + /* Force stack size to a multiple of 4 bytes, round up if needed. */ + temp32 = ((stack_size + 3u) & ~0x3u); + + /* Add a little extra padding to stack. */ + temp32 += OSEK_STACK_PADDING; + + /* Is task stack big enough? ThreadX needs a minimum stack size for each task. */ + if (temp32 < TX_MINIMUM_STACK) + { + /* Return an error as there is not enough stack. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((ISRType)TX_NULL); + } + + /* Got all input parameters within limits, now try to get a free task control block(TCB) for this new ISR. */ + tcb_ptr = TX_NULL; + status = osek_allocate_tcb(temp32, &tcb_ptr); + /* Make sure we got a TCB. */ + if((status != TRUE) || (tcb_ptr == TX_NULL)) + { + /* Return an error since no memory is available. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((TaskType)TX_NULL); + } + + /* Got a tcb , now fill up the TCB with all supplied parameters. */ + + /* Store ISR objectID ,this is same for all ISRs, this helps in checking whether the data + structure is really a ISR CONTROL BLOCK. */ + tcb_ptr->osek_task_id = OSEK_ISR_ID; + + /* Store ISR name. */ + tcb_ptr->name = name; + /* Store ISR category. */ + tcb_ptr->task_type = category; + + /* Store the statically assigned (design time) priority and same would be runtime priority. */ + + if (category == 1u) + { + tcb_ptr->org_prio = OSEK_ISR1_PRIORITY; + } + else + { + tcb_ptr->org_prio = OSEK_ISR2_PRIORITY; + } + + tcb_ptr->cur_threshold = tcb_ptr->org_prio; + + /* Store the ISR entry point. This is where the ISR will begin. */ + tcb_ptr->task_entry = entry_function; + + /* Store maximum activations defined for ISR. */ + /* Only 1 ISR of this name can be pending. */ + tcb_ptr->max_active = 1u; + tcb_ptr->current_active = 0u; + tcb_ptr->internal_res = TX_FALSE; + + /* Store the scheduling policy defined for the task. */ + tcb_ptr->policy = NON; + + /* Store the start up condition of the ISR which of course is DO NOT START. */ + tcb_ptr->task_autostart = FALSE; + + /* An ISR is always created in suspended state. */ + tcb_ptr->suspended = TX_TRUE; + tcb_ptr->waiting = TX_FALSE; + + /* Now create the ThreadX thread which actually mimics this ISR. */ + status = osek_create_task(tcb_ptr); + + /* Check whether we encounter any error during ThreadX thread creation. */ + if (status == E_OS_SYSTEM) + { + /* Can't create a task? This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((ISRType)TX_NULL); + } + + /* Everything worked fine so far. Return ISRID. This is nothing but a TCB structure + type casted to ISRType UDT. */ + return ((ISRType)tcb_ptr); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ActivateTask PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call transfers a task from suspended state into the ready */ +/* state. The operating system ensures that the task code is being */ +/* executed from the first statement. The service may be called both */ +/* from interrupt level and from task level. Rescheduling after this */ +/* call depends on from where it is called from. Also if required */ +/* resources are freed as well as this being the highest priority task */ +/* than the task executing at this instance. If E_OS_LIMIT is returned */ +/* then activation is ignored. When an extended task is transferred */ +/* from suspended to ready state all its events are cleared. */ +/* */ +/* INPUT */ +/* */ +/* TaskId Task Name */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_ID Invalid TaskId */ +/* E_OS_LIMIT Task activation limit */ +/* exceeded */ +/* */ +/* CALLS */ +/* */ +/* tx_queue_send Send message to Sys Manager */ +/* osek_internal_error OSEK internal error */ +/* osek_task_independent_area Check calling context */ +/* tx_thread_identify Get ThreadX thread of caller */ +/* osek_thread2tcb Convert ThreadX to OSEK */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType ActivateTask(TaskType TaskId) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +OSEK_TCB *tcb_ptr_self; +UINT status; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +ULONG area; +TX_THREAD *p_thread; + + + /* Log this call and arguments passed, this is required for the macro 'OSErrorGetServiceId'. */ + service_GetServiceId.id = (OsServiceIdType)OSServiceId_ActivateTask; + service_ActivateTask.TaskID = TaskId; + + /* Check if we are in task context. */ + area = osek_task_independent_area(); + if(area != TX_TRUE) + { + exec_ErrorHook(E_OS_CALLEVEL); + /* Return error. */ + return (E_OS_CALLEVEL); + } + + /* Check operating mode */ + if ((osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE) && (osek_wrapper_operation_mode != ISR2_MODE)) + { + /* Hook routines and alarm callbacks can't call this service. */ + /* This explicit check is required because all hook routines are + executed in task's context! */ + exec_ErrorHook(E_OS_ID); + return (E_OS_CALLEVEL); + } + + /* Get OSEK TCB of the calling task. */ + p_thread = tx_thread_identify(); + tcb_ptr_self = osek_thread2tcb(p_thread); + + if ((tcb_ptr_self->osek_task_id != OSEK_TASK_ID) && (tcb_ptr_self->osek_task_id != OSEK_ISR_ID)) + { + /* This call is allowed only from TASK and ISR */ + return (E_OS_CALLEVEL); + } + + /* Get OSEK TCB of the TASK to activate. */ + tcb_ptr = (OSEK_TCB *)TaskId; + if ((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_TASK_ID)) + { + exec_ErrorHook(E_OS_ID); + return (E_OS_ID); + } + + TX_DISABLE + + /* Check whether the task to be activated is activated up to its defined activation limit. */ + if(tcb_ptr->current_active >= tcb_ptr->max_active) + { + TX_RESTORE + exec_ErrorHook(E_OS_LIMIT); + /* Reached its max activation limit. */ + return (E_OS_LIMIT); + } + + /* Now send a message to the system manager thread to activate this task. */ + /* Build the request. */ + request[0] = SYSMGR_ACTIVATE_TASK; /* Request type. */ + request[1] = (ULONG)tcb_ptr; /* Task to activate. */ + + /* Now check who is calling this service, a task or an ISR? */ + if (tcb_ptr_self->osek_task_id == OSEK_TASK_ID) + { + request[2] = (ULONG)tcb_ptr_self; /* Task id of the calling task. */ + } + else + { + request[2] = 0u; /* When ISR activates a task rescheduling (if any) is held + till ISR completes so no need to suspend ISR task. */ + } + + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, this call */ + /* will be preempted by SysMgr supervisor thread. */ + /* SysMgr will eventually call osek_do_task_activate. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_ACTIVATETASK); + } + + /* Return status. */ + return(E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* TerminateTask PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This service terminates the calling task, which means transferring */ +/* the calling task from the running state into the suspended state. */ +/* Only internal resources held by this task are released here. While */ +/* it is assumed that any external resources occupied by the task must */ +/* have been released before the call to TerminateTask. In case */ +/* a resource is still occupied while calling this service, then the */ +/* behaviour is undefined in STANDARD version of OSEK. In the EXTENDED */ +/* version of OSEK, this service returns an error, which can be */ +/* evaluated by the application. */ +/* If successful, this call will causes rescheduling, this also means */ +/* that upon success TerminateTask does not return to the call level. */ +/* */ +/* NOTE: */ +/* */ +/* Ending a task function without call to TerminateTask or ChainTask is */ +/* strictly forbidden and may leave the system in an undefined state. */ +/* But in this implementation TerminateTask service is called if needed.*/ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None If success */ +/* Error Code. If error */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area Check if we are in task context */ +/* osek_thread2tcb Get TCB pointer for thread pointer */ +/* tx_queue_send Send message to Sys Manager Thread */ +/* osek_internal_error In case of any internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code (TASKs only) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType TerminateTask(void) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT index; +UINT status; +ULONG area; +TX_THREAD *p_thread; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_TerminateTask; + service_TerminateTask.TaskID = (StatusType)0u; + + /* Check for Task or ISR context. */ + /* All ISRs are treated as as a high priority tasks. */ + area = osek_task_independent_area(); + if(area != TX_TRUE) + { + exec_ErrorHook(E_OS_CALLEVEL); + /* Return error. */ + return (E_OS_CALLEVEL); + } + + /* Get OSEK TCB of this TASK/ISR. */ + p_thread = tx_thread_identify(); + tcb_ptr = osek_thread2tcb(p_thread); + if (tcb_ptr == TX_NULL) + { + exec_ErrorHook(E_OS_CALLEVEL); + return (E_OS_CALLEVEL); + } + + if (tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + /* This call is allowed only from TASK and ISR. */ + exec_ErrorHook(E_OS_CALLEVEL); + return (E_OS_CALLEVEL); + } + + + /* Check operating mode */ + if (osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE) + { + /* Hook routines and alarm callbacks can't call this service. */ + /* This explicit check is required because all hook routines are + executed in task's context! */ + exec_ErrorHook(E_OS_CALLEVEL); + + return (E_OS_CALLEVEL); + } + + TX_DISABLE + + /* Check if any resource is occupied. A task can not be terminated if it is holding any resource. */ + if(tcb_ptr->res_ocp != 0u) + { + TX_RESTORE + + exec_ErrorHook(E_OS_RESOURCE); + + /* Return. */ + return (E_OS_RESOURCE); + } + + /* Release any internal resources held. */ + if (tcb_ptr->internal_res != 0u) + { + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) + { + break; + } + + ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u; + tcb_ptr->internal_resource_occuplied_list[index] = 0u; + + } /* End of for loop. */ + } + + /* Now it's okay to terminate this task, clear its events. */ + tcb_ptr->waiting_events = 0u; + tcb_ptr->set_events = 0u; + + /* Now all set to terminate this task. */ + /* Send a message to the System Manager to terminate this task. */ + /* Build the request. */ + + request[0] = SYSMGR_TERMINATE_TASK; /* Request type. */ + request[1] = (ULONG)tcb_ptr; /* ID of the task to kill. */ + request[2] = 0u; + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this call will be preempted by SysMgr supervisor thread */ + /* SysMgr will eventually call osek_do_task_terminate and reschedule. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. and Sys Manager terminates this task */ + /* This point will never be reached, as this thread itself will be */ + /* deleted by the system manager! */ + + if (status != TX_SUCCESS) + { + osek_internal_error(SYS_MGR_SEND_TERMINATETASK); + } + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ChainTask PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This service causes the termination of the calling task. After */ +/* termination of the calling task, a succeeding task (supplied as an */ +/* input argument for the call) is activated. If the succeeding task */ +/* is the same calling task, then this does not result in multiple */ +/* requests and the task is not transferred to the suspended state. */ +/* Only internal resources held by this task are released here, even */ +/* in case the calling task is identical with the task to chain. */ +/* While it is assumed that any external resources occupied by the */ +/* task must have been released before the call to TerminateTask. */ +/* In case a resource is still occupied while calling this service, */ +/* then the behaviour is undefined in STANDARD version of OSEK. */ +/* In the EXTENDED version of OSEK, an error is returned, which can be */ +/* evaluated by the application. */ +/* If called successfully, ChainTask does not return to call level and */ +/* the status can not be evaluated. In case of error the service */ +/* returns to the calling task and provides a status which can then be */ +/* checked by the application. */ +/* If successful, this call will causes rescheduling, this also means */ +/* that upon success ChainTask does not return to the call level. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* Task_ID Task id to activate. */ +/* OUTPUT */ +/* */ +/* E_OK If successful. */ +/* E_OS_LIMIT Too many activations */ +/* E_OS_CALLEVEL Called at interrupt level */ +/* E_OS_RESOURCE Resources are not released */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area Make sure called in Task context */ +/* osek_thread2tcb Get TCB pointer for the thread */ +/* tx_queue_send send message to sys manager thread */ +/* osek_internal_error Any internal errors */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code (TASKs only) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType ChainTask(TaskType TaskID) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +OSEK_TCB *tcb_ptr1; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT index; +ULONG area; +TX_THREAD *p_thread; + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_ChainTask; + service_ChainTask.TaskID = TaskID; + + /* Check if we are in task context. */ + area = osek_task_independent_area(); + if(area != TX_TRUE) + { + exec_ErrorHook(E_OS_CALLEVEL); + /* Return error. */ + return(E_OS_CALLEVEL); + } + + /* Get OSEK TCB of this TASK/ISR. */ + p_thread = tx_thread_identify(); + tcb_ptr = osek_thread2tcb(p_thread); + if (tcb_ptr == TX_NULL) + { + exec_ErrorHook(E_OS_ID); + return (E_OS_ID); + } + + if (tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + /* This call is allowed only from TASK. */ + exec_ErrorHook(E_OS_CALLEVEL); + return (E_OS_CALLEVEL); + } + + /* Check operating mode. */ + if (osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE) + { + /* ISRs, hook routines and alarm callbacks can't call this service. */ + /* This explicit check is required because all ISRs and hook routines are + executed in task's context! */ + exec_ErrorHook(E_OS_CALLEVEL); + + return (E_OS_CALLEVEL); + } + + /* Check if any external resources are occupied. */ + if(tcb_ptr->res_ocp != 0u) + { + exec_ErrorHook(E_OS_RESOURCE); + + /* The external resource is not released. */ + return (E_OS_RESOURCE); + } + + /* Get tcb of task to be chained. */ + tcb_ptr1 = (OSEK_TCB *)TaskID; + + /* First, check for an invalid task pointer. */ + if ((tcb_ptr1 == TX_NULL) || ((tcb_ptr1->osek_task_id) != OSEK_TASK_ID)) + { + exec_ErrorHook(E_OS_ID); + + /* Return Error. */ + return (E_OS_ID); + } + + TX_DISABLE + + /* Check both calling task and task_to_be_chained are one and the same. */ + if (tcb_ptr != tcb_ptr1) + { + /* Check for proper multiple activation. */ + if(tcb_ptr1->current_active >= tcb_ptr1->max_active) + { + TX_RESTORE + + /* Reached its max activation limit. */ + exec_ErrorHook(E_OS_LIMIT); + + return (E_OS_LIMIT); + } + } + + /* Store TaskID which is to be chained after termination of this task. */ + tcb_ptr->task_to_chain = TaskID; + + /* Now release any internal resources held by the calling task. */ + if (tcb_ptr->internal_res != 0u) + { + for (index = 0u ; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) + { + break; + } + + ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u; + tcb_ptr->internal_resource_occuplied_list[index] = 0u; + + } /* End of for loop. */ + } + + /* Now it's ok to terminate this task , clear its events. */ + tcb_ptr->waiting_events = 0u; + tcb_ptr->set_events = 0u; + + /* Send message to the system manager to suspend calling task and activate + task to be chained. */ + + /* Build the request. */ + request[0] = SYSMGR_CHAIN_TASK; /* Request type. */ + request[1] = (ULONG)tcb_ptr; /* TCB ptr of calling task. */ + request[2] = TaskID; /* Task to chain. */ + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread. */ + + tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed and sys manager terminates this task */ + /* This point will never be reached, as this thread itself will be */ + /* deleted by the System Manager! */ + + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetTaskID PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* GetTaskID returns the task id of the task currently running. */ +/* Calling GetTaskID is allowed from task level, ISR level and in */ +/* several hook routines. This service is intended to be used by */ +/* library functions and hook routines. If can’t be evaluated */ +/* (no task currently running), the service returns INVALID_TASK as */ +/* TaskType. */ +/* */ +/* INPUT */ +/* */ +/* TaskID Pointer to stored Task ID */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success */ +/* INVALID_TASK If failure */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify Identifies the current thread */ +/* */ +/* CALLED BY */ +/* */ +/* Application code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetTaskID(TaskRefType TaskID) +{ + +TX_THREAD *thread_ptr; + + + /* Check for valid pointer to store the task ID. */ + if(TaskID == TX_NULL) + { + /* Return error. */ + return (E_OS_ID); + } + + /* Check for the pointer to thread. */ + thread_ptr = tx_thread_identify(); + + if ((thread_ptr == TX_NULL) || (thread_ptr == &_tx_timer_thread)) + { + /* No task running TaskID can’t be evaluated return a special Error. */ + *TaskID = INVALID_TASK; + + return (E_OK); + } + + if ((osek_wrapper_operation_mode == STARTUPHOOK_MODE) || + (osek_wrapper_operation_mode == SHUTDOWNHOOK_MODE) || + (osek_wrapper_operation_mode == ALARM_CALLBACK_MODE)) + { + *TaskID = INVALID_TASK; + } + else + { + *TaskID = last_run_task; + } + + /* Return success. */ + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetTaskState PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Returns the state of a task (running, ready, waiting, suspended) at */ +/* the time of calling GetTaskState. The service may be called from */ +/* interrupt service routines, task level, and some hook routines. */ +/* Within a full preemptive system, calling this operating system */ +/* service only provides a meaningful result if the task runs in an */ +/* interrupt disabling state at the time of calling. */ +/* When a call is made from a task in a full preemptive system, the */ +/* result may already be incorrect at the time of evaluation. When the */ +/* service is called for a task, which is multiply activated, the */ +/* state is set to running if any instance of the task is running. */ +/* */ +/* INPUT */ +/* */ +/* Task_ID Task id to query */ +/* State Pointer to result state */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_ID Task is invalid */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area Check if called from task */ +/* independent area */ +/* tx_thread_identify Identify the current thread */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetTaskState(TaskType TaskID, TaskStateRefType State) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +TX_THREAD *this_thread; +ULONG area; +TX_THREAD *p_thread; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetTaskState; + service_GetTaskState.TaskID = (StatusType)0; + + /* Check for valid task ID. */ + if(TaskID == 0u) + { + exec_ErrorHook(E_OS_ID); + /* Return error. */ + return (E_OS_ID); + } + + /* Get OSEK TCB. */ + tcb_ptr = (OSEK_TCB *)TaskID; + + /* First, check for an invalid task pointer. */ + if((tcb_ptr == TX_NULL) || ((tcb_ptr->osek_task_id) != OSEK_TASK_ID)) + { + exec_ErrorHook(E_OS_ID); + /* Return error. */ + return (E_OS_ID); + } + + TX_DISABLE + + if ((osek_wrapper_operation_mode == STARTUPHOOK_MODE) || + (osek_wrapper_operation_mode == SHUTDOWNHOOK_MODE) || + (osek_wrapper_operation_mode == ALARM_CALLBACK_MODE)) + { + TX_RESTORE + + /* Return error. */ + return (E_OS_ID); + } + + /* Get the ThreadX TCB. */ + this_thread = (TX_THREAD *)tcb_ptr; + + /* Check if we are only in task context. */ + area = osek_task_independent_area(); + if (area == TX_TRUE) + { + /* Get the OSEK TCB. */ + p_thread = tx_thread_identify(); + if(this_thread == p_thread) + { + TX_RESTORE + + /* This is the running thread. */ + *State = RUNNING; + return (E_OK); + } + } + + if (tcb_ptr->waiting == TX_TRUE) + { + TX_RESTORE + + *State = WAITING; + return (E_OK); + } + if (tcb_ptr->suspended == TX_TRUE) + { + TX_RESTORE + + *State = SUSPENDED; + return (E_OK); + } + + TX_RESTORE + + *State = READY; + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* Schedule PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* If a higher-priority task is ready, the internal resource of the */ +/* task is released, the current task is put into the ready state, its */ +/* context is saved and the higher-priority task is executed. */ +/* Otherwise the calling task is continued. */ +/* Rescheduling can only take place if an internal resource is */ +/* assigned to the calling task during system generation. For these */ +/* tasks, schedule enables a processor assignment to other tasks with */ +/* lower or equal priority than the ceiling priority of the internal */ +/* resource and higher priority than the priority of the calling task */ +/* in application-specific locations. When returning from schedule, */ +/* the internal resource has been taken again. */ +/* This service has no influence on tasks with no internal resource */ +/* assigned (preemptable tasks). */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success. */ +/* E_OS_CALLLEVEL Called at interrupt level */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area Check if called from task */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType Schedule (void) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +TX_THREAD *this_thread; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT status; +ULONG area; + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_Schedule; + service_GetTaskState.TaskID = (StatusType)0u; + + /* Check if we are in task context. */ + area = osek_task_independent_area(); + if(area != TX_TRUE) + { + /* Return error. */ + return (E_OS_CALLEVEL); + } + + /* Get the ThreadX thread and OSEK TCB. */ + this_thread = tx_thread_identify(); + tcb_ptr = osek_thread2tcb(this_thread); + + if (tcb_ptr == TX_NULL) + { + return (E_OS_ID); + } + + if (tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + /* This call is allowed only from TASK. */ + return(E_OS_ID); + } + + TX_DISABLE + + /* Check operating mode. */ + if (osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE) + { + + TX_RESTORE + + /* Hook routines, alarm callbacks and ISRs can't call this service. */ + /* This explicit check is required because all hook routines are + executed in task's context. */ + return (E_OS_ID); + } + + /* Check if any resource is occupied. */ + if(tcb_ptr->res_ocp != 0u) + { + TX_RESTORE + + exec_ErrorHook(E_OS_RESOURCE); + /* Return. */ + return (E_OS_RESOURCE); + + } + + /* Now release internal resources, if any, held by this task */ + /* This call releases internal resources and moves the task to */ + /* a new queue position based on its new ceiling priority. */ + /* release_internal_resource(tcb_ptr); */ + + /* Now send message to system Manager to check any higher priority task is ready. */ + /* Build the request. */ + request[0] = SYSMGR_SCHEDULE; /* Request type. */ + request[1] = (ULONG)this_thread; /* Self ID. */ + request[2] = 0u; + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue read is successful. */ + /* System Manager will eventually call start_osek_tasks. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + } + + /* Assume that the sys manager does its job. */ + /* And has returned from schedule, restore preemption threshold if any. */ + + /* Now we need to move this task back to its priority level */ + /* before coming here all internal resources (if any are taken). */ + + TX_DISABLE + + /* Now check task's scheduling policy */ + if (tcb_ptr->policy == NON) + { + pop_task_from_table(tcb_ptr); + /* If policy is NON then restore to OSEK_NON_SCHEDULE priority. */ + tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY; + push_task_to_table(tcb_ptr); + } + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* CreateResource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Creates resources for inter-task mutual exclusion for resource */ +/* protection */ +/* */ +/* INPUT */ +/* */ +/* name Name of the Resource. */ +/* type Type of the resource standard/internal */ +/* */ +/* OUTPUT */ +/* */ +/* RES_ID If successful */ +/* ZERO If error while creating resource */ +/* */ +/* CALLS */ +/* */ +/* osek_memory_allocate Allocate memory from system */ +/* osek_get_resource Get one resource from the pool */ +/* tx_mutex_create Create a Mutex in ThreadX */ +/* osek_internal_error OSEK internal Error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +ResourceType CreateResource(const CHAR *name, StatusType type, ResourceType linked_res) +{ + +OSEK_RESOURCE *res_ptr; +OSEK_RESOURCE *linked_res_ptr; +OSEK_RESOURCE *res1_ptr; + +ResourceType ID; +ResourceType linked_res_id; +UINT done_flag; +UINT iter_max; + + /* Check whether calling from task context or ISR. */ + if ((osek_init_state != OSEK_INIT) || /* Not in Initialization. */ + (_tx_thread_current_ptr == &_tx_timer_thread)) + { + /* Return default error. */ + Application->osek_object_creation_error++; + return ((ResourceType) TX_NULL); + } + + /* Check whether the linked resource (if specified) exists. */ + if (type == LINKED) + { + if (linked_res == 0u) + { + /* Specified linked resource doesn't exist */ + /* OR Resource is trying to link itself. */ + Application->osek_object_creation_error++; + return ((ResourceType) TX_NULL); + } + + /* Check if the resource to which this resource is linked is external. */ + linked_res_ptr = (OSEK_RESOURCE *)linked_res; + if (linked_res_ptr->type == INTERNAL) + { + /* Specified linked resource is of INTERNAL type. */ + Application->osek_object_creation_error++; + return ((ResourceType) TX_NULL); + } + } + + /* Find out any resource is available. */ + ID = osek_get_resource(); + if(ID == 0u) + { + /* Resource is not available. */ + Application->osek_object_creation_error++; + return ((ResourceType) TX_NULL); + } + + /* Get the OSEK resource. */ + res_ptr = (OSEK_RESOURCE *)ID; + + res_ptr->name = name; + + res_ptr->c_priority = 0u; + + res_ptr->type = type; + + res_ptr->linked_res = linked_res; + + res_ptr->resolved_res = 0u; + + /* Now resolve if chain of linked linked resources. */ + + if (res_ptr->type == LINKED) + { + done_flag = FALSE; + res1_ptr = res_ptr; + iter_max = OSEK_MAX_LINK_DEPTH; /* Safety count to prevent infinite loop. */ + while(done_flag == 0u) + { + if(iter_max == 0u) { + /* Maximum iteration count exceeded, return an error. */ + Application->osek_object_creation_error++; + return ((ResourceType) TX_NULL); + } + + linked_res_id = res1_ptr->linked_res; + linked_res_ptr = (OSEK_RESOURCE *)linked_res_id; + if (linked_res_ptr->type == STANDARD) + { + res_ptr->resolved_res = linked_res_id; + done_flag = TRUE; + } + res1_ptr = linked_res_ptr; + + iter_max--; + } + + } + + + /* No task is occupying this resource. */ + res_ptr->taskid = 0u; + + res_ptr->osek_res_id = OSEK_RES_ID; + + return (ID); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetResource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call serves to enter critical sections in the code that are */ +/* assigned to the resource referenced by . A critical section */ +/* must always be left using ReleaseResource. Nested resource */ +/* occupation is only allowed if the inner critical sections are */ +/* completely executed within the surrounding critical section. */ +/* Nested occupation of one and the same resource is also forbidden. */ +/* Corresponding calls to GetResource and ReleaseResource should appear */ +/* within the same function on the same function level. */ +/* */ +/* INPUT */ +/* */ +/* id Id of the resource. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success */ +/* E_OS_CALLEVEL Called from ISR */ +/* E_OS_ACCESS Attempt to get a resource which is */ +/* already occupied by any task or ISR, */ +/* or the statically assigned priority of */ +/* the calling task or interrupt routine */ +/* is higher than the calculated ceiling */ +/* priority, */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area See if called from task independent */ +/* area */ +/* tx_thread_identify Identify the current thread */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetResource(ResourceType id) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_RESOURCE *osek_res; +OSEK_TCB *tcb_ptr; +TX_THREAD *this_thread; +UINT index ; +UINT new_prio; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT status; +ULONG area; + + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetResource; + service_GetResource.ResID = id; + + /* Check we are calling from task context only. */ + area = osek_task_independent_area(); + if(area == 0u) + { + exec_ErrorHook(E_OS_CALLEVEL); + /* Return default error. */ + return (E_OS_CALLEVEL); + } + + /* Check for valid ID. */ + if(id == 0u) + { + exec_ErrorHook(E_OS_ID); + /* Return error. */ + return (E_OS_ID); + } + + /* Get thread currently executed. */ + this_thread = tx_thread_identify(); + if(this_thread == NULL) + { + exec_ErrorHook(E_OS_CALLEVEL); + return (E_OS_CALLEVEL); + } + + /* Get RES's control block. */ + osek_res = (OSEK_RESOURCE *)id; + + /* First, check for an invalid resource pointer. */ + if((osek_res == TX_NULL) || ((osek_res->osek_res_id) != OSEK_RES_ID)) + { + exec_ErrorHook(E_OS_ID); + + /* Return Error. */ + return (E_OS_ID); + } + + /* Get the OSEK TCB. */ + tcb_ptr = (OSEK_TCB *) this_thread; + + /* Now check whether this resource is standard or internal. */ + if (osek_res->type == INTERNAL) + { + /* Internal Resource can not be occupied via GetResource call. */ + exec_ErrorHook(E_OS_ID); + return (E_OS_ID); + } + + TX_DISABLE + + /* Now check whether this resource is occupied. */ + if (osek_res->taskid != 0u) + { + TX_RESTORE + + /* Already occupied by this task or any other task, this also prevent double occupancy. */ + exec_ErrorHook(E_OS_ACCESS); + + return (E_OS_ACCESS); + } + + /* OK up to this point, now what type of resource is it? */ + /* Because 'RES_SCEDULER' is a special type of resource. */ + + if (id == RES_SCHEDULER) + { + + /* This task has taken this resource so update this task's resource hold count. */ + tcb_ptr->res_ocp++; + + /* Save this task's id in the res's control block. */ + osek_res->taskid = (TaskType)tcb_ptr; + + tcb_ptr->resource_scheduler = TX_TRUE; + + /* Being RES_SCHEDULER no need to add RES_SCEDULER in the task's list of occupied resources. */ + + /* As task is occupying RES_SCHEDULER all preemptions are blocked so make the policy to NON PREEMP. */ + /* A NON preempt type task is already having OSEK_NON_SCHEDULE_PRIORITY during RUN time, so need + to change it. */ + + if (tcb_ptr->policy == FULL) + { + /* For a FULL preempt type task assign having highest preemption threshold */ + /* Now ask the System Manager to change this task's priority, and also check if there is + any possibility of preemption. */ + /* Send message to System Manager to check any preemption out of ReleaseResource call. */ + new_prio = OSEK_NON_SCHEDULE_PRIORITY; + + /* Build the request. */ + request[0] = SYSMGR_GET_RESOURCE; /* Request type. */ + request[1] = (ULONG)this_thread; + request[2] = (ULONG)new_prio; + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue is successful. */ + /* System Manager will eventually call start_osek_tasks. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + + } + } + + TX_RESTORE + + return (E_OK); + + } /* End if ( id == RES_SCHEDULER ). */ + + + /* Not RES_SCEDULER. */ + + /* Check whether this resource is assigned to this task or not? */ + for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + if (tcb_ptr-> external_resource_list[index] == id) { + /* Yes it is registered with this task, stop searching. */ + break; + } + } /* Check next in the list. */ + + /* Checked entire list and found that this resource is not in the list? */ + if (index >= OSEK_MAX_EXTERNAL_RES) + { + TX_RESTORE + + exec_ErrorHook(E_OS_NOFUNC); + + /* Return error. */ + return (E_OS_NOFUNC); + } + + /* Yes this resource is assigned to this task. */ + /* First check the task has room to hold one more resource? */ + + /* Find the next free entry in the task's res occupied list. */ + for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + if(tcb_ptr->external_resource_occuplied_list[index] == 0u) + { + /* Found next free entry but do not add this resource to the list at this moment. */ + break; + } + } + + /* We got an entry or not? */ + if (index >= OSEK_MAX_EXTERNAL_RES) + { + TX_RESTORE + + /* This is very unlikely, as list is big enough to hold all resources defined in the system. */ + exec_ErrorHook(E_OS_ACCESS); + + /* Return Error. */ + return (E_OS_ACCESS); + } + + /* Now entry is available, take this resource. */ + + tcb_ptr->external_resource_occuplied_list[index] = id; + /* Save this task's id in the res's control block to indicate that this is the owner of this res. */ + osek_res->taskid = (TaskType)(tcb_ptr); + /* This task has taken this resource so update this task's resource hold count. */ + tcb_ptr->res_ocp++; + + /* Now we need to change this task's preemption threshold to this resource's ceiling priority. */ + /* But if the task is of NON scheduling no need to take any action , it is already having + highest preemption threshold. */ + + if ((tcb_ptr->policy == FULL) && (tcb_ptr->cur_threshold < osek_res->c_priority)) + { + /* Need to change the at the task is having lower preemption threshold. */ + /* Remove this task from its current queue and place it in front of + occupied resource's ceiling priority queue. */ + + new_prio = osek_res->c_priority; + + /* Build the request. */ + request[0] = SYSMGR_GET_RESOURCE; /* Request type. */ + request[1] = (ULONG)this_thread; + request[2] = (ULONG)new_prio; + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue is successful. */ + /* System Manager will eventually call start_osek_tasks. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + } + } + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ReleaseResource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* ReleaseResource is the counterpart of GetResource and serves to */ +/* leave critical sections in the code that are assigned to the */ +/* resource referenced by . For information on nesting */ +/* conditions, see GetResource. The service may be called from an ISR */ +/* and from task level */ +/* */ +/* INPUT */ +/* */ +/* id Id of the resource. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_NOFUNC Attempt to release a resource which is */ +/* not occupied by any task or ISR, or */ +/* another resource has to be released */ +/* before,If error occurs while creating */ +/* task */ +/* E_OS_ACCESS Attempt to release a resource which has*/ +/* a lower ceiling priority than the */ +/* statically assigned priority of the */ +/* calling task or interrupt routine. */ +/* */ +/* CALLS */ +/* */ +/* */ +/* osek_task_independent_area See if called from task independent */ +/* area */ +/* tx_thread_identify Identify the current thread */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType ReleaseResource(ResourceType id) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_RESOURCE *osek_res; +OSEK_TCB *tcb_ptr; +TX_THREAD *this_thread; +UINT index; +UINT res_prio; +UINT location; +UINT new_prio; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT status; +ULONG area; + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_ReleaseResource; + service_ReleaseResource.ResID = id; + + /* Fist check valid resource id and proper calling context. */ + + /* Check we calling from from task context only. */ + area = osek_task_independent_area(); + if(area == 0u) + { + exec_ErrorHook(E_OS_CALLEVEL); + + /* Return default error. */ + return (E_OS_CALLEVEL); + } + + /* Check for valid Resource ID. */ + if(id == 0u) + { + exec_ErrorHook(E_OS_ID); + + /* Return error. */ + return (E_OS_ID); + } + + /* Get thread currently executed. */ + this_thread = tx_thread_identify(); + if(this_thread == TX_NULL) + { + exec_ErrorHook(E_OS_CALLEVEL); + + return (E_OS_CALLEVEL); + } + + /* Get OSEK resource control block. */ + osek_res = (OSEK_RESOURCE *)id; + + /* Get the OSEK TCB. */ + tcb_ptr = (OSEK_TCB *)this_thread; + + /* Now check whether this resource is standard or internal. */ + + if (osek_res->type == INTERNAL) + { + /* Internal resource can not be released via ReleaseResource call. */ + exec_ErrorHook(E_OS_ID); + + return (E_OS_ID); + } + + TX_DISABLE + + /* Is this task holding any resource? Check for resource count. */ + if(tcb_ptr->res_ocp == 0u) + { + TX_RESTORE + + /* No resource taken yet trying to release resource? */ + exec_ErrorHook(E_OS_NOFUNC); + + /* Return error. */ + return(E_OS_NOFUNC); + } + + /* Check whether this resource is occupied by this task. */ + /* A task cannot release resource which are not occupied by itself. */ + + if (osek_res->taskid != (TaskType)tcb_ptr) + { + TX_RESTORE + + exec_ErrorHook(E_OS_NOFUNC); + + return (E_OS_NOFUNC); + } + + /* Everything is valid up to this point, now try to release the resource requested. */ + /* Check what type of Resource it is as RES_SCEDULER is a special case of resource. */ + + if (id == RES_SCHEDULER) + { + + /* Remove this task's id from the res's control block which usually indicate that this is the + owner of this res and also update this task's resource hold count. */ + osek_res->taskid = 0u; + tcb_ptr->res_ocp--; + + /* As the task is giving up RES_SCHEDULER, make the associated flag FALSE. */ + tcb_ptr->resource_scheduler = TX_FALSE; + + /* If Task is NON scheduling type, no preemption takes place. */ + if (tcb_ptr->policy == NON) + { + TX_RESTORE + + /* Release this resource. */ + return (E_OK); + } + + /* With FULL scheduling, a change in preemption to highest + ceiling priority of any other resources held by this task is needed. */ + /* Check RES_SCEDULER is the only resource occupied by this task, then restore this task's threshold + to its original priority. */ + + /* Assume no other resources are held. */ + new_prio = tcb_ptr->org_prio; + + if (tcb_ptr->res_ocp > 0u) + { + /* If no other external resources are held the task will revert back to + to its original design time priority. */ + /* Or check the ceiling priorities of other external resources held by this task. */ + + for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + if (tcb_ptr->external_resource_occuplied_list[index] == 0u) + { + break; + } + + res_prio = ((OSEK_RESOURCE *) (tcb_ptr->external_resource_occuplied_list[index]))->c_priority; + if (new_prio < res_prio) { + new_prio = res_prio; + } + } + } + + /* Done with external resource, now check if there are any internal resources held? */ + for ( index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) + { + break; + } + + res_prio = ((OSEK_RESOURCE *) (tcb_ptr->internal_resource_occuplied_list[index]))->c_priority; + + if (new_prio < res_prio) + { + new_prio = res_prio; + } + } + + + /* new_prio now holds the highest of ceiling priority of the remaining + resources held by this task. */ + + /* Now ask the system manager to change this task's priority, and also check if there is + any possibility of preemption. */ + /* Send message to the system manager to check any preemption out of ReleaseResource call. */ + + /* Build the request. */ + request[0] = SYSMGR_RELEASE_RESOURCE; /* Request type. */ + request[1] = (ULONG)this_thread; + request[2] = (ULONG)new_prio; + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue is successful. */ + /* System Manager will eventually call start_osek_tasks. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + + } + + TX_RESTORE + + /* Assume that the system manager does its job. */ + return (E_OK); + + } /* End if ( id == RES_SCHEDULER ). */ + + + /* Not a RES_SCHEDULER. */ + + /* Are we releasing the resource which is last taken? */ + for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + if ( tcb_ptr->external_resource_occuplied_list[index] == 0u) + { + /* Reached at the last entry, stop searching. */ + break; + } + } /* Next entry. */ + + if (index == 0u) + { + /* List is empty and resource is taken? */ + return(E_OS_NOFUNC); + } + + location = index - 1u; /* Save the location of last resource entry. */ + + /* Check the last resource taken. */ + if (tcb_ptr->external_resource_occuplied_list[location] != id) + { + /* Are we trying to release the resource which was not in LIFO order. */ + exec_ErrorHook(E_OS_NOFUNC); + + /* Return error. */ + return(E_OS_NOFUNC); + } + + /* Now to change preemption threshold to suit next resource with highest ceiling priority */ + /* But if the task has got NON scheduling policy then do nothing. */ + + tcb_ptr->external_resource_occuplied_list[location] = 0u; + /* And remove this task's id from the res's control block. */ + osek_res->taskid = 0u; + tcb_ptr->res_ocp--; + + if ((tcb_ptr->policy == NON ) || (tcb_ptr->resource_scheduler == TX_TRUE)) + { + /* In case of NON scheduling policy or if a Task holds a RES_SCHEDULER, no need to change preemption. */ + /* Even if a resource is released the task is still remains in OSEK_NON_SCHEDULE_PRIORITY. */ + /* just remove this resource from the list. */ + return (E_OK); + } + + /* FULL scheduling policy and no RES_SCHEDULER held. */ + + /* Assume no other resources are held. */ + new_prio = tcb_ptr->org_prio; + + if (tcb_ptr->res_ocp > 0u) + { + /* This task is holding more than one resources. */ + /* Find out new highest ceiling priority. */ + /* Assume task's original priority is the highest. */ + for ( index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + + /* Get this resource's ceiling priority. */ + if ( tcb_ptr->external_resource_occuplied_list[index] == 0u) { + break; + } + + res_prio = ((OSEK_RESOURCE *) (tcb_ptr->external_resource_occuplied_list[index]) )->c_priority; + /* Check if this is more than Task's static priority. */ + if (new_prio < res_prio) + { + new_prio = res_prio; + } + } + + } + + /* Done with external resource, now check if there are any internal resources held? */ + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) + { + break; + } + + res_prio = ( (OSEK_RESOURCE *) (tcb_ptr->internal_resource_occuplied_list[index]) )->c_priority; + + if (new_prio < res_prio ) + { + new_prio = res_prio; + } + } + + /* new_prio now holds the highest of ceiling priority of the remaining + resources held by this task. */ + + /* Now ask the system manager to change this task's priority, and also check if there is + any possibility of preemption. */ + /* Send message to system manager to check any preemption out of ReleaseResource call. */ + + /* Build the request. */ + request[0] = SYSMGR_RELEASE_RESOURCE; /* Request type. */ + request[1] = (ULONG)this_thread; + request[2] = (ULONG)new_prio; + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue is successful. */ + /* System manager will eventually call start_osek_tasks. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + } + + /* Assume that system manager does its job. */ + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* RegisterTasktoResource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function registers a resource to the task specified, provided */ +/* a free entry is available in the task's list of resources. */ +/* If entry is registered then resource's ceiling priority is also */ +/* adjusted to this task's priority provided that the task's priority */ +/* is higher than the resource's current ceiling priority. */ +/* */ +/* INPUT */ +/* */ +/* Resource Id of the resource. */ +/* TaskID ID of the task */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_NOFUNC No free entries */ +/* E_OS_ID Invalid task or resource id. */ +/* not occupied by any task or ISR, or */ +/* another resource has to be released */ +/* before. */ +/* E_OS_ACCESS Attempt to release an invalid resource */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code (System Creation section) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType RegisterTasktoResource(ResourceType Resource, TaskType TaskID) +{ + +OSEK_TCB *tcb_ptr; +OSEK_RESOURCE *resource_ptr; +UINT index; + + /* Check if we are in initialization. */ + /* This will ensure that no one calls this function after system is started. */ + if (osek_init_state != OSEK_INIT) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((StatusType)TX_NULL); + } + + /* Check for valid Resource ID. */ + if(Resource == 0u) + { + /* Return error. */ + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + /* Check if task id is valid. */ + if(TaskID == 0u) + { + /* Return error. */ + return (E_OS_ID); + } + + /* Convert object IDs to object control block pointers. */ + resource_ptr = (OSEK_RESOURCE *)Resource; + tcb_ptr = (OSEK_TCB *)TaskID; + + /* Check for valid resource pointer. */ + if (resource_ptr == TX_NULL) + { + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + if (resource_ptr->osek_res_id != OSEK_RES_ID) + { + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + /* Check for valid task pointer. */ + if (tcb_ptr == TX_NULL) + { + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + if ((tcb_ptr->osek_task_id != OSEK_TASK_ID) && (tcb_ptr->osek_task_id != OSEK_ISR_ID)) + { + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + /* This task is to be registered with this resource. */ + /* Add this Resource to the task's list of resource. */ + /* provided there is space left for this. */ + + /* Before check whether the resource is internal or standard? */ + if ((resource_ptr->type == STANDARD)|| (resource_ptr->type == LINKED)) + { + + for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + if (tcb_ptr->external_resource_list[index] == 0u) + { + /* Empty entry found, write this resource there. */ + tcb_ptr->external_resource_list[index] = Resource; + + /* Also clear the resource occupancy count. */ + tcb_ptr->external_resource_occuplied_list[index] = 0u; + + /* As this resource is attached to a TASK or ISR change this resource's ceiling priority + to task's (or ISR's) priority provided that it is higher than resource's current ceiling priority. */ + if (tcb_ptr->org_prio > resource_ptr->c_priority) + { + resource_ptr->c_priority = tcb_ptr->org_prio; + } + + /* Job done. */ + break; + } /* Try next entry. */ + } + + if (index >= OSEK_MAX_EXTERNAL_RES) /* No free entry. */ + { + Application->osek_object_creation_error++; + return (E_OS_NOFUNC); + } + else + { + return (E_OK); + } + } /* END STANDARD. */ + else + { + /* Attaching Internal resource to this task, so set the flag. */ + tcb_ptr->internal_res = TX_TRUE; + + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_list[index] == 0u) + { + /* Empty entry found write this resource there. */ + tcb_ptr->internal_resource_list[index] = Resource; + + /* As this resource is attached to the resource change this resource's ceiling priority + to this task's original priority provide it is higher than resource's current ceiling priority. */ + if (tcb_ptr->org_prio > resource_ptr->c_priority) + { + resource_ptr->c_priority = tcb_ptr->org_prio; + } + + /* Job done. */ + break; + } /* Try next entry. */ + } + + if (index >= OSEK_MAX_INTERNAL_RES) /* No free entry. */ + { + Application->osek_object_creation_error++; + return (E_OS_NOFUNC); + } + else + { + return (E_OK); + } + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* RegisterISRtoResource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function registers a resource to the ISR specified, provided */ +/* a free entry is available in the ISR's list of resources. */ +/* If entry is registered then resource's ceiling priority is also */ +/* adjusted to this task's priority provided that the task's priority */ +/* is higher than the resource's current ceiling priority. */ +/* */ +/* INPUT */ +/* */ +/* Resource Id of the resource. */ +/* TaskID ID of the task */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_NOFUNC No free entries */ +/* E_OS_ID Invalid task or resource id. */ +/* not occupied by any task or ISR, or */ +/* another resource has to be released */ +/* before */ +/* E_OS_ACCESS Attempt to release an invalid resource */ +/* */ +/* CALLS */ +/* */ +/* RegisterTasktoResource Register resource. */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType RegisterISRtoResource(ResourceType Resource, ISRType ISRID) +{ +StatusType status; + + status = RegisterTasktoResource(Resource, ISRID); + return (status); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* CreateEvent PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Creates an event. It is a 32 bit number with only one bit set. */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* eventid If success */ +/* 0 If error occurs */ +/* */ +/* CALLS */ +/* */ +/* osek_get_event Get the event */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal call */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +EventMaskType CreateEvent(void) +{ +EventMaskType event; + + event = osek_get_event(); + if (event == 0u) + { + /* Error will be returned whenever the ThreadX call fails. */ + Application->osek_object_creation_error++; + return (0u); + } + + return (event); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* SetEvent PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Sets events of the given task according to the event mask. */ +/* */ +/* INPUT */ +/* */ +/* task ID ID for the task */ +/* mask Mask of the events to be set. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_ID Invalid task or event id */ +/* E_OS_STATE Invalid target task state */ +/* */ +/* CALLS */ +/* */ +/* tx_event_flags_set Set ThreadX event flag. */ +/* osek_internal_error OSEK Internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType SetEvent(TaskType task_id, EventMaskType mask) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +TX_THREAD *this_thread; +EventMaskType balance_events; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT status; +OSEK_TCB *p_this_tcb; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_SetEvent; + service_SetEvent.TaskID = task_id; + + /* Check if task id not valid. */ + if(task_id == 0u) + { + exec_ErrorHook(E_OS_ID); + + /* Return error. */ + return (E_OS_ID); + } + + /* Get TCB_PTR. */ + tcb_ptr = (OSEK_TCB *)task_id; + + if (tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + exec_ErrorHook(E_OS_ID); + + /* Return error. */ + return (E_OS_ID); + } + + /* Check if any event is assigned to task. */ + if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC)) + { + exec_ErrorHook(E_OS_ACCESS); + + /* No event assigned to task, return error. */ + return (E_OS_ACCESS); + } + + TX_DISABLE + + if (tcb_ptr->suspended == TX_TRUE) + { + TX_RESTORE + + exec_ErrorHook(E_OS_STATE); + + /* Return error. */ + return (E_OS_STATE); + } + + /* Check this event mask with the task . */ + /* Update the set events for this task with this new mask. */ + tcb_ptr->set_events = tcb_ptr->set_events | mask; + + /* See how many events are set. */ + balance_events = tcb_ptr->set_events & tcb_ptr->waiting_events; + + /* Is there any from waiting events. */ + if (balance_events != 0u) + { + /* Get calling task's ThreadX thread */ + this_thread = tx_thread_identify(); + + /* Check whether the same running task is setting its own events or + the task is already out of wait state. */ + /* if yes then no need to add this task in the ready list and of course no + need to check for any preemption possibilities. */ + + p_this_tcb = osek_thread2tcb(this_thread); + if ((tcb_ptr != p_this_tcb) && (tcb_ptr->waiting == TX_TRUE)) + { + tcb_ptr->waiting = TX_FALSE; + /* Now, send message to the system manager to check any preemption out of SetEvent() call. */ + + /* Build the request. */ + request[0] = SYSMGR_SETEVENT; /* Request type. */ + request[1] = (ULONG)this_thread; /* ThreadX Thread for this task. */ + request[2] = (ULONG)tcb_ptr; /* id in OSEK_TCB format. */ + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue is successful. */ + /* System Manager will eventually call start_osek_tasks. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + + } + } + + } + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ClearEvent PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Clears events of the calling task according to the event mask. */ +/* */ +/* INPUT */ +/* */ +/* mask Mask of the events to be cleared */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success */ +/* ERROR If error occurs while creating task */ +/* */ +/* CALLS */ +/* */ +/* tx_event_flags_set Set or clears ThreadX event flag */ +/* osek_task_independent_area See if out of task context */ +/* tx_thread_identify Identify the current thread */ +/* tx_event_flags_set Set the event Flags */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType ClearEvent(EventMaskType mask) +{ +TX_INTERRUPT_SAVE_AREA +TX_THREAD *this_thread; +OSEK_TCB *tcb_ptr; +ULONG area; + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_ClearEvent; + service_ClearEvent.EventID = mask; + /* Check if we are calling from initialization. */ + if (osek_init_state == OSEK_INIT) + { + exec_ErrorHook(E_OS_CALLEVEL); + + /* Return error. */ + return (E_OS_CALLEVEL); + } + + /* Check if we are not at task level. */ + area = osek_task_independent_area(); + if(area == 0u) + { + exec_ErrorHook(E_OS_CALLEVEL); + + /* Return error. */ + return (E_OS_CALLEVEL); + } + + this_thread = tx_thread_identify(); + + /* Get OSEK TCB. */ + tcb_ptr = (OSEK_TCB *)this_thread; + + /* Check if any event is assigned to task. */ + if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC)) + { + exec_ErrorHook(E_OS_ACCESS); + + /* No event assigned to task, return error. */ + return (E_OS_ACCESS); + } + + TX_DISABLE + + /* Update the events. */ + tcb_ptr->set_events = tcb_ptr->set_events & (~mask); + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetEvent PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Gets the current event setting of the given task. */ +/* */ +/* INPUT */ +/* */ +/* task_id ID or the task */ +/* mask Mask of the events to be set. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* ERROR If an error occurs */ +/* */ +/* CALLS */ +/* */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetEvent(TaskType task_id, EventMaskRefType event) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetEvent; + service_GetEvent.TaskID = task_id; + + /* Check if task id is valid. */ + if(task_id == 0u) + { + exec_ErrorHook(E_OS_ID); + + /* Return error. */ + return (E_OS_ID); + } + + /* Get the tcb pointer. */ + tcb_ptr = (OSEK_TCB *)task_id; + + if (tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + exec_ErrorHook(E_OS_ID); + + /* Return error. */ + return (E_OS_ID); + } + + /* Check if any event is assigned to task and task is extended type. */ + if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC)) + { + exec_ErrorHook(E_OS_ACCESS); + + /* No event assigned to task, return error. */ + return (E_OS_ACCESS); + } + + TX_DISABLE + + if (tcb_ptr->suspended == TX_TRUE) + { + TX_RESTORE + + exec_ErrorHook(E_OS_STATE); + + /* Return error. */ + return (E_OS_STATE); + } + + /* Get the event. */ + *event = tcb_ptr->set_events; + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* WaitEvent PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Transfers the calling task into the waiting state until specified */ +/* events are set. */ +/* */ +/* INPUT */ +/* */ +/* mask Mask of the events to be set */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success */ +/* ERROR If error occurs while creating task */ +/* */ +/* CALLS */ +/* */ +/* tx_event_flags_get Retrieves ThreadX event flag from */ +/* specified ThreadX event flag group */ +/* osek_internal_error OSEK internal error */ +/* tx_thread_identify Identify current thread */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType WaitEvent(EventMaskType mask) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +TX_THREAD *this_thread; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT index; +UINT status; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_WaitEvent; + service_WaitEvent.EventID = mask; + + + /* Check if we are in interrupt. */ + if((_tx_thread_current_ptr == TX_NULL) || /* Not in a task. */ + (_tx_thread_system_state != 0u)) /* In an ISR. */ + { + exec_ErrorHook(E_OS_CALLEVEL); + + /* Return error. */ + return (E_OS_CALLEVEL); + } + + /* Check if the thread is currently executed. */ + this_thread = tx_thread_identify(); + if(this_thread == TX_NULL) + { + exec_ErrorHook(E_OS_CALLEVEL); + + /* Not allowed on the calling thread. */ + return (E_OS_CALLEVEL); + } + + /* Get OSEK TCB. */ + tcb_ptr = (OSEK_TCB *)this_thread; + + /* Check if any event is assigned to task or the task is of BASIC type. */ + if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC)) + { + exec_ErrorHook(E_OS_ACCESS); + + /* No event assigned to task, return error. */ + return (E_OS_ACCESS); + } + + /* Check if any resource is occupied by this task. */ + if(tcb_ptr->res_ocp != 0u) + { + exec_ErrorHook(E_OS_RESOURCE); + + /* Return error. */ + return (E_OS_RESOURCE); + } + + TX_DISABLE + + tcb_ptr->waiting_events = mask; + + /* Is any event set? */ + if ((tcb_ptr->set_events & tcb_ptr->waiting_events) != 0u) + { + TX_RESTORE + + return (E_OK); + } + else + { + /* Events are not set wait for them. */ + tcb_ptr->waiting = TX_TRUE; + } + + /* Release any internal resources held. */ + if (tcb_ptr->internal_res != 0u) + { + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) + { + break; + } + + ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u; + tcb_ptr->internal_resource_occuplied_list[index] = 0u; + + } + } + + /* Now, send message to system thread to check any preemption out of the WaitEvent() call. */ + + /* Build the request. */ + request[0] = SYSMGR_WAITEVENT; /* Request type. */ + request[1] = (ULONG)this_thread; /* Self ID. */ + request[2] = (ULONG)tcb_ptr; /* Self Id in OSEK_TCB format. */ + request[3] = 0u; + /* Now send a message to the SysMgr supervisor thread and ask */ + /* to check any preemption is possible. */ + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue is successful. */ + /* System Manager will eventually call start_osek_tasks. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + } + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* RegisterEventtoTask PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function registers an event to the task specified, provided */ +/* a free entry is available in the task's list of events. */ +/* */ +/* INPUT */ +/* */ +/* event_id Id of the event */ +/* TaskID Id of the task */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_NOFUNC No free entries */ +/* E_OS_ID Invalid task or resource id. */ +/* not occupied by any task or ISR, or */ +/* another resource has to be released */ +/* before. */ +/* E_OS_ACCESS Attempt to release an invalid resource */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code (System Creation section) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType RegisterEventtoTask(EventMaskType eventid, TaskType TaskID) +{ + +OSEK_TCB *tcb_ptr; + + /* Check if we are in initialization. */ + /* This will ensure that no one calls this function after system is started. */ + if (osek_init_state != OSEK_INIT) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + return ((StatusType)TX_NULL); + } + + /* Check if task id is valid. */ + if(TaskID == 0u) + { + + /* Return error. */ + Application->osek_object_creation_error++; + + return (E_OS_ID); + } + + + + /* Convert object IDs to object control block pointers. */ + tcb_ptr = (OSEK_TCB*)TaskID; + + + /* Check for valid task pointer. */ + if (tcb_ptr == TX_NULL) + { + Application->osek_object_creation_error++; + + return (E_OS_ID); + } + + if(tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + Application->osek_object_creation_error++; + + return (E_OS_ID); + } + + /* This task is to be registered with this event. */ + tcb_ptr->events = tcb_ptr->events | eventid; + + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* EnableInterrupt PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This service enables interrupts. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType EnableInterrupt(void) +{ + TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + + if (disable_ISR2 != 0u) { + disable_ISR2--; + } + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* DisableInterrupt PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This service disables interrupts. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType DisableInterrupt(void) +{ + TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + + disable_ISR2++; + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetInterruptDescriptor PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Query of interrupt status and returns the current CPU interrupt */ +/* mask */ +/* */ +/* INPUT */ +/* */ +/* mask A reference to the interrupt mask to be */ +/* filled. In the mask, a "1" means (Group */ +/* of) Interrupt is enabled. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success */ +/* ERROR If error occurs while creating task */ +/* */ +/* CALLS */ +/* */ +/* tx_interrupt_control Enables or disables interrupts */ +/* specified by new_posture */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetInterruptDescriptor(UINT *mask) +{ +UINT old_posture; +UINT new_posture; + + /* Get the old posture of the interrupt. */ + old_posture = tx_interrupt_control(TX_INT_DISABLE); + + new_posture = old_posture; + + /* Invert the mask for OSEK interrupt. */ + *mask = ~old_posture ; + + /* Restore the same interrupts. */ + tx_interrupt_control(new_posture); + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* SuspendAllInterrupts PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call serves to enter critical sections by disabling all */ +/* interrupts. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void SuspendAllInterrupts (void) +{ + TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + suspend_ISR2++; + TX_RESTORE +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ResumeAllInterrupts PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Exits a critical section entered by calling SuspendAllInterrupts. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area See if called from task independent */ +/* area */ +/* tx_thread_identify Identify the current thread */ +/* osek_internal_error Osek internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void ResumeAllInterrupts (void) +{ +TX_INTERRUPT_SAVE_AREA +TX_THREAD *thread_ptr; +UINT status; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; + + TX_DISABLE + if (suspend_ISR2 != 0u) + { + suspend_ISR2--; + } + + if (suspend_ISR2 == 0u) + { + /* Interrupts resume, check if any pending. */ + /* get the pointer to the calling thread. */ + thread_ptr = tx_thread_identify(); + + /* Now send a message to the SysMgr supervisor thread to execute the error hook. */ + /* Build the request. */ + request[0] = SYSMGR_ERRORHOOK; /* Request type. */ + request[1] = (ULONG)thread_ptr; /* Ptr of calling thread. */ + request[2] = 0u; /* Input to Error hook. */ + request[3] = 0u; + + /* Since the SysMgr supervisor thread is has the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue read is successful. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + TX_RESTORE + + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + + /* Return. */ + return; + } + + } /* end if (!suspend_ISR2). */ + + TX_RESTORE + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* DisableAllInterrupts PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call serves to enter critical sections by disabling all */ +/* interrupts. */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void DisableAllInterrupts (void) +{ +TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + disable_ISR2++; + TX_RESTORE +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* EnableAllInterrupts PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Exits a critical section entered by calling DisableAllInterrupts. */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void EnableAllInterrupts (void) +{ +TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + if (disable_ISR2 != 0u) + { + disable_ISR2--; + } + TX_RESTORE +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* SuspendOSInterrupts PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call serves to enter critical sections by disabling all */ +/* interrupts. */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void SuspendOSInterrupts (void) +{ +TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + suspend_ISR2++; + TX_RESTORE +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ResumeOSInterrupts PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Exits a critical section entered by calling SuspendOSInterrupts. */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area See if called from task independent */ +/* area */ +/* tx_thread_identify Identify the current thread */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void ResumeOSInterrupts (void) +{ +TX_INTERRUPT_SAVE_AREA +TX_THREAD *thread_ptr; +UINT status; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; + + TX_DISABLE + + if (suspend_ISR2 != 0u) + { + suspend_ISR2--; + } + + if (suspend_ISR2 == 0u) + { + /* Interrupts resume, check if any pending. */ + /* get the pointer to the calling thread. */ + thread_ptr = tx_thread_identify(); + + /* Now send a message to the SysMgr supervisor thread to execute the error hook */ + /* Build the request. */ + request[0] = SYSMGR_ERRORHOOK; /* Request type. */ + request[1] = (ULONG)thread_ptr; /* Pointer of calling thread. */ + request[2] = 0u; /* Input to Error hook. */ + request[3] = 0u; + + /* Since the SysMgr supervisor thread is with the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue read is successful. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + TX_RESTORE + + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + + /* Return. */ + return; + } + + } /* end if (!suspend_ISR2). */ + + TX_RESTORE + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetActiveApplicationMode PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call returns the current application mode. */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* Current application mode */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +AppModeType GetActiveApplicationMode(void) +{ + return (Application->application_mode); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetCounterValue PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Returns the current value of a counter. */ +/* */ +/* INPUT */ +/* */ +/* counter_ptr Pointer to OSEK Counter */ +/* tick_ptr Pointer to ticks */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_ID Invalid counter object */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetCounterValue(OSEK_COUNTER *counter_ptr, TickRefType tick_ptr) +{ + + /* Check for valid counter. */ + if ((counter_ptr != TX_NULL) && (counter_ptr->osek_counter_id == OSEK_COUNTER_ID)) + { + *tick_ptr = counter_ptr->counter_value; + } + else + { + /* There is error in counter object supplied. */ + return (E_OS_ID); + } + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* CreateCounter PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Creates a counter. */ +/* */ +/* INPUT */ +/* */ +/* N/A */ +/* */ +/* OUTPUT */ +/* */ +/* COUNTER_ID Reference to counter */ +/* */ +/* CALLS */ +/* */ +/* osek_memory_allocate Allocate memory from system */ +/* osek_counter_name_check Check if counter name duplicate */ +/* osek_get_counter Get pointer to counter structure */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +CounterType CreateCounter(const CHAR *name, TickType max_allowed_value, TickType ticks_per_base, + TickType min_cycle, TickType start_value) +{ + +CounterType cntr_id; +OSEK_COUNTER *cntr_ptr; +UINT index; + + /* Check if we are in initialization. */ + /* This will ensure that no one calls this function after system is started. */ + if (osek_init_state != OSEK_INIT) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + + return((TaskType)TX_NULL); + } + + /* Check if there is space for this counter. */ + cntr_id = osek_get_counter(); + if (cntr_id == 0u) + { + /* Return error. */ + Application->osek_object_creation_error++; + + return ((CounterType) TX_NULL); + } + + /* Get the pointer to counter structure. */ + cntr_ptr = (OSEK_COUNTER *)cntr_id; + + + if (max_allowed_value > MAXALLOWEDVALUE) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + + return ((TaskType)TX_NULL); + } + + /* Store maximum value of this counter. */ + cntr_ptr->maxallowedvalue = max_allowed_value; + + if (min_cycle > MAXALLOWEDVALUE) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + + return ((TaskType)TX_NULL); + } + + /* Store minimum allowed number of ticks of the counter. */ + cntr_ptr->mincycle = min_cycle; + + if (ticks_per_base > MAXALLOWEDVALUE) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + + return ((TaskType)TX_NULL); + } + + /* Store ticksperbase. */ + cntr_ptr->ticksperbase = ticks_per_base; + + /* Store start up value. */ + if (start_value > max_allowed_value) + { + cntr_ptr->counter_value = start_value; + } + else + { + cntr_ptr->counter_value = 0u; + } + + /* Store object identifier. */ + cntr_ptr->osek_counter_id = OSEK_COUNTER_ID; + + /* Now initialize the list of alarms attached to this counter. */ + + for (index = 0u; index < OSEK_MAX_ALARMS; index++) + { + cntr_ptr-> alarm_list[ index ] = 0u; + } + + cntr_ptr->cntr_in_use = TX_TRUE; + + cntr_ptr->name = name; + + /* Return the created counter. */ + return ((CounterType) cntr_ptr); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* IncrCouner PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function increments the specified counter, checks its new */ +/* value with all alarms attached to it and triggers expired alarms. */ +/* If an alarm is expired then its actions are executed from here. */ +/* */ +/* INPUT */ +/* */ +/* Counter Counter to update */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_ID If counter id is not correct */ +/* E_OS_NOFUNC In case of any errors */ +/* */ +/* CALLS */ +/* */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType IncrCounter(CounterType cntr) +{ + +TX_INTERRUPT_SAVE_AREA + +OSEK_COUNTER *cntr_ptr; +UINT index; +UINT msg_cnt; +UINT save_op_mode; +AlarmType alarmid; +OSEK_ALARM *this_alarm; +UINT this_action; +UINT alarm_fired; +UINT status; +OSEK_TCB *tcb_ptr; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +EventMaskType balance_events; + +cntr_ptr = (OSEK_COUNTER *)cntr; + + /* Check for valid counter. */ + if ((cntr_ptr == TX_NULL) && (cntr_ptr->osek_counter_id != OSEK_COUNTER_ID)) + { + /* There is error in counter object supplied. */ + return (E_OS_ID); + } + + /* Disable interrupt. */ + TX_DISABLE + + if (cntr_ptr->cntr_in_use == TX_FALSE) + { + TX_RESTORE + + return (E_OS_ID); + } + + if (cntr_ptr->ticksperbase == 0u) + { + TX_RESTORE + + return (E_OS_NOFUNC); + } + + + /* Increment counters sub count and check it with tick_pre-Base. */ + cntr_ptr->sub_count++; + if (cntr_ptr->sub_count < cntr_ptr->ticksperbase) + { + /* Still need to count enough to reach tics-per-base, no need to increment + main count. */ + TX_RESTORE + + return (E_OK); + } + + /* Reached to tick-per-base, reset it and increment main count. */ + cntr_ptr->sub_count = 0u; + + /* Now increment the counter value. */ + if ( cntr_ptr->counter_value >= cntr_ptr->maxallowedvalue) + { + cntr_ptr->counter_value = 0u; + } + else + { + (cntr_ptr->counter_value)++; + } + + /* Now check if counter is rolled back to zero. */ + if ( cntr_ptr->counter_value == 0u) + { + /* Counter is rolled back set flags in all Alarms attached to this counter. */ + for (index = 0u; index < OSEK_MAX_ALARMS; index++) + { + alarmid = cntr_ptr->alarm_list[index]; + if (alarmid == 0u) + { + continue; + } + + /* Something is defined. */ + this_alarm = (OSEK_ALARM *)alarmid; + + /* But is it a valid OSEK ALARM? */ + if((this_alarm == TX_NULL) || (this_alarm->osek_alarm_id != OSEK_ALARM_ID)) + { + continue; + } + + /* Yes this is a valid alarm , but is it armed? */ + if ( this_alarm->armed == TX_FALSE) + { + continue; + } + /* This is an ALARM and is armed, set its rollback flag. */ + /* This flag will be cleared when an alarm is armed again or expired. */ + this_alarm->counter_rollback = TX_TRUE; + } + } + + /* Reset a count of messages sent to the system manager. */ + msg_cnt = 0u; + + /* Now it is time to check all alarms for expiration. */ + for (index = 0u; index < OSEK_MAX_ALARMS; index++) + { + + alarm_fired = TX_FALSE; + + /* Get the alarm id. */ + alarmid = cntr_ptr->alarm_list[index]; + if (alarmid == 0u) + { + continue; /* This alarm is not for me, go to check next alarm. */ + } + + /* Something is defined, try to get the AlarmID. */ + this_alarm = (OSEK_ALARM *)alarmid; + + /* But is it a valid OSEK ALARM? */ + if((this_alarm == TX_NULL) || (this_alarm->osek_alarm_id != OSEK_ALARM_ID)) + { + continue; + } + + /* Yes this is a valid alarm , but is it armed? */ + if (this_alarm->armed == TX_FALSE) /* This alarm is not armed, go to check next alarm. */ + { + continue; + } + + /* Now check this with counter's current value, if it is less than it do not fire alarm. */ + if (this_alarm->rel_abs_mode == RELATIVE_ALARM) + { + /* It is a REALTIVE ALARM. */ + if (cntr_ptr->counter_value < this_alarm->expiration_count) + { + continue; /* Not yet expired. */ + } + else + { + /* Alarm expired, set flag. */ + alarm_fired = TX_TRUE; + } + } /* End It is a REALTIVE ALARM. */ + else + { + /* It is ABSOLUTE ALARM. */ + if (cntr_ptr->counter_value < this_alarm->expiration_count) + { + /* counter is less than expiration. */ + continue; /* Not yet expired. */ + } + + if (cntr_ptr->counter_value == this_alarm->expiration_count) + { + /* If both are equal alarm is fired. */ + alarm_fired = TX_TRUE; + } + else + { + /* count > expiration alarm to fire only if roll back occurred. */ + /* This check is required, because when an Alarm is started in ABS mode, counter's current value could + be more than the alarm's expiration count, so that may fire an Alarm the moment it is Armed, + in fact, under such condition (counter's current value more than + the alarm's expiration count, at the time of arming the alarm) the alarm will expires only when , the + counter counts to its max value then rolls back to zero then again counts up and now when it + reaches the alarm's expiration count, the alarm gets fired. */ + + if (this_alarm->counter_rollback == TX_FALSE) + { + continue; + } + else + { + alarm_fired = TX_TRUE; + } + + } + + } /* END: else { ABSOLUTE ALARM .. */ + + + /* STILL IN for ( index = 0; index < OSEK_MAX_ALARMS; index++) LOOP. */ + + /* Check alarm has fired? */ + + if (alarm_fired == TX_FALSE) + { + continue; + } + + /* Reached here means an alarm has fired. */ + /* Clear the counter roll back flag. */ + this_alarm->counter_rollback = TX_FALSE; + + /* Dis arm the Alarm */ + this_alarm->armed = TX_FALSE; + + /* But is it cyclic? */ + if (this_alarm->cycle != 0u) + { + /* Yes, then load new expiration count. */ + this_alarm->expiration_count += this_alarm->cycle; + /* Arm the alarm for next cycle. */ + this_alarm->armed = TX_TRUE; + } + + /* Get what action to be taken for this alarm. */ + this_action = this_alarm->action; + + /* Check for action to be taken. */ + switch(this_action) + { + case CALLBACK: + + /* Call a call-back function. */ + if (this_alarm->alarm_callback != TX_NULL) + { + save_op_mode = osek_wrapper_operation_mode; + osek_wrapper_operation_mode = ALARM_CALLBACK_MODE; + (this_alarm->alarm_callback)(); + osek_wrapper_operation_mode = save_op_mode; + } + break; + + case ACTIVATETASK: + /* Activate a task. */ + /* Get the OSEK TCB for the task to be activated. */ + tcb_ptr = (OSEK_TCB *)(this_alarm->task); + + /* Check for any invalid thread pointer. */ + if((tcb_ptr == TX_NULL) || ((tcb_ptr->task.tx_thread_id) != TX_THREAD_ID)) + { + break; + } + + /* Check whether the task is activated up to its defined multiple activations. */ + if(tcb_ptr->current_active >= tcb_ptr->max_active) + { + break; + } + + /* Now send a message to the System Manager thread to activate this task. */ + /* Build the request. */ + request[0] = SYSMGR_ACTIVATE_TASK; /* Request type. */ + request[1] = (ULONG)tcb_ptr; /* task to Activate. */ + request[2] = last_run_task; /* task currently executing. */ + request[3] = 0u; + status = tx_queue_send (&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_ACTIVATETASK); + } + + /* One message sent, increment the msg counter, this is required because + the System manager message queue can hold only certain number of messages. */ + msg_cnt++; + break; + + case SETEVENT: + /* Set the specified events for the specified task. */ + /* Check if task id not valid. */ + if (this_alarm->task == TX_NULL) + { + break; + } + + /* Get TCB_PTR. */ + tcb_ptr = (OSEK_TCB *) (this_alarm->task); + + if (tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + break; + } + + /* Check if any event is assigned to task. */ + if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC)) + { + break; + } + + if (tcb_ptr->suspended == TX_TRUE) + { + break; + } + + /* Check this event mask with the task. */ + /* Update the set events for this task with this new mask. */ + tcb_ptr->set_events = tcb_ptr->set_events | (this_alarm->events); + + /* See if any events is set. */ + balance_events = tcb_ptr->set_events & tcb_ptr->waiting_events; + + /* Is there any from waiting events. */ + if (balance_events != 0u) + { + + if (tcb_ptr->waiting == TX_TRUE) + { + tcb_ptr->waiting = TX_FALSE; + /* Now, send message to the system manager to check any preemption out of SetEvent call. */ + + /* Build the request. */ + request[0] = SYSMGR_SETEVENT; /* Request type. */ + request[1] = last_run_task; /* Task currently executing. */ + request[2] = (ULONG)tcb_ptr; /* Task id for which events are set. */ + request[3] = 0u; + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + } + + + /* One message sent, increment the msg counter, this required because + System manager message queue can hold only certain number of messages. */ + msg_cnt++; + + } /* End if (tcb_ptr->waiting == TX_TRUE). */ + } /* End if (balance_events). */ + break; + + default: + break; + } /* switch ends. */ + + /* A situation may arise that multiple alarms expire at time (being set to same expiration count and mode) + Which means timer has to send multiple alarm action messages to the system manager. But as the system manager accepts + only certain number of messages at a time, we can't send more than that number of alarm action + messages (SetEvent, ActivateTask) in one loop, + so check if the system manager queue is filled up if yes stop checking for next alarm, we'll come again to check + balance alarms. */ + + if (msg_cnt == (SYSMGR_QUEUE_MSG_COUNT)) + { + break; + } + + } /* for ends. */ + + /* Enable interrupt. */ + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* DefineSystemCounter PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This functions sets the system counter by assigning the specified */ +/* counter as a system counter. */ +/* If a counter is already defined as a system counter this call will */ +/* return an error. */ +/* */ +/* INPUT */ +/* */ +/* Counter Counter to assign as system counter */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_ID If counter id is invalid */ +/* E_OS_NOFUNC Counter already assigned */ +/* */ +/* CALLS */ +/* */ +/* tx_timer_activate starts the Thread timer to update */ +/* this SystemCounter */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType DefineSystemCounter (CounterType cntr) +{ + +OSEK_COUNTER *cntr_ptr; +OSEK_COUNTER *this_counter; +UINT index; +UINT attached; + + /* Check if we are in initialization. */ + /* This will ensure that no one calls this function after system is started. */ + if (osek_init_state != OSEK_INIT) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + + return ((TaskType)TX_NULL); + } + + /* Convert counter id to counter pointer. */ + + cntr_ptr = (OSEK_COUNTER *)cntr; + + /* Check for valid counter. */ + if ((cntr_ptr == TX_NULL) && (cntr_ptr->osek_counter_id != OSEK_COUNTER_ID)) + { + /* There is error in counter object supplied. */ + Application->osek_object_creation_error++; + + return (E_OS_ID); + } + + if (cntr_ptr->cntr_in_use == TX_FALSE) + { + Application->osek_object_creation_error++; + + return (E_OS_ID); + } + + /* Now check if there any a counter exists attached to system timer? */ + attached = TX_FALSE; + + /* Search for a free counter. */ + this_counter = osek_counter_pool; + for (index = 0u; index < OSEK_MAX_COUNTERS; index++) + { + /* Is this guy is attached to system timer? */ + if (this_counter->system_timer == TX_TRUE) + { + /* This counter is attached to system timer. */ + attached = TX_TRUE; + /* Stop searching. */ + break; + } + + this_counter++; + } /* check all counters. */ + + /* No body attached to system timer? */ + if (attached == TX_FALSE) + { + /* No one is attached, attach counter supplied to system timer. */ + cntr_ptr->system_timer = TX_TRUE; + + /* Now start the system timer. */ + tx_timer_activate(&osek_system_timer); + + return (E_OK); + } + + /* One counter is already attached to system timer. */ + Application->osek_object_creation_error++; + + return (E_OS_NOFUNC); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* CreateAlarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Creates an alarm. */ +/* */ +/* INPUT */ +/* */ +/* ticks Tick count */ +/* */ +/* OUTPUT */ +/* */ +/* ALARM_ID Reference to alarm */ +/* */ +/* CALLS */ +/* */ +/* osek_get_alarm Get the alarm if possible */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +AlarmType CreateAlarm(const CHAR *name, CounterType cntr, UINT action, ULONG events, TaskType task, + void (*callback)(), UINT Startup, TickType Alarmtime, TickType Cycle ) +{ + +AlarmType alarm_id; +OSEK_COUNTER *cntr_ptr; +OSEK_TCB *tcb_ptr; +OSEK_ALARM *this_alarm; +UINT index; +TickType current_value; +StatusType status; + + /* Check if we are in Initialization. */ + /* This will ensure that no one calls this function after system is started. */ + if (osek_init_state != OSEK_INIT) + { + /* Return OSEK internal error. This is not a standard OSEK error. */ + Application->osek_object_creation_error++; + + return ((TaskType)TX_NULL); + } + + /* Start with validating arguments passed. */ + cntr_ptr = (OSEK_COUNTER*)cntr; + if ((cntr_ptr == TX_NULL) || (cntr_ptr->osek_counter_id != OSEK_COUNTER_ID)|| (cntr_ptr->cntr_in_use == TX_FALSE)) + { + /* Counter is not valid. */ + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + if (cntr_ptr->cntr_in_use != TX_TRUE) + { + /* Counter is not in use. */ + Application->osek_object_creation_error++; + + return (E_OS_ID); + } + + tcb_ptr = (OSEK_TCB *)task; + + /* Check the action to be taken and parameters passed. */ + switch(action) + { + case SETEVENT: + + /* For SetEvents there should not be call back function. */ + if((events == 0u) || (task == 0u) || (callback != TX_NULL)) + { + /* Return error. */ + Application->osek_object_creation_error++; + + return (E_OS_NOFUNC); + } + + if ((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_TASK_ID)) + { + /* Task is not valid. */ + Application->osek_object_creation_error++; + + return (E_OS_ID); + } + + if (tcb_ptr->tcb_in_use != TX_TRUE) + { + /* Task is not in use */ + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + break; + + case ACTIVATETASK: + /* For activate task there should not be any call-back function or any event. */ + if((task == 0u) || (events != 0u) || (callback != TX_NULL)) + { + /* Return error. */ + Application->osek_object_creation_error++; + + return (E_OS_NOFUNC); + } + + if ((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_TASK_ID)) + { + /* Task is not valid. */ + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + if (tcb_ptr->tcb_in_use != TX_TRUE) + { + /* Task is not in use. */ + Application->osek_object_creation_error++; + return (E_OS_ID); + } + + break; + + case CALLBACK: + /* For ALARMCALLBACK there should not be task or any event. */ + if((callback == TX_NULL) || (events != 0u) || (task != 0u)) + { + /* Return error. */ + Application->osek_object_creation_error++; + + return (E_OS_NOFUNC); + } + + break; + + default: + /* Return error. */ + Application->osek_object_creation_error++; + + return (E_OS_NOFUNC); + + break; + } + + /* Check if there is space for this alarm. */ + alarm_id = osek_get_alarm(); + if (alarm_id == 0u) + { + /* Return error. */ + Application->osek_object_creation_error++; + + return (E_OS_NOFUNC); + } + + /* Got correct inputs, get pointer to alarm. */ + this_alarm = (OSEK_ALARM *)alarm_id; + + /* Store object id. */ + this_alarm->osek_alarm_id = OSEK_ALARM_ID; + + /* Before attaching this alarm to a counter, disarm it. */ + this_alarm->armed = TX_FALSE; + + this_alarm->name = name; + + /* Now, try attaching this alarm to the counter specified. */ + for (index = 0u; index < OSEK_MAX_ALARMS; index++) + { + /* Find a free entry in the list maintained by the counter. */ + if (cntr_ptr->alarm_list[index] == 0u) + { + /* Found one. */ + cntr_ptr->alarm_list[index] = alarm_id; + + break; + } + } + + /* Searched the entire list and came empty handed? */ + if (index >= OSEK_MAX_ALARMS) + { + /* Return error. */ + osek_reset_alarm(this_alarm); + + Application->osek_object_creation_error++; + + return (E_OS_NOFUNC); + } + + /* Got the counter, now save the counter in to ALARM structure. */ + this_alarm->cntr = cntr_ptr; + + /* Maximum allowed value and minimum cycles for this alarms this values are from */ + /* the counter to which this alarm is attached. */ + this_alarm->max_allowed_value = cntr_ptr->maxallowedvalue; + this_alarm->min_cyc = cntr_ptr->mincycle; + this_alarm->ticks_per_base = cntr_ptr->ticksperbase; + + this_alarm->name = name; + + /* Store the ACTION upon alarm expiration. */ + this_alarm->action = action; + + /* Store event in case of SETEVENT action. */ + this_alarm->events = events; + + /* Check for call back and store it. */ + if(callback != TX_NULL) + { + this_alarm->alarm_callback = callback; + } + + if (Startup != 0u) + { + this_alarm->auto_start = TX_TRUE; + } + + /* Save the TASK in to ALARM structure. */ + this_alarm->task = tcb_ptr; + + /* Everything is OK so far, now fill this alarm control block with some default parameters. */ + + /* Reset max cycles, current cycles and expiration count. */ + this_alarm->expiration_count = 0u; + this_alarm->cycle = 0u; + + /* Now it is time to check for AUTOSTART. */ + if (this_alarm->auto_start != 0u) + { + /* Check start. */ + if ((Alarmtime == 0u) || (Alarmtime > this_alarm->max_allowed_value)) + { + /* Invalid input parameter. */ + Application->osek_object_creation_error++; + + return (E_OS_VALUE); + } + + /* Check cycle. */ + if (Cycle != 0u) + { + if ((Cycle < this_alarm->min_cyc) || (Cycle > this_alarm->max_allowed_value)) + { + /* Invalid input parameter. */ + Application->osek_object_creation_error++; + + return (E_OS_VALUE); + } + } + + /* All input parameters are ok, store relative value and cycle. */ + this_alarm->cycle = Cycle; + + status = GetCounterValue(cntr_ptr, ¤t_value); + if (status != E_OK) + { + Application->osek_object_creation_error++; + + return (E_OS_VALUE); /* Some problem in getting counter's current value. */ + } + + this_alarm->expiration_count = current_value + Alarmtime; /* Load the counter with its expiration count. */ + + /* Now set the relative mode. */ + this_alarm->rel_abs_mode = RELATIVE_ALARM; + this_alarm->counter_rollback = TX_FALSE; + this_alarm->armed = TX_TRUE; + this_alarm->occupied = TX_TRUE; + + } /* End.. this_alarm->auto_start. */ + + return(alarm_id); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetAlarmBase PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Reads the alarm base characteristics. Returns info which is a */ +/* in which the information of the data type AlarmbaseType is */ +/* stored. */ +/* */ +/* INPUT */ +/* */ +/* AlarmID Reference to alarm */ +/* */ +/* OUTPUT */ +/* */ +/* Info user_defined parameters of the */ +/* counter associated with alarm. */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetAlarmBase(AlarmType AlarmID, AlarmBaseRefType info) +{ + +OSEK_ALARM *alarm_ptr; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetAlarmBase; + service_GetAlarmBase.AlarmID = AlarmID; + + /* Get the OSEK alarm. */ + alarm_ptr = (OSEK_ALARM *) AlarmID; + + /* Check valid ID. */ + if((alarm_ptr == 0u) || (alarm_ptr->osek_alarm_id != OSEK_ALARM_ID)) + { + exec_ErrorHook (E_OS_ID); + + /* Invalid AlarmID. */ + return (E_OS_ID); + } + + info->maxallowedvalue = alarm_ptr->max_allowed_value; + info->mincycle = alarm_ptr->min_cyc; + info->ticksperbase = alarm_ptr->ticks_per_base; + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* SetAbsAlarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Sets an alarm to an absolute cycle value. */ +/* */ +/* INPUT */ +/* */ +/* AlarmID Reference to alarm. */ +/* start Absolute value in ticks. */ +/* cycle Cycle value in case of cyclic alarm. */ +/* In case of single alarm it must be */ +/* zero. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* ERROR If error occurs while creating task */ +/* */ +/* CALLS */ +/* */ +/* osek_internal_error OSEK internal error */ +/* tx_time_get Get system time */ +/* tx_timer_create Create the timer is created */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType SetAbsAlarm(AlarmType AlarmID, TickType start, TickType cycle) +{ + TX_INTERRUPT_SAVE_AREA + OSEK_ALARM *osek_alarm; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_SetAbsAlarm; + service_SetAbsAlarm.AlarmID = AlarmID; + service_SetAbsAlarm.start = start; + service_SetAbsAlarm.cycle = cycle; + + /* Convert AlarmID to OSEK_ALARM. */ + osek_alarm = (OSEK_ALARM *) AlarmID; + + /* Check valid ID. */ + if((osek_alarm == 0u) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID)) + { + exec_ErrorHook (E_OS_ID); + + /* Invalid AlarmID. */ + return (E_OS_ID); + } + + TX_DISABLE + + /* Check already armed? */ + if (osek_alarm->armed == TX_TRUE) + { + TX_RESTORE + + exec_ErrorHook(E_OS_STATE); + + return (E_OS_STATE); + } + + /* Check start. */ + if ((start == 0u) || ( start > osek_alarm->max_allowed_value)) + { + TX_RESTORE + + /* Invalid input parameter. */ + exec_ErrorHook(E_OS_VALUE); + + return (E_OS_VALUE); + } + + + /* Check cycle. */ + if (cycle != 0u) + { + if ((cycle < osek_alarm->min_cyc) || ( cycle > osek_alarm->max_allowed_value)) + { + TX_RESTORE + + exec_ErrorHook(E_OS_VALUE); + + /* Invalid input parameter. */ + return (E_OS_VALUE); + } + } + + /* All input parameters are ok, store abs value and cycle. */ + osek_alarm->cycle = cycle; + osek_alarm->expiration_count = start; /* Load the counter with its expiration count. */ + + /* Now set the absolute mode. */ + osek_alarm->rel_abs_mode = ABSOLUTE_ALARM; + + /* Now, arm the alarm. */ + osek_alarm->armed = TX_TRUE; + osek_alarm->occupied = TX_TRUE; + osek_alarm->counter_rollback = TX_FALSE; + + TX_RESTORE + + /* Return OK. */ + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* SetRelAlarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Sets an alarm to a relative cycle value from the current time. */ +/* */ +/* INPUT */ +/* */ +/* AlarmID Reference to alarm. */ +/* increment Relative value in ticks */ +/* cycle Cycle value in case of cyclic alarm */ +/* In case of single alarm it must be */ +/* zero. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* ERROR If an error occurs */ +/* */ +/* CALLS */ +/* */ +/* osek_internal_error OSEK internal error */ +/* tx_timer_change Change the timer */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType SetRelAlarm(AlarmType AlarmID, TickType increment, TickType cycle) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_ALARM *osek_alarm; +OSEK_COUNTER *counter_ptr; +TickType current_value; +StatusType status; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_SetRelAlarm; + service_SetRelAlarm.AlarmID = AlarmID; + service_SetRelAlarm.increment = increment; + service_SetRelAlarm.cycle = cycle; + + /* Convert AlarmID to OSEK_ALARM. */ + osek_alarm = (OSEK_ALARM *)AlarmID; + + /* Check valid ID. */ + if((osek_alarm == TX_NULL) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID)) + { + exec_ErrorHook(E_OS_ID); + + /* Invalid AlarmID. */ + return (E_OS_ID); + } + + TX_DISABLE + + /* Check already armed? */ + if (osek_alarm->armed == TX_TRUE) + { + TX_RESTORE + + exec_ErrorHook(E_OS_STATE); + + return (E_OS_STATE); + } + + /* Check start. */ + if ((increment == 0u) || (increment > osek_alarm->max_allowed_value)) + { + TX_RESTORE + + exec_ErrorHook(E_OS_VALUE); + + /* Invalid input parameter. */ + return (E_OS_VALUE); + } + + /* Check cycle. */ + if (cycle != 0u) + { + if ((cycle < osek_alarm->min_cyc) || (cycle > osek_alarm->max_allowed_value)) + { + TX_RESTORE + + exec_ErrorHook(E_OS_VALUE); + + /* Invalid input parameter. */ + return (E_OS_VALUE); + } + } + + /* All input parameters are ok, store rel value and cycle. */ + osek_alarm->cycle = cycle; + counter_ptr = osek_alarm->cntr; + + status = GetCounterValue(counter_ptr, ¤t_value); + if (status != E_OK) + { + TX_RESTORE + return (E_OS_STATE); + } + + osek_alarm->expiration_count = current_value + increment; /* Load the counter with its expiration count. */ + + /* Now set the relative mode. */ + osek_alarm->rel_abs_mode = RELATIVE_ALARM; + osek_alarm->counter_rollback = TX_FALSE; + + /* Now, arm the alarm. */ + osek_alarm->armed = TX_TRUE; + osek_alarm->occupied = TX_TRUE; + + TX_RESTORE + + /* Return OK. */ + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* CancelAlarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Cancels the alarm: the alarm transition into the stop state. */ +/* */ +/* INPUT */ +/* */ +/* AlarmID Reference to alarm */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* ERROR If an error occurs */ +/* */ +/* CALLS */ +/* */ +/* tx_timer_deactivate Timer deactivate */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType CancelAlarm(AlarmType AlarmID) +{ +TX_INTERRUPT_SAVE_AREA + OSEK_ALARM *osek_alarm; + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_CancelAlarm; + service_CancelAlarm.AlarmID = AlarmID; + + /* Check valid ID and absolute ticks. */ + osek_alarm = (OSEK_ALARM *) AlarmID; + if((osek_alarm == TX_NULL) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID)) + { + exec_ErrorHook(E_OS_ID); + + /* Invalid AlarmID. */ + return (E_OS_ID); + } + + TX_DISABLE + + /* Is this alarm in use? */ + if ((osek_alarm->armed == TX_FALSE) || (osek_alarm->occupied == TX_FALSE)) + { + TX_RESTORE + + exec_ErrorHook(E_OS_NOFUNC); + + return (E_OS_NOFUNC); + } + + /* Alarm is in use so make it inactive. */ + osek_alarm->armed = TX_FALSE; + + TX_RESTORE + + /* Return OK. */ + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* GetAlarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Returns the no. of ticks before the alarm expires. */ +/* */ +/* INPUT */ +/* */ +/* ticks Pointer to the returned tick count */ +/* */ +/* OUTPUT */ +/* */ +/* N/A */ +/* */ +/* CALLS */ +/* */ +/* tx_timer_info_get Retrieves information about specified */ +/* timer. */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +StatusType GetAlarm(AlarmType AlarmID, TickRefType tick_ptr) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_ALARM *osek_alarm; +OSEK_COUNTER *counter_ptr; +TickType current_ticks; +StatusType status; + + + service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetAlarm; + service_GetAlarm.AlarmID = AlarmID; + + /* Check valid ID and absolute ticks. */ + osek_alarm = (OSEK_ALARM *) AlarmID; + if((osek_alarm == TX_NULL) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID)) + { + exec_ErrorHook (E_OS_ID); + + /* Invalid AlarmID. */ + return (E_OS_ID); + } + + TX_DISABLE + + if ((osek_alarm->armed == FALSE) || (osek_alarm->occupied == TX_FALSE)) + { + TX_RESTORE + + exec_ErrorHook(E_OS_NOFUNC); + + return (E_OS_NOFUNC); /* Alarm expired or not in use. */ + } + + counter_ptr = osek_alarm->cntr; + + status = GetCounterValue(counter_ptr, ¤t_ticks); + if (status != E_OK) + { + TX_RESTORE + + exec_ErrorHook (E_OS_ID); + return (E_OS_ID); + } + + if (osek_alarm->expiration_count < current_ticks) + { + /* Alarm's expiration count is less than current counter value means */ + /* alarm will expire after the counter rolls back and reach alarm's expiration count. */ + *tick_ptr = (osek_alarm->max_allowed_value - current_ticks + osek_alarm->expiration_count); + } + else + { + /* Alarm's expiration is more than counter's current value. */ + *tick_ptr = (osek_alarm->max_allowed_value - current_ticks); + } + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_initialize PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets up, configures and initializes all the */ +/* "behind-the-scenes" data structures, tables, memory regions, etc. */ +/* used by the OSEK at run-time. */ +/* */ +/* INPUT */ +/* */ +/* osek_memory OSEK pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_create Create system manager thread */ +/* tx_timer_create Create a system timer */ +/* osek_memory_init Initialize OSEK memory */ +/* tx_queue_create Create system manager queue */ +/* osek_tcb_init Initialize OSEK tasks */ +/* osek_resource_init Initialize OSEK resources */ +/* osek_alarm_init Initialize OSEK alarms */ +/* osek_counter_init Initialize OSEK counter */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +UCHAR *osek_initialize(void *osek_memory, APPLICATION_INFO_PTR application1) +{ + +UCHAR *pointer; +UINT status; +UINT i; +UINT j; + + /* Initialization started, set init state. */ + osek_init_state = OSEK_INIT; + + Application = application1; + Application->osek_object_creation_error = 0u; + /* Setup temporary memory pointer so we can start allocating + space for the OSEK data structures. The important thing to + remember here is that the system threads stack, the region0 + memory, and the queue are allocated sequentially from the + address specified by OSEK_memory. */ + + pointer = (UCHAR *)osek_memory; + + /* Create the work item message queue. */ + status = tx_queue_create(&osek_work_queue, "OSEK work queue", SYSMGR_QUEUE_MSG_LENGTH, + pointer, SYSMGR_QUEUE_DEPTH * SYSMGR_QUEUE_MSG_LENGTH); + if(status != TX_SUCCESS) + { + Application->osek_object_creation_error++; + } + + pointer = pointer + (SYSMGR_QUEUE_DEPTH * SYSMGR_QUEUE_MSG_LENGTH); + + /* Create the system manager thread. */ + status = tx_thread_create(&osek_system_manager, "OSEK System Manager", osek_system_manager_entry, + 0, pointer, OSEK_SYSTEM_STACK_SIZE, SYSMGR_PRIORITY, SYSMGR_THRESHOLD, + TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) + { + /* Error creating the system manager thread. */ + Application->osek_object_creation_error++; + } + + pointer = pointer + OSEK_SYSTEM_STACK_SIZE; + + /* Set up a memory "heap" or TX_REGION0_SIZE_IN_BYTES used internally + by the osek. */ + + status = osek_memory_init(pointer); + + if (status != TX_SUCCESS) + { + Application->osek_object_creation_error++; + } + + pointer = pointer + TX_REGION0_SIZE_IN_BYTES; + + + /* Create the system timer. */ + status = tx_timer_create( &osek_system_timer, "OSEK SYSTEM TIMER", osek_system_timer_entry, + 0,5,5,TX_NO_ACTIVATE); + + if (status != TX_SUCCESS) + { + Application->osek_object_creation_error++; + } + + /* Check whether any error occurred during system object creation. */ + if (Application->osek_object_creation_error != 0u) + { + osek_internal_error(THREADX_OBJECT_CREATION_ERROR); + } + + /* Initialize static pool of task control blocks. */ + osek_tcb_init(); + + /* Set up a pool of resource used internally by the OSEK layer. */ + osek_resource_init(); + + /* Set up a pool of counter used internally by the OSEK layer. */ + osek_counter_init(); + + /* Set up a pool of alarm used internally by the OSEK layer. */ + osek_alarm_init(); + + /* Clear all events. */ + global_events = 0u; + global_event_count = 0u; + + /* Clear task table. */ + + for (i = 0u; i < (OSEK_ISR1_PRIORITY + 1u); i++) + { + for (j = 0u; j < TASK_QUEUE_DEPTH; j++) + { + task_table[i][j] = 0u; + } + } + + /* Change OSEK mode. */ + osek_wrapper_operation_mode = INITSYSTEM_MODE; + + system_start = TX_TRUE; + + /* All done. */ + return (pointer); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_cleanup PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Cleans up after an OS shutdown. Used for testing. */ +/* */ +/* INPUT */ +/* */ +/* application1 Application pointer. */ +/* */ +/* OUTPUT */ +/* */ +/* TX_SUCCESS If successful. */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +UINT osek_cleanup(APPLICATION_INFO_PTR application1) +{ + +UINT status; +UINT i; +OSEK_TCB *p_tcb; + + /* Delete the system manager thread. */ + status = tx_thread_delete(&osek_system_manager); + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + /* Delete the system manager work queue. */ + status = tx_queue_delete(&osek_work_queue); + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + /* Delete the system timer. */ + status = tx_timer_delete(&osek_system_timer); + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + /* Delete the memory pool used for OSEK objects. */ + status = tx_byte_pool_delete(&osek_region0_byte_pool); + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + /* Terminate and delete all the threads. */ + for(i = 0u; i < OSEK_MAX_TASKS; i++) { + p_tcb = &osek_tcb_pool[i]; + if(p_tcb->task.tx_thread_entry != NULL) { + status = tx_thread_terminate(&p_tcb->task); + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + status = tx_thread_delete(&p_tcb->task); + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + p_tcb->task.tx_thread_entry = NULL; + } + } + + /* Clear the memory pool to prevent errors on restart. */ + memset(osek_tcb_pool, 0u, sizeof(osek_tcb_pool)); + + /* OSEK cleaned up, change init state to not initialized. */ + osek_init_state = OSEK_NOT_INIT; + + return TX_SUCCESS; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* process_ISR2 PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* */ +/* INPUT */ +/* */ +/* isrname ISR to process. */ +/* */ +/* CALLS */ +/* */ +/* ActivateISR Puts ISR in the queue area */ +/* */ +/* CALLED BY */ +/* */ +/* Wrapper Internal code (Not available for Application) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void process_ISR2(ISRType isrname) +{ + + if (disable_ISR2 != 0u) + { + /* ISR2 disabled, do nothing. */ + return; + } + + ActivateISR(isrname); + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ShutdownOS PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shuts down the OS. If ShutdownHook is defined it is */ +/* called. */ +/* */ +/* INPUT */ +/* */ +/* StatusType Returned error to the hook */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* ErrorHook If defined */ +/* */ +/* CALLED BY */ +/* */ +/* Application or OS */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void ShutdownOS(StatusType error) +{ +TX_INTERRUPT_SAVE_AREA +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT status; + + TX_DISABLE + + /* Disable ISRs. */ + disable_ISR2 = TX_TRUE; + + /* Check for any shutdown hook routine. */ + if (Application->shutdown_hook_handler != TX_NULL) + { + /* Change operation mode for to shutdownhook mode. */ + osek_wrapper_operation_mode = SHUTDOWNHOOK_MODE; + + (Application->shutdown_hook_handler)(error); + + } + + /* Change to default operations mode. */ + osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE; + + /* Now send message to system thread to shut down the system. */ + /* Build the request. */ + request[0] = SYSMGR_SHUTDOWN_OS; /* Request type. */ + request[1] = 0u; /* Dummy. */ + request[2] = 0u; /* Dummy. */ + request[3] = 0u; /* Dummy. */ + + /* Now send a message to the SysMgr supervisor thread. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_START_OS); + } + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* ActivateISR PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call activates a task which eventually executes an ISR code */ +/* This call puts the task in the ready queue. */ +/* The operating system ensures that the task code is being executed */ +/* from the first statement. Rescheduling after this call depends on */ +/* whether required resources for this ISR are free or not and no */ +/* other higher priority are running. */ +/* If E_OS_LIMIT is returned then activation is ignored as there is */ +/* one request of same ISR is already pending. */ +/* */ +/* ** NOTE** */ +/* This is not a standard OSEK API call. */ +/* */ +/* INPUT */ +/* */ +/* ISRId ISR Name */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_ID Invalid ISR id */ +/* E_OS_LIMIT One ISR already pending */ +/* */ +/* CALLS */ +/* */ +/* tx_queue_send Send message to Sys Manager */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK Wrapper Internal code (not available for Applications) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType ActivateISR(ISRType ISRID) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +UINT status; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; + + /* Get the OSEK TCB for the ISR to be activated. */ + tcb_ptr = (OSEK_TCB *)ISRID; + + /* Check for a valid ISR id. */ + if((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_ISR_ID)) + { + /* Return Error. */ + return (E_OS_ID); + } + + TX_DISABLE + + /* Check whether an ISR of same name is pending. */ + if(tcb_ptr->current_active >= tcb_ptr->max_active) + { + TX_RESTORE + /* Reached its max activation limit. */ + return (E_OS_LIMIT); + } + + /* Now send a message to the system manager to activate this ISR. */ + /* Build the request. */ + + request[0] = SYSMGR_ACTIVATE_TASK; /* Request type. */ + request[1] = (ULONG)tcb_ptr; /* ISR to Activate, */ + request[2] = last_run_task; /* Running task if any. */ + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, this call */ + /* will be preempted by SysMgr supervisor thread. */ + /* SysMgr will eventually call osek_do_task_activate(). */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_ACTIVATETASK); + } + + /* Return status. */ + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* TerminateISR PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This service terminates the calling ISR. */ +/* Only internal resources held by this ISR are released here. While */ +/* it is assumed that any external resources occupied by the ISR must */ +/* have been released before the call to TerminateISR. In case */ +/* a resource is still occupied while calling this service, then the */ +/* behaviour is undefined in STANDARD version of OSEK. In the EXTENDED */ +/* version of OSEK, this service returns an error, which can be */ +/* evaluated by the application. */ +/* If successful, this call will causes rescheduling, this also means */ +/* that upon success TerminateTask does not return to the call level. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None If success */ +/* Error Code. If error */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area Check if we are in task context */ +/* osek_thread2tcb Get TCB pointer for thread pointer */ +/* tx_queue_send Send message to sys manager thread */ +/* osek_internal_error In case of any internal error */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK Wrapper Internal code (Not available for Applications) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType TerminateISR(void) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; +UINT index; +UINT status; +ULONG area; +TX_THREAD *p_thread; + + + /* Check for task or ISR context */ + /* All ISR are treated as as a high priority tasks. */ + area = osek_task_independent_area(); + if(area != TX_TRUE) + { + /* Return error. */ + return (E_OS_CALLEVEL); + } + + /* Get OSEK TCB of this TASK/ISR */ + p_thread = tx_thread_identify(); + tcb_ptr = osek_thread2tcb(p_thread); + if (tcb_ptr == NULL) + { + return (E_OS_CALLEVEL); + } + + if ((tcb_ptr->osek_task_id != OSEK_ISR_ID)) + { + /* This call is allowed only from ISR. */ + return (E_OS_CALLEVEL); + } + + + /* Check operating mode. */ + if ((osek_wrapper_operation_mode != ISR1_MODE) && (osek_wrapper_operation_mode != ISR2_MODE)) + { + /* Hook toutines and alarm callbacks can't call this service. */ + /* This explicit check is required because all hook routines are + executed in task's context. */ + return (E_OS_CALLEVEL); + } + + TX_DISABLE + + /* Check if any resource is occupied. A task can not be terminated if it is holding any resource. */ + if(tcb_ptr->res_ocp != 0u) + { + TX_RESTORE + + /* Return. */ + return (E_OS_RESOURCE); + } + + /* Release any internal resources held. */ + if (tcb_ptr->internal_res != 0u) + { + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) + { + break; + } + + ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u; + tcb_ptr->internal_resource_occuplied_list[index] = 0u; + + } /* End of for loop. */ + } + + /* Now all set to terminate this task. */ + /* Send a message to the System Manager to terminate this task. */ + /* Build the request. */ + + request[0] = SYSMGR_TERMINATE_TASK; /* Request type. */ + request[1] = (ULONG)tcb_ptr; /* ID of the task to kill. */ + request[2] = 0u; + request[3] = 0u; + + /* Since the SysMgr supervisor thread has the highest priority, */ + /* this call will be preempted by SysMgr supervisor thread */ + /* SysMgr will eventually call osek_do_task_terminate and reschedule. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + TX_RESTORE + + /* This should always succeed. and Sys Manager terminates this task */ + /* This point will never be reached, as this thread itself will be */ + /* deleted by the system manager! */ + /* Still as a safety precaution enter system internal error loop. */ + + if (status != TX_SUCCESS) + { + osek_internal_error(SYS_MGR_SEND_TERMINATETASK); + } + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_system_manager_entry PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This is the System Manager thread for the OSEK. */ +/* All OSEK service calls that may cause rescheduling, ends up in */ +/* sending a message to a queue, and this highest priority thread */ +/* 'System Manager' reads this message and acts upon it. */ +/* It then calls the actual task scheduler which selects the next ready*/ +/* task from a queue of READY tasks. */ +/* After completing the request this routine returns back to read */ +/* next message which suspends this System Manager Thread and the task */ +/* selected by the task scheduler starts running. */ +/* */ +/* INPUT */ +/* */ +/* input Not used (Don't care) */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* tx_queue_receive Get message from ThreadX queue */ +/* osek_do_task_terminate Terminate the OSEK task. */ +/* osek_do_task_activate Activate the task */ +/* osek_internal_error OSEK internal error. */ +/* osek_do_delete_task Delete the OSEK task */ +/* pop_task_from_table Removes a task from the queue */ +/* tx_thread_suspend Suspends the calling task */ +/* add_task_to_table Adds a task to the TASK ready queue */ +/* start_osek_tasks Runs the next ready task from queue */ +/* */ +/* CALLED BY */ +/* */ +/* Wrapper Internal code (Not available to Application ) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_system_manager_entry(ULONG input) +{ +TX_THREAD *this_thread; +OSEK_TCB *tcb_ptr; +UINT status; +StatusType osek_status; +UINT i; +UINT j; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; + + + /* The input argument 'input' is not needed , hence not used */ + /* This statement is added just to avoid compiler warning. */ + (void)&input; + + /* Loop forever, waiting for any new message in the work queue. */ + for(;;) + { + /* Wait forever for the next work request. */ + status = tx_queue_receive(&osek_work_queue, &request, TX_WAIT_FOREVER); + + /* Make sure we didn't encounter any trouble. */ + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + continue; + } + + /* Look at the first entry in the message for the request type. */ + switch(request[0u]) + { + case SYSMGR_TERMINATE_TASK: + + /* ISR ends up in terminating itself so there is no separate switch case + for 'Return from ISR'. */ + /* As the task is terminated, remove it from the queue. */ + pop_task_from_table((OSEK_TCB *)request[1u]); + /* Now Terminate the task. */ + osek_status = osek_do_task_terminate((OSEK_TCB *)request[1u]); + if(osek_status != E_OK) { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + task_terminated = TX_TRUE; + + /* Enforce default operations mode. */ + osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE; + + break; + + + case SYSMGR_CHAIN_TASK: + + /* As calling task is terminated remove it from the queue. */ + pop_task_from_table ((OSEK_TCB *)request[1u]); + + /* Now terminate the calling task. */ + osek_status = osek_do_task_terminate((OSEK_TCB *)request[1u]); + if(osek_status != E_OK) { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + task_terminated = TX_TRUE; + + /* Now activate the task to be chained. */ + osek_status = osek_do_activate_task((OSEK_TCB *)request[2u]); + if(osek_status != E_OK) { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + break; + + case SYSMGR_START_OS: + + system_start = TX_TRUE; /* Indicates a fresh OS start. */ + disable_ISR2 = TX_FALSE; + suspend_ISR2 = TX_FALSE; + + /* OSEK started change init mode. */ + osek_init_state = OSEK_STARTED; + + break; + + case SYSMGR_ACTIVATE_TASK: + + /* First suspend the calling task but if an ISR is activating a task then */ + /* no need to suspend ISR Task as rescheduling (if required) is done only */ + /* after ISR completes. With ISR calling this service the request[2] is */ + /* always a NULL. */ + if (request[2] != 0u) + { + this_thread = (TX_THREAD *)request[2]; + status = tx_thread_suspend(this_thread); + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + } + + /* Now activate the requested task. */ + osek_status = osek_do_activate_task((OSEK_TCB *)request[1]); + if(osek_status != E_OK) { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + break; + + case SYSMGR_RELEASE_RESOURCE: + + tcb_ptr = (OSEK_TCB *)request[1]; + + /* First remove the task from its current queue position. */ + pop_task_from_table( tcb_ptr); + + /* Now change this task prio to a new one after release res. */ + tcb_ptr->cur_threshold = (UINT)request[2]; + + /* Now move this task to its new position. */ + push_task_to_table(tcb_ptr); + + /* Now suspend the calling task. */ + if (request[1u] != 0u) + { + this_thread = (TX_THREAD *)request[1]; + status = tx_thread_suspend(this_thread); + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + } + break; + + case SYSMGR_GET_RESOURCE: + + tcb_ptr = (OSEK_TCB *)request[1]; + + /* First remove the task from its current queue position. */ + pop_task_from_table ( tcb_ptr); + + /* Now change this task prio to a new one after release res. */ + tcb_ptr->cur_threshold = (UINT)request[2]; + + /* Now move this task to its new position. */ + push_task_to_table(tcb_ptr); + + /* Now suspend the calling task. */ + if (request[1u] != 0u) + { + this_thread = (TX_THREAD *)request[1u]; + status = tx_thread_suspend(this_thread); + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + } + + break; + + case SYSMGR_SCHEDULE: + + /* Get TCB for the calling task. */ + tcb_ptr = (OSEK_TCB *)request[1u]; + + /* Now release any internal resources held + and move the task to its original priority queue. */ + osek_status = release_internal_resource(tcb_ptr); + if(osek_status != E_OK) { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + /* Suspend the calling task. */ + if (request[1u] != 0u) + { + this_thread = (TX_THREAD *)request[1u]; + status = tx_thread_suspend(this_thread); + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + } + + break; + + case SYSMGR_SETEVENT: + + /* Add this out of wait state task to the ready queue as a newest member. */ + ((OSEK_TCB *)request[2u])->cur_threshold = ((OSEK_TCB *)request[2u])->org_prio; + + add_task_to_table((OSEK_TCB *)request[2u]); + + /* Suspend the calling task. */ + if (request[1u] != 0u) + { + this_thread = (TX_THREAD *)request[1u]; + status = tx_thread_suspend(this_thread); + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + } + + break; + + case SYSMGR_WAITEVENT: + + /* Remove from the queue the task that went into waiting state. */ + pop_task_from_table((OSEK_TCB *)request[2u]); + + /* Suspend it. */ + this_thread = (TX_THREAD *)request[1u]; + + status = tx_thread_suspend(this_thread); + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + break; + + case SYSMGR_SHUTDOWN_OS: + /* System shut down, clear task queue. */ + + for (i = 0u; i < (OSEK_ISR1_PRIORITY + 1u); i++) + { + for (j = 0u; j < TASK_QUEUE_DEPTH; j++) + { + if (task_table[i][j] != 0u) + { + status = tx_thread_terminate((TX_THREAD *)(task_table[i][j])); + if(status != TX_SUCCESS) { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + task_table [i][j] = 0u; + } + } + } + + return; + + break; + + case SYSMGR_ERRORHOOK: + this_thread = (TX_THREAD *)request[1u]; + + /* Although an ERRORHOOK won't call any API Service that may cause + rescheduling there could be an ISR logged while an Errorhook + was executing, so Errorhook call ends up in sending a message to + SYS manager to reschedule if necessary. */ + + /* Suspend the task causing Error condition. */ + status = tx_thread_suspend(this_thread); + if (status != TX_SUCCESS) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + break; + + default: + + /* We should NEVER get here... call a fatal error. */ + /* System internal error. */ + osek_internal_error(SYSMGR_FATAL_ERROR); + + break; + + } /* End of switch. */ + + /* Now call scheduler to check for any preemption and resume. */ + start_osek_tasks(); + + } /* wile (1) System Manager forever loop. */ + +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_memory_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to create a ThreadX byte pool that will */ +/* act as a "heap" for the OSEK dynamic internal objects */ +/* memory needs. */ +/* */ +/* INPUT */ +/* */ +/* region0_ptr OSEK memory pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* tx_byte_pool_create Create region0 byte pool */ +/* osek_internal_error Internal OSEK error */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static UINT osek_memory_init (void *region0_ptr) +{ +UINT retval; + + /* Create a ThreadX byte pool that will provide memory + needed by the OSEK. */ + retval = tx_byte_pool_create((TX_BYTE_POOL *)&osek_region0_byte_pool, + "OSEK REGION 0", + region0_ptr, + TX_REGION0_SIZE_IN_BYTES); + + return (retval); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_counter_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets up, configures and initializes all the */ +/* counter structures, which are defined at compile-time in order to */ +/* ensure that there is sufficient memory. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* osek_reset_counter Reset a Counters structure */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_counter_init(void) +{ + +ULONG index; + + /* Loop through array of semaphores and initialize each one. */ + for (index = 0u; index < OSEK_MAX_COUNTERS; index++) + { + osek_reset_counter(&(osek_counter_pool[index])); + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_reset_counter PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets a counter structure. */ +/* */ +/* INPUT */ +/* */ +/* counter_ptr Counter pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_reset_counter(OSEK_COUNTER *counter_ptr) +{ +TX_INTERRUPT_SAVE_AREA +UINT index; + + TX_DISABLE + + /* This counter is now no longer in use. */ + counter_ptr->cntr_in_use = TX_FALSE; + + /* Make any counter initial ticks to 0. */ + counter_ptr->counter_value = 0u; + + /* Make max. allowable ticks to 0. */ + counter_ptr->maxallowedvalue = 0u; + + /* Make no. of alarm repetition to 0. */ + counter_ptr->mincycle = 0u; + + /* Make ticks per base = 1. */ + counter_ptr->ticksperbase = 1u; + + /* Not attached yet to system timer. */ + counter_ptr->system_timer = TX_FALSE; + + /* Clear alarm list. */ + for (index = 0u; index < OSEK_MAX_ALARMS; index++) + { + counter_ptr->alarm_list[index] = 0u; + } + + counter_ptr->osek_counter_id = 0u; + + TX_RESTORE + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_alarm_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets up, configures and initializes all the */ +/* alarm structures, which we define at compile-time in order to */ +/* ensure that there is sufficient memory. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* osek_reset_alarm */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_alarm_init(void) +{ + +ULONG index; + + /* Loop through array of Semaphores and initialize each one. */ + for(index = 0u; index < OSEK_MAX_ALARMS; index++) + { + osek_reset_alarm(&(osek_alarm_pool[index])); + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_reset_alarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets an alarm structure to its default state. */ +/* */ +/* INPUT */ +/* */ +/* alarm_ptr Alarm pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_reset_alarm(OSEK_ALARM *alarm_ptr) +{ +TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + + /* First unarm the timer. */ + alarm_ptr->armed = TX_FALSE; + + /* This alarm is now no longer in use. */ + alarm_ptr->alarm_in_use = TX_FALSE; + alarm_ptr->occupied = TX_FALSE; + + /* Make Call back function to TX_NULL. */ + alarm_ptr->alarm_callback = TX_NULL; + + /* Make any counter reference to TX_NULL. */ + alarm_ptr->cntr = TX_NULL; + + /* Make any task and event reference to TX_NULL. */ + alarm_ptr->task = TX_NULL; + alarm_ptr->events = 0u; + alarm_ptr->action = 0u; + + /* Make its default value = 0. */ + alarm_ptr->max_allowed_value = 0u; + alarm_ptr->min_cyc = 0u; + alarm_ptr->cycle = 0u; + alarm_ptr->expiration_count = 0u; + alarm_ptr->auto_start = 0u; + + alarm_ptr->osek_alarm_id = 0u; + + TX_RESTORE + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_tcb_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets up, configures and initializes all the */ +/* task control blocks, which are defined at compile-time in order to */ +/* ensure that there is sufficient memory. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* osek_reset_tcb Reset a task control block */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_tcb_init(void) +{ + +ULONG index; + + /* Loop through array of TCBs and initialize each one. */ + for(index = 0u; index < OSEK_MAX_TASKS; index++) + { + osek_reset_tcb(&(osek_tcb_pool[index])); + } +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_resource_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets up, configures and initializes all the */ +/* resource structures, which are defined at compile-time in order to */ +/* ensure that there is sufficient memory. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* osek_reset_res Reset a semaphore structure */ +/* CreateResource Create the resource in OSEK */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_resource_init(void) +{ + +ULONG index; +OSEK_RESOURCE *res_ptr; + + + /* Loop through array of resources and initialize each one. */ + for(index = 0u; index < OSEK_MAX_RES; index++) + { + osek_reset_res(&(osek_res_pool[index])); + } + + RES_SCHEDULER = CreateResource("RES_SCHEDULER", STANDARD, 0u); + res_ptr = (OSEK_RESOURCE *)RES_SCHEDULER; + res_ptr->c_priority = OSEK_NON_SCHEDULE_PRIORITY; +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_reset_res PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets a resource a structure to its default state. */ +/* */ +/* INPUT */ +/* */ +/* res_ptr Resource pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_reset_res(OSEK_RESOURCE *res_ptr) +{ +TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + + /* Indicate this entry is not in use. */ + res_ptr->res_in_use = TX_FALSE; + + TX_RESTORE + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_do_task_terminate PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function terminates the specified task. */ +/* */ +/* INPUT */ +/* */ +/* tcb_ptr Task to activate */ +/* */ +/* OUTPUT */ +/* */ +/* None If successful */ +/* Error Code. If an error occurs */ +/* */ +/* CALLS */ +/* */ +/* osek_internal_error Internal error */ +/* tx_thread_terminate Terminate the thread */ +/* tx_thread_create Create the thread */ +/* osek_reset_tcb Free the task control block */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK only (internal) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType osek_do_task_terminate(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA +UINT retval; +TX_THREAD *thread_ptr; +UINT priority; + + + /* Converts OSEK into ThreadX. */ + priority = osek_remap_priority(tcb_ptr->org_prio); + + /* Make the current threshold as original priority. */ + tcb_ptr->cur_threshold = tcb_ptr->org_prio; + + /* Get the ThreadX thread pointer. */ + thread_ptr = (TX_THREAD *)tcb_ptr; + + /* Terminate the task's thread. */ + retval = tx_thread_terminate(thread_ptr); + + /* See if every thing is fine. */ + if (retval != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(THREADX_THREAD_TERMINATE_TERMINATETASK); + + /* Error will be returned whenever the ThreadX call fails. */ + return (E_OS_SYSTEM); + } + + TX_DISABLE + + /* Delete the ThreadX thread. */ + retval = tx_thread_delete(thread_ptr); + + /* Check if everything is fine. */ + if (retval != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(THREADX_THREAD_DELETE_TERMINATETASK); + + /* Error will be returned whenever the ThreadX call fails. */ + return (E_OS_SYSTEM); + } + + + if (tcb_ptr->current_active != 0u) + { + /* Decrement the activation count. */ + tcb_ptr->current_active--; + } + + /* Now check if there is any activations pending? */ + if (tcb_ptr->current_active == 0u) + { + /* If no activations pending then make this task SUSPENDED. */ + tcb_ptr->suspended = TX_TRUE; + } + + TX_RESTORE + + tcb_ptr->waiting = TX_FALSE; + + /* Create ThreadX thread. */ + retval = tx_thread_create(thread_ptr, + (char *)tcb_ptr->name, + osek_task_wrapper, + (ULONG)tcb_ptr, + tcb_ptr->pStackBase, + tcb_ptr->stack_size, + priority, + priority, + TX_NO_TIME_SLICE, + TX_DONT_START); + + /* See if ThreadX encountered an error. */ + if (retval != TX_SUCCESS) + { + /* Free the task TCB structure. */ + osek_reset_tcb(tcb_ptr); + + /* Internal error */ + osek_internal_error(THREADX_OBJECT_CREATION_ERROR); + + /* Error will be returned whenever the ThreadX call fails. */ + return (E_OS_SYSTEM); + } + + /* Everything is OK. */ + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_do_activate_task PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function activates the specified task. */ +/* */ +/* INPUT */ +/* */ +/* *tcb_ptr task to activate */ +/* */ +/* OUTPUT */ +/* */ +/* None If successful */ +/* Error Code. If an error occurs. */ +/* */ +/* CALLS */ +/* */ +/* osek_internal_error Internal error */ +/* tx_thread_resume Activate the thread */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK only (internal) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType osek_do_activate_task (OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA + /* Activate a task means making it READY and place into the TASK READY queue. */ + + TX_DISABLE + /* Increment current multiple activation count. */ + tcb_ptr->current_active++ ; + + /* Move this task from suspended state to ready state. */ + tcb_ptr->suspended = TX_FALSE; + + /* And add to the queue as a newest member. */ + add_task_to_table(tcb_ptr); + + TX_RESTORE; + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_thread2tcb PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns a ThreadX thread pointer to an OSEK task */ +/* pointer. */ +/* */ +/* INPUT */ +/* */ +/* thread Thread pointer */ +/* */ +/* OUTPUT */ +/* */ +/* *tcb TCB pointer */ +/* On error a null pointer is returned */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static OSEK_TCB *osek_thread2tcb(TX_THREAD *thread_ptr) +{ + +OSEK_TCB *tcb; + + /* Make sure we were called from a thread. */ + if (thread_ptr == TX_NULL) + { + /* Communicate error by means of a NULL pointer. */ + return ((OSEK_TCB *)0u); + } + + /* We can do this because the Thread information is intentionally + located as the first field in the structure. */ + tcb = (OSEK_TCB *)thread_ptr; + + /* All done. */ + return (tcb); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_task_independent_area PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines if the system is currently in a thread */ +/* context, i.e. not timer routine, not ISR, not idling, */ +/* not in initialization phase. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE If in task area */ +/* TX_FALSE If not in task area */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* osek internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static ULONG osek_task_independent_area(void) +{ + + if (osek_init_state != OSEK_STARTED) + { + + /* We are calling from initialization, return FALSE. */ + return (TX_FALSE); + } + else if ((_tx_thread_current_ptr == TX_NULL) || /* Not in a thread. */ + (_tx_thread_system_state != 0u) || /* In an ISR. */ + (_tx_thread_current_ptr == &_tx_timer_thread)) /* Timer routine. */ + + { + /* We are NOT in thread (task) context. */ + return (TX_FALSE); + } + else + { + /* We ARE in thread (task) context. */ + return (TX_TRUE); + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_create_task PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates an OSEK task under ThreadX. */ +/* */ +/* INPUT */ +/* */ +/* tcb_ptr Task control block pointer */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If successful */ +/* E_OS_SYSTEM If failure */ +/* */ +/* CALLS */ +/* */ +/* osek_tcb2thread Convert TCB to thread */ +/* tx_thread_create Create thread */ +/* osek_reset_tcb OSEK free task control block */ +/* add_task_to_table Add this task to queue */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK only (internal) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType osek_create_task(OSEK_TCB * tcb_ptr) +{ + +TX_INTERRUPT_SAVE_AREA + +UINT retval; +UINT priority; + +TX_DISABLE + + /* Converts OSEK priority into ThreadX. In ThreadX '0' is highest priority and '31' is the lowest + while in OSEK it is exactly the opposite. */ + + priority = osek_remap_priority(tcb_ptr->org_prio); + + /* Create a ThreadX thread, osek_task_wrapper is the entry function which is common for all thread + implementing an OSEK task to differentiate which task we supply 'task id' as an input for + thread entry function. */ + + retval = tx_thread_create ( &(tcb_ptr->task), + (char *)tcb_ptr->name, + osek_task_wrapper, + (ULONG)tcb_ptr, + tcb_ptr->pStackBase, + tcb_ptr->stack_size, + priority, + priority, + TX_NO_TIME_SLICE, + TX_DONT_START); /* All threads implementing an OSEK TASK are created in SUSPENDED state. */ + + /* Check for any error. */ + if (retval != TX_SUCCESS) + { + /* Free the task tcb structure. */ + osek_reset_tcb(tcb_ptr); + + /* Internal error. */ + osek_internal_error(THREADX_OBJECT_CREATION_ERROR); + + /* Error will be returned whenever the ThreadX call fails. */ + retval = E_OS_SYSTEM; + } + else + { + /* Got the thread, now check AUTO START Specified for this task. */ + /* If the task is not specified as 'AUTO RUN' then it is not in 'READY' State, + so won't be added to task queue at this stage. */ + + if (tcb_ptr->task_autostart == TRUE) + { + /* With AUTO START the task will attain READY state + the moment it is created, whether it will execute (RUN) will depend on Scheduler. */ + + tcb_ptr->suspended = TX_FALSE; + + /* As this task will be in Ready immediately after creation its + Current activation counter must be increment to 1 from 0. */ + tcb_ptr->current_active = 1u; + + /* Now add this task to Schedulers 'READY' task queue. */ + add_task_to_table(tcb_ptr); + } + + /* Everything is fine. */ + retval = E_OK; + } + + +TX_RESTORE + + return(retval); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_allocate_tcb PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to allocate memory for a task stack and an */ +/* OSEK Thread Control Block (TCB). */ +/* */ +/* INPUT */ +/* */ +/* stack_size Requested task stack size */ +/* tcb_ptr Pointer to tcb pointer */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE If successful. */ +/* TX_FALSE If an error occurs. */ +/* */ +/* CALLS */ +/* */ +/* osek_memory_allocate Allocate task's stack */ +/* osek_reset_tcb Free task control block */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static ULONG osek_allocate_tcb(ULONG stack_size, OSEK_TCB **tcb_ptr) +{ +OSEK_TCB * tcb; +ULONG index; +ULONG retval; + + /* Assume the worst. */ + tcb = (OSEK_TCB *)TX_NULL; + + /* This next search is optimized for simplicity, not speed. */ + tcb = osek_tcb_pool; + for (index = 0u; index < OSEK_MAX_TASKS; index++) + { + /* Is thisTCB in use? If not, we can use it. */ + if (tcb->tcb_in_use == TX_FALSE) + { + /* This TCB is now in use. */ + tcb->tcb_in_use = TX_TRUE; + + /* Stop searching. */ + break; + } + + tcb++; + } /* try next TCB. */ + + /* Did we search all TCBs and come up empty? */ + if (index == OSEK_MAX_TASKS) + { + /* No more TCBs available - user configuration error. */ + return(E_OS_SYS_STACK); + } + else + { + /* Found one. */ + *tcb_ptr = tcb; + } + + /* Reset stack pointer. */ + tcb->pStackBase = (CHAR *)TX_NULL; + + /* Allocate memory for the task stack. */ + retval = osek_memory_allocate(stack_size, + ((void **)&(tcb->pStackBase))); + + /* Make sure we got the memory for the task stack. */ + if ((retval == 0u) || (tcb->pStackBase == TX_NULL)) + { + /* Failed - at least try to return the OSEK TCB memory. */ + osek_reset_tcb(tcb); + + /* Indicate failure. */ + return (E_OS_SYS_STACK); + } + + /* Remember the size of the stack. */ + tcb->stack_size = stack_size; + + /* Return OSEK TCB to caller. */ + return (TX_TRUE); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_memory_allocate PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to obtain the specified amount of memory */ +/* from the OSEK heap. */ +/* */ +/* INPUT */ +/* */ +/* size Number of bytes to allocate */ +/* memory_ptr Pointer to the returned */ +/* memory */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE If successful */ +/* TX_FALSE If an error occurs */ +/* */ +/* CALLS */ +/* */ +/* tx_byte_allocate Allocate from the pool */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static UINT osek_memory_allocate(ULONG size, void **memory_ptr) +{ +ULONG size_align; +UINT retval; + + /* Initialize the pointer to NULL in case we fail. */ + *memory_ptr = (void *)TX_NULL; + + /* Force all alignments to long word boundaries to be safe. */ + size_align = size; + if ((size_align) != 0u) + { + /* Bump size up to next 4 byte boundary. */ + size_align = ((size_align + 0x03u) & ~0x03u); + } + + /* Attempt to allocate the desired memory from the OSEK heap. */ + /* Do not wait - if memory isn't available, flag an error. */ + retval = tx_byte_allocate((TX_BYTE_POOL *)&osek_region0_byte_pool, memory_ptr, + size_align, TX_NO_WAIT); + + /* Make sure the memory was obtained successfully. */ + if(retval != TX_SUCCESS) + { + /* Error obtaining memory. */ + return (TX_FALSE); + } + + /* Return to caller. */ + return (TX_TRUE); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_reset_tcb PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets a task TCB to its default state. */ +/* */ +/* INPUT */ +/* */ +/* tcb Task control block pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_reset_tcb(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA + +UINT index; + + /* Disable interrupt. */ + TX_DISABLE + + /* Indicate this TCB is not in use. */ + tcb_ptr->tcb_in_use = TX_FALSE; + + /* Make suspended and waiting to FALSE. */ + tcb_ptr->suspended = TX_TRUE; + tcb_ptr->waiting = TX_FALSE; + + /* Make this task as BASIC. */ + tcb_ptr->task_type = BASIC; + + /* No AUTOSTART */ + tcb_ptr->task_autostart = 0u; + + /* Erase TCB id */ + tcb_ptr->osek_task_id = 0u; + + /* Make original priority of the task to 0 (the lowest possible). */ + tcb_ptr->org_prio = 0u; + + /* Set the thread preemption threshold to default. */ + tcb_ptr->cur_threshold = THREADX_LOWEST_PRIORITY; + + /* Make the stack size to 0. */ + tcb_ptr->stack_size = 0u; + + /* No task to chain. */ + tcb_ptr->task_to_chain = 0u; + + /* Since now event is not attached Make it to TX_NULL. */ + tcb_ptr->events = 0u; + + /* Make task entry function to TX_NULL. */ + tcb_ptr->task_entry = TX_NULL; + + /* Make maximum activation to 0. */ + tcb_ptr->max_active = 0u; + + /* Make current activation to 0. */ + tcb_ptr->current_active = 0u; + + /* Clear lists for external Resource attached and Resource occupied. */ + for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + tcb_ptr->external_resource_list[index] = 0u; + tcb_ptr->external_resource_occuplied_list[index] = 0u; + } + + /* Clear lists for Internal Resource attached and resource occupied. */ + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + tcb_ptr->internal_resource_list[index] = 0u; + tcb_ptr->internal_resource_occuplied_list[index] = 0u; + } + + /* Since resource is not occupied make it to FALSE. */ + tcb_ptr->res_ocp = 0u; + + /* All done. */ + + /* Enable interrupt. */ + TX_RESTORE + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_get_resource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function finds if any resource is available in the pool. */ +/* */ +/* INPUT */ +/* */ +/* tcb Task control block pointer */ +/* */ +/* OUTPUT */ +/* */ +/* res_ptr Resource pointer OR null */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static ResourceType osek_get_resource(void) +{ +TX_INTERRUPT_SAVE_AREA +ULONG index; +OSEK_RESOURCE *res_ptr; + + TX_DISABLE + + /* Start out pessimistic - assume we won't find a match. */ + res_ptr = (OSEK_RESOURCE *)TX_NULL; + + /* Search the resource from resource pool. */ + res_ptr = &(osek_res_pool[0u]); + for (index = 0u; index < OSEK_MAX_RES; index++) + { + /* Make sure the resource is not already in use. */ + if (res_ptr->res_in_use == TX_FALSE) + { + /* This Resource is now in use. */ + res_ptr->res_in_use = TX_TRUE; + break; + } + + res_ptr++; + } + + TX_RESTORE + + /* Did we search all OSEK RESOURCES and come up empty? */ + if (index == OSEK_MAX_RES) + { + return ((ResourceType) TX_NULL); + } + + return ((ResourceType) res_ptr); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_get_alarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets an alarm if it is available. */ +/* */ +/* INPUT */ +/* */ +/* NONE */ +/* */ +/* OUTPUT */ +/* */ +/* ALARM_ID AlarmID if found */ +/* TX_FALSE If not available */ +/* */ +/* CALLS */ +/* */ +/* NONE */ +/* */ +/* CALLED BY */ +/* */ +/* API function. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static UINT osek_get_alarm(void) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_ALARM *this_alarm; +UINT index; + + TX_DISABLE + + /* Assume the worst. */ + this_alarm = (OSEK_ALARM *)TX_NULL; + + /* Search for a free alarm. */ + this_alarm = osek_alarm_pool; + + for (index = 0u; + index < OSEK_MAX_ALARMS; + index++) + { + /* Is this alarm in use? If not, we can use it. */ + if (this_alarm->alarm_in_use == TX_FALSE) + { + /* This alarm is now in use. */ + this_alarm->alarm_in_use = TX_TRUE; + + /* Stop searching. */ + break; + } + + this_alarm++; + } /* check next if this one is in use. */ + + TX_RESTORE + + /* Did we search alarms all and come up empty? */ + if (index == OSEK_MAX_ALARMS) + { + /* No more alarms available - user configuration error. */ + return ((AlarmType)0u); + } + + /* Found one. */ + + return ((AlarmType) this_alarm); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_get_events PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets events if it is available in the pool. */ +/* */ +/* INPUT */ +/* */ +/* NONE */ +/* */ +/* OUTPUT */ +/* */ +/* COUNTER_ID CounterID if found */ +/* TX_FALSE if not available */ +/* */ +/* CALLS */ +/* */ +/* NONE */ +/* */ +/* CALLED BY */ +/* */ +/* API function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static EventMaskType osek_get_event(void) +{ +TX_INTERRUPT_SAVE_AREA +EventMaskType event_mask; + + TX_DISABLE + + if (global_event_count >= OSEK_MAX_EVENTS) + { + TX_RESTORE + + /* Already alloted all possible events. */ + return ((EventMaskType)0u); + } + + /* Next event. */ + event_mask = 1u; + event_mask <<= global_event_count; + global_event_count++; + + TX_RESTORE + + return (event_mask); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_get_alarm PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets an alarm if it is available. */ +/* */ +/* INPUT */ +/* */ +/* NONE */ +/* */ +/* OUTPUT */ +/* */ +/* COUNTER_ID CounterID if found */ +/* TX_FALSE If not available */ +/* */ +/* CALLS */ +/* */ +/* NONE */ +/* */ +/* CALLED BY */ +/* */ +/* API function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static CounterType osek_get_counter(void) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_COUNTER *this_counter; +UINT index; + + TX_DISABLE + + /* Assume the worst. */ + this_counter = (OSEK_COUNTER *)TX_NULL; + + /* Search for a free counter. */ + this_counter = osek_counter_pool; + for ( index = 0u; + index < OSEK_MAX_COUNTERS; + index++) + { + /* Is this guy in use? If not, we can use it. */ + if (this_counter->cntr_in_use == TX_FALSE) + { + /* This counter is now in use. */ + this_counter->cntr_in_use = TX_TRUE; + /* Stop searching. */ + break; + } + + this_counter++; + } /* Try next counter. */ + + TX_RESTORE + + /* Did we search all OSEK COUNTERS and come up empty? */ + if (index >= OSEK_MAX_COUNTERS) + { + /* No more Counters available - user configuration error. */ + return ((CounterType) E_OS_SYS_STACK); + } + + /* Found one. */ + return ((CounterType)this_counter); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_system_timer_entry PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This wrapper acts as a system timer and maintains a system counter */ +/* It is up to the user to assign any one of the OSEK counter as */ +/* a system counter by defining it. */ +/* This counter will then be updated by this system timer. */ +/* */ +/* INPUT */ +/* */ +/* input Not used */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK system timer expiry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_system_timer_entry(ULONG input) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_COUNTER *this_counter; +UINT index; +UINT found; + + TX_DISABLE + + (void)&input; /* Prevent unused parameter warnings. */ + + found = TX_FALSE; + /* Search for a counter acting as a system counter. */ + this_counter = osek_counter_pool; + for ( index = 0u; + index < OSEK_MAX_COUNTERS; + index++) + { + /* Is this guy in a system counter. */ + if (this_counter->system_timer == TX_TRUE) + { + /* Got system counter. */ + found = TX_TRUE; + /* Stop searching. */ + break; + } + + this_counter++; + } /* Try next counter. */ + + /* Did we search all OSEK COUNTERS and come up empty? */ + if (found == TX_TRUE) + { + /* Got a system counter, update it. */ + IncrCounter((CounterType)this_counter); + } + + TX_RESTORE + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_remap_priority PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function converts a OSEK task priority into a ThreadX */ +/* priority. */ +/* */ +/* INPUT */ +/* */ +/* osek_priority Priority of task */ +/* */ +/* OUTPUT */ +/* */ +/* ThreadX priority Converted priority */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static UINT osek_remap_priority(UINT osek_priority) +{ + + /* Remap OSEK task priority to ThreadX thread priority. */ + /* In OSEK 0 = lowest priority and in ThreadX, 0 = highest priority, */ + /* Means ThreadX priority of a thread acting as a OSEK Task */ + /* would be ThreadX max priority - osek_priority. */ + + /* Return the ThreadX priority. */ + return (THREADX_MAX_PRIORITY - 1u - osek_priority); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_task_wrapper PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Every thread that is modeling a OSEK task uses this routine has */ +/* its entry point. This routine calls the OSEK task entry function. */ +/* */ +/* A task must end with either TerminateTask() or ChainTask(), if this */ +/* is not the way a task is ended, the control will come back to this */ +/* osek_task_wrapper and call osek_internal_error() with an error code */ +/* 'TASK_ENDING_WITHOUT_CHAIN_OR_TERMINATE'. */ +/* */ +/* INPUT */ +/* */ +/* tcb Task control block pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* task_entry OSEK task entry */ +/* osek_internal_error */ +/* */ +/* CALLED BY */ +/* */ +/* Internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_task_wrapper(ULONG tcb) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_TCB *tcb_ptr; +StatusType status; + + TX_DISABLE + + /* The input argument is really a pointer to the task's TCB. */ + tcb_ptr = (OSEK_TCB *)tcb; + /* Check whether it is a Task or an ISR. */ + if (tcb_ptr->osek_task_id == OSEK_TASK_ID) + { + osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE; + + /* last_run_task now holds this new task being run. */ + last_run_task = (ULONG)((TX_THREAD*)tcb_ptr); + + /* Check this task's scheduling policy. */ + if (tcb_ptr->policy == NON) + { + pop_task_from_table(tcb_ptr); /* This routine remove task from table based on its cur_threshold. */ + + /* Store the new preemption threshold. */ + tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY; + + /* Place this task to its proper priority queue based on Scheduling policy. */ + push_task_to_table(tcb_ptr); /* This routine pushes a task at the front of a queue based on its cur_threshold. */ + } + + } + else + { + if (tcb_ptr->task_type == CATEGORY1) + { + osek_wrapper_operation_mode = ISR1_MODE; + } + else + { + osek_wrapper_operation_mode = ISR2_MODE; + } + } + + TX_RESTORE + + /* Invoke the OSEK task entry point with appropriate arguments. */ + (tcb_ptr->task_entry)(); + + /* In case of a task we shouldn't be here- because tasks are always ended with either + a TerminateTask() or ChainTask() but ISR will return here. */ + /* If it is a TASK then seems to be ended without any ChainTask or TerminateTask call + anyway, as the task is ended it is better to Terminate it so that next available ready + task can be run. */ + + + /* Terminate the task. */ + if (tcb_ptr->osek_task_id == OSEK_TASK_ID) + { + /* Change to default operations mode. */ + osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE; + + status = TerminateTask(); + if(status != E_OK) { + osek_internal_error(SYS_MGR_SEND_TERMINATETASK); + } + } + else + { + status = TerminateISR(); + if(status != E_OK) { + osek_internal_error(SYS_MGR_SEND_TERMINATETASK); + } + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* osek_internal_error PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is invoked whenever an error is encountered */ +/* in the OSEK code. This is an endless loop. */ +/* Source of the error can be traced by the error code. */ +/* */ +/* INPUT */ +/* */ +/* error_code Error code */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void osek_internal_error(ULONG error_code) +{ + /* This just an end less loop, to trap error. */ + for(;;) + { + ; /* Empty loop. */ + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* exec_ErrorHook PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function invokes ErroHook routine whenever an error is */ +/* encountered, provided ErroHook is defined. */ +/* Hook routines are called by the operating system, in a special */ +/* context have higher prior than all tasks, and not interrupted by */ +/* category 2 interrupt routines. */ +/* These functions are implemented by the user with user defined */ +/* functionality. Usually hook routines are allowed to use only a */ +/* subset of API functions. Whether to execute these routine or not is */ +/* user configurable via OIL. */ +/* */ +/* INPUT */ +/* */ +/* error_code Passed to ErrorHook */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* Application->error_handler That is ErrorHook (if defined) */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void exec_ErrorHook (StatusType error) +{ + +TX_THREAD *thread_ptr; +UINT save_op_mode; +UINT status; +ULONG request[SYSMGR_QUEUE_MSG_LENGTH]; + + /* Check for any startup hook routine. */ + if (Application->error_hook_handler != TX_NULL) + { + /* But check whether already in ErrorHook routine? There must not be nested ErrorHook calls. */ + if (osek_wrapper_operation_mode == ERRORHOOK_MODE) + { + /* Already in ErroHook. */ + return; + } + + /* Save old operation mode. */ + save_op_mode = osek_wrapper_operation_mode; + + /* Change to ErroHOOK mode. */ + osek_wrapper_operation_mode = ERRORHOOK_MODE; + + /* Now execute user defined ErroHook routine. */ + (Application->error_hook_handler)(error); + + /* Get the pointer to thread. */ + thread_ptr = tx_thread_identify(); + + /* Restore original operation mode. */ + osek_wrapper_operation_mode = save_op_mode; + + /* If this ErrorHook is called by a task then check for any ISR came while executing this ErrorHook. */ + if (osek_wrapper_operation_mode == NORMAL_EXECUTION_MODE) + { + /* Now send a message to the SysMgr supervisor thread to execute the Error Hook. */ + /* Build the request. */ + request[0] = SYSMGR_ERRORHOOK; /* Request type. */ + request[1] = (ULONG)thread_ptr; /* ptr of calling thread. */ + request[2] = 0u; /* input to Error Hook. */ + request[3] = 0u; + + /* Since the system manager supervisor thread is with the highest priority, */ + /* this routine will be preempted by SysMgr supervisor thread when */ + /* queue read is successful. */ + + status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT); + + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + /* System internal error. */ + osek_internal_error(SYS_MGR_SEND_CHAINTASK); + + /* Return. */ + return; + } + } /* End if ( osek_wrapper_operation_mode ==. */ + + } /* end if (Application->error_handler). */ + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* exec_PreTaskHook PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function invokes the PreTaskHook routine whenever a task */ +/* starts provided PreTaskHook is defined. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void exec_PreTaskHook(void) +{ + +UINT save_op_mode; + + if (Application->pretask_hook_handler != TX_NULL) + { + /* Set up the mode. */ + save_op_mode = osek_wrapper_operation_mode; + osek_wrapper_operation_mode = PRETASKHOOK_MODE; + + /* Call the Pretask hook. */ + (Application->pretask_hook_handler)(); + + /* Restore mode. */ + osek_wrapper_operation_mode = save_op_mode; + + } /* end if (Application->PretaskHook_handler). */ + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* exec_PostTaskHook PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function invokes PostTaskHook routine whenever a task */ +/* terminates provided PostTaskHook is defined. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void exec_PostTaskHook(void) +{ + +UINT sav_op_mode; + + if (Application->posttask_hook_handler != TX_NULL) + { + /* Set up the mode. */ + sav_op_mode = osek_wrapper_operation_mode; + osek_wrapper_operation_mode = POSTTASKHOOK_MODE; + + /* Call the Posttask hook. */ + (Application->posttask_hook_handler)(); + + /* Restore mode. */ + osek_wrapper_operation_mode = sav_op_mode; + + } /* end if (Application->PosttaskHook_handler). */ + + return; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* add_task_to_table PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function adds a ready task in the task queue. */ +/* */ +/* INPUT */ +/* */ +/* *tcb_ptr Pointer to the task to be added to the queue */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void add_task_to_table(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA +UINT priority; +UINT i; + + TX_DISABLE + + /* Get the priority of this task. */ + priority = tcb_ptr-> org_prio; + + for (i = 0u; i < TASK_QUEUE_DEPTH; i++) + { + /* Add this task to the a queue assigned for this task's priority level. */ + /* Find next free entry in the queue. */ + /* Oldest activated task is at the front of the queue, so this new entry. */ + /* will go at the end of the queue. */ + + if (task_table[priority][i] == 0u) + { + task_table[priority][i] = (TaskType)tcb_ptr; + break; + } + } + + if (i >= TASK_QUEUE_DEPTH) + { + osek_internal_error(SYSMGR_FATAL_ERROR); + } + + TX_RESTORE + +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* push_task_to_table PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function pushes a task at the front of the task queue. */ +/* */ +/* INPUT */ +/* */ +/* *tcb_ptr Pointer to the task to be added to the queue */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* OSEK internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void push_task_to_table(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA +UINT priority; +UINT i; +UINT k; + + TX_DISABLE + + priority = tcb_ptr->cur_threshold; + + i = (TASK_QUEUE_DEPTH - 2u); + + while (i != 0u) + { + /* Add this task to the queue (of for priority level supplied). */ + /* Place the entry at the front of the queue and push back all entries by one */ + k = i + 1u; + task_table[priority][k] = task_table[priority][i]; + i--; + } + + task_table[priority][1u] = task_table[priority][0u]; + + /* Now push the calling task's id at the front of the queue. */ + task_table[priority][0u] = (ULONG)tcb_ptr; + + TX_RESTORE +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* start_osek_tasks PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function schedules the first task upon StatOS */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* Error Code */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_resume */ +/* */ +/* CALLED BY */ +/* */ +/* osek_system_manager_entry */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void start_osek_tasks(void) +{ +TX_INTERRUPT_SAVE_AREA +TX_THREAD *task_thread; +UINT i; +UINT j; +UINT found; + + TX_DISABLE + + /* Start with the highest priority */ + j = OSEK_ISR1_PRIORITY; + found = FALSE; + + while (found == FALSE) + { + for (i = 0u; i < TASK_QUEUE_DEPTH; i++) + { + /* Search for any ready but not waiting task within this priority level. */ + if (( task_table[j][i] != 0u) && (((OSEK_TCB*)task_table[j][i] )->waiting == TX_FALSE)) + { + /* Found it but check whether this task can be run, + This task must have higher priority than current task's ceiling priority + This task must have all needed Internal/External resources. */ + task_thread = &((OSEK_TCB*)task_table[j][i])->task; + found = check_task_to_run((OSEK_TCB*)task_table[j][i]); + if (found == TRUE) + { + break; + } + } + + } + + /* No ready task found for this priority level, check for next lower priority level + but are we at the lowest priority level? */ + if ((j == 0u) || (found == TRUE)) + { + break; + } + + j--; + + } /* End while. */ + + /* Reached here means either a ready Task is found or no task is READY. */ + /* if found = 1, task is found. */ + + if (found == FALSE) + { + last_run_task = INVALID_TASK; + } + else + { + if (((OSEK_TCB*)task_thread)->osek_task_id == OSEK_ISR_ID) + { + /* If it is an ISR , set the op mode and no need to: + call pre and post task hooks as well as change last_run_task data. */ + osek_wrapper_operation_mode = ISR2_MODE; + } + else + { + osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE; + /* Check whether it is a fresh OS start, for fresh start no need to run pre & post task hooks. */ + if (system_start == 0u) + { + /* If no preemption takes place , then no need to execute pre and post task hooks. */ + if ((last_run_task != (ULONG)task_thread )|| (task_terminated == TX_TRUE)) + { + exec_PostTaskHook(); + + /* Update last run task data to reflect next task to run. */ + last_run_task = (ULONG)task_thread; + + exec_PreTaskHook(); + } + + } + + last_run_task = (ULONG)task_thread; + } /* End else. */ + + tx_thread_resume(task_thread); + + system_start = TX_FALSE; + + task_terminated = TX_FALSE; + + } /* end of else part of if (!found). */ + + TX_RESTORE +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* check_task_to_run PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function schedules the first task upon StatOS */ +/* This is called by system manager thread when StartOS is called. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* Error Code */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_resume */ +/* */ +/* CALLED BY */ +/* */ +/* osek_system_manager_entry */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static UINT check_task_to_run (OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA + UINT status; + + TX_DISABLE + + if (tcb_ptr->osek_task_id != OSEK_TASK_ID) + { + /* if selection is an ISR, + it can't be run if ISRs are suspended or any HOOK mode is ON. */ + if ((suspend_ISR2 == TX_TRUE) || + (osek_wrapper_operation_mode == ERRORHOOK_MODE) || + (osek_wrapper_operation_mode == PRETASKHOOK_MODE) || + (osek_wrapper_operation_mode == POSTTASKHOOK_MODE) || + (osek_wrapper_operation_mode == STARTUPHOOK_MODE) || + (osek_wrapper_operation_mode == SHUTDOWNHOOK_MODE) || + (osek_wrapper_operation_mode == ALARM_CALLBACK_MODE)) + { + TX_RESTORE + + return (FALSE); + } + } + + if (tcb_ptr->internal_res != 0u) + { + status = get_internal_resource(tcb_ptr); + + if (status != E_OK) + { + TX_RESTORE + + return (FALSE); + } + } + + status = check_external_resource(tcb_ptr); + if (status != E_OK) + { + TX_RESTORE + + return (FALSE); + } + + /* Now check for NON scheduling policy. */ + if (tcb_ptr->policy == NON) + { + /* First remove task from its current queue position. */ + pop_task_from_table(tcb_ptr); + + tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY; + + push_task_to_table(tcb_ptr); + } + + TX_RESTORE + + return (TRUE); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pop_task_from_table PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* Removes a task from the table of active tasks. */ +/* */ +/* INPUT */ +/* */ +/* id Id of the resource. */ +/* */ +/* OUTPUT */ +/* */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void pop_task_from_table(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA +UINT priority; +UINT i; +UINT j; +UINT k; + + TX_DISABLE + + /* Get the priority of this task. */ + priority = tcb_ptr-> cur_threshold; + j = (TASK_QUEUE_DEPTH - 2u); + for (i = 0u; i < j; i++) + { + /* Move N+1 th element to Nth location. */ + /* Oldest task is at the bottom of the queue. */ + k = i + 1u; + task_table[priority][i] = task_table[priority][k]; + } + + /* Make the top most element in the queue NULL as the oldest task is removed from the bottom. */ + j = (TASK_QUEUE_DEPTH) - 1u; + task_table[priority][j] = 0u; + + TX_RESTORE +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* check_linked_resources PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Check if resources are linked */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static void check_linked_resources(void) +{ +TX_INTERRUPT_SAVE_AREA +ULONG index; +OSEK_RESOURCE *res_ptr; +OSEK_RESOURCE *linked_res_ptr; + + TX_DISABLE + + /* Search the Resource from resource pool. */ + for (index = 0u; index < OSEK_MAX_RES; index++) + { + + res_ptr = &(osek_res_pool[index]); + if ((res_ptr->res_in_use == TX_TRUE) && (res_ptr->type == LINKED)) + { + /* Get the res linked to this resource. */ + linked_res_ptr = (OSEK_RESOURCE *)(res_ptr->resolved_res); + + /* Make this resources's ceiling priority equal to the ceiling priority of linked resource. */ + if ( res_ptr->c_priority < linked_res_ptr->c_priority) + { + res_ptr->c_priority = linked_res_ptr->c_priority; + } + } + } + + TX_RESTORE +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* get_internal_resource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call serves to enter critical sections in the code that are */ +/* assigned to the resource referenced by . A critical section */ +/* must always be left using ReleaseResource. Nested resource */ +/* occupation is only allowed if the inner critical sections are */ +/* completely executed within the surrounding critical section. */ +/* Nested occupation of one and the same resource is also forbidden. */ +/* Corresponding calls to GetResource and ReleaseResource should appear */ +/* within the same function on the same function level. */ +/* */ +/* INPUT */ +/* */ +/* id Id of the resource. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success */ +/* E_OS_CALLEVEL Called from ISR */ +/* E_OS_ACCESS Attempt to get a resource which is */ +/* already occupied by any task or ISR, */ +/* or the statically assigned priority of */ +/* the calling task or interrupt routine */ +/* is higher than the calculated ceiling */ +/* priority, */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area See if called from task independent */ +/* area */ +/* tx_thread_identify Identify the current thread */ +/* osek_internal_error Osek internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType get_internal_resource(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_RESOURCE *osek_res; +UINT res_prio; +UINT index; + + +TX_DISABLE + + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + + if (tcb_ptr->internal_resource_list[index] == 0u) + { + break; /* No Internal Resource in the list. */ + } + + /* Get internal RES's control block. */ + osek_res = (OSEK_RESOURCE *)tcb_ptr->internal_resource_list[index]; + + /* Now check whether this resource is already occupied by other task. */ + if (osek_res->taskid != 0u) + { + /* Some entry is there, is it occupied by any other task? */ + if (osek_res->taskid != (TaskType)tcb_ptr) + { + TX_RESTORE + + return (E_OS_ACCESS); + } + } + + /* Take this resource. */ + tcb_ptr->internal_resource_occuplied_list[index] = tcb_ptr->internal_resource_list[index]; + + /* Save this task's id in the res's control block to indicate that this task is the owner of this res. */ + osek_res->taskid = (TaskType)(tcb_ptr); + + } /* End for (index.. */ + + /* Now all internal resources are taken, this needs to change task's preemption + to highest ceiling priority of internal resource occupied. */ + + /* First remove task from its current queue position. */ + pop_task_from_table(tcb_ptr); + + /* Now need to change this task's preemption threshold to resource's ceiling priority. */ + /* Assume task's original priority is the highest. */ + if ((tcb_ptr->resource_scheduler != 0u) || (tcb_ptr->policy == NON)) + { + tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY; + } + + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) { + break; + } + + res_prio = ((OSEK_RESOURCE *) (tcb_ptr->internal_resource_occuplied_list[index]))->c_priority; + if (tcb_ptr->cur_threshold < res_prio ) + { + tcb_ptr->cur_threshold = res_prio; + } + } + /* Now the task's current threshold reflect the highest of ceiling priority of the remaining + resources held by this task, move this task to the front of that priority queue. */ + push_task_to_table(tcb_ptr); + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* release_internal_resource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call releases any internal resources held by the calling task. */ +/* It also changes the calling task's priority to reflect either its */ +/* original priority, NON SCHEDULE priority or maximum ceiling */ +/* priority of any any external resources held by this task. */ +/* At the end this task is then moved to a queue appropriate to its new */ +/* ceiling priority. */ +/* */ +/* INPUT */ +/* */ +/* id Task id. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK Always */ +/* */ +/* CALLS */ +/* */ +/* pop_task_from_table Removes a task from its current queue */ +/* push_task_to_table Pushes a task at the front of a queue */ +/* */ +/* CALLED BY */ +/* */ +/* Wrapper internal code (not available for application) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType release_internal_resource(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA +UINT index; + + TX_DISABLE + + /* Release any internal resources held? */ + for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++) + { + + if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) + { + break; + } + + ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u; + + tcb_ptr->internal_resource_occuplied_list[index] = 0u; + } + + /* First remove task from its current queue position. */ + pop_task_from_table(tcb_ptr); + + /* As all internal resources are released and no external resources are held + this task must be reverted to its original design time priority. */ + + tcb_ptr->cur_threshold = tcb_ptr->org_prio; + + /* Now move this task to the front of that priority queue. */ + push_task_to_table(tcb_ptr); + + TX_RESTORE + + return (E_OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* check_external_resource PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This call serves to enter critical sections in the code that are */ +/* assigned to the resource referenced by . A critical section */ +/* must always be left using releaseResource. Nested resource */ +/* occupation is only allowed if the inner critical sections are */ +/* completely executed within the surrounding critical section. */ +/* Nested occupation of one and the same resource is also forbidden. */ +/* Corresponding calls to GetResource and ReleaseResource should appear */ +/* within the same function on the same function level. */ +/* */ +/* INPUT */ +/* */ +/* id Id of the resource. */ +/* */ +/* OUTPUT */ +/* */ +/* E_OK If success */ +/* E_OS_CALLEVEL Called from ISR */ +/* E_OS_ACCESS Attempt to get a resource which is */ +/* already occupied by any task or ISR, */ +/* or the statically assigned priority of */ +/* the calling task or interrupt routine */ +/* is higher than the calculated ceiling */ +/* priority. */ +/* */ +/* CALLS */ +/* */ +/* osek_task_independent_area See if called from task independent */ +/* area */ +/* tx_thread_identify Identify the current thread */ +/* osek_internal_error OSEK internal error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static StatusType check_external_resource(OSEK_TCB *tcb_ptr) +{ +TX_INTERRUPT_SAVE_AREA +OSEK_RESOURCE *osek_res; +OSEK_RESOURCE *osek_res1; +StatusType status; +UINT index; + + /* Check that all assigned external resources for this task are free. */ + /* Here only availability of resources is checked, no resource will be taken. */ + + TX_DISABLE + + status = E_OK; /* Assuming that everything is OK. */ + for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++) + { + + if (tcb_ptr->external_resource_list[index] == 0u) + { + break; /* No External Resource left in the list. */ + } + + /* Get External RES's control block. */ + osek_res = (OSEK_RESOURCE *)tcb_ptr->external_resource_list[index]; + + /* Now check whether this resource is already occupied by other task. */ + if (osek_res->taskid != 0u) + { + if (osek_res->taskid != (TaskType)tcb_ptr) + { + status = E_OS_ACCESS; /* Already occupied by any other task. */ + break; + } + + } + + if (osek_res->type == LINKED) + { + + osek_res1 = (OSEK_RESOURCE *)(osek_res->resolved_res); + + if (osek_res1->taskid != 0u) + { + if (osek_res1->taskid != (TaskType)tcb_ptr) + { + status = E_OS_ACCESS; /* Already occupied by any other task. */ + break; + } + } + + } /* End (osek_res->type == LINKED) */ + + + } /* End for. */ + + TX_RESTORE + + return (status); +} + + +/*************************** END OF FILE ************************************/ diff --git a/utility/rtos_compatibility_layers/posix/errno.h b/utility/rtos_compatibility_layers/posix/errno.h new file mode 100644 index 00000000..dcfe9cff --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/errno.h @@ -0,0 +1,220 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** POSIX Compliancy Wrapper (POSIX) */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKP DEFINITIONS RELEASE */ +/* */ +/* errno.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc.needed to */ +/* implement the Evacuation Kit for POSIX Users (POSIX) */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef _ERRNO_H +#define _ERRNO_H + + + +#ifndef TX_POSIX_SOURCE +#define errno posix_errno +#endif + +/* the POSIX standard does not impose particular values for errno.h */ +/* error codes between 200 and 1000 are not used by the Threadx wrapper */ +/* but supplied for completeness. */ + + + + +#define E2BIG 200 + +#define EACCES 13 + +#define EADDRINUSE 201 + +#define EADDRNOTAVAIL 202 + +#define EAFNOSUPPORT 203 + +#define EAGAIN 11 + +#define EALREADY 204 + +#define EBADF 9 + +#define EBADMSG 205 + +#define EBUSY 9999 + +#define ECANCELED 206 + +#define ECHILD 207 + +#define ECONNABORTED 208 + +#define ECONNREFUSED 209 + +#define ECONNRESET 210 + +#define EDEADLK 3333 + +#define EDESTADDRREQ 211 + +#define EDOM 212 + +#define EDQUOT 213 + +#define EEXIST 17 + +#define EFAULT 214 + +#define EFBIG 215 + +#define EHOSTUNREACH 216 + +#define EIDRM 217 + +#define EILSEQ 218 + +#define EINPROGRESS 219 + +#define EINTR 4 + +#define EINVAL 22 + +#define EIO 220 + +#define EISCONN 221 + +#define EISDIR 222 + +#define ELOOP 223 + +#define EMFILE 224 + +#define EMLINK 225 + +#define EMSGSIZE 36 + +#define EMULTIHOP 226 + +#define ENAMETOOLONG 26 + +#define ENETDOWN 227 + +#define ENETRESET 228 + +#define ENETUNREACH 229 + +#define ENFILE 230 + +#define ENOBUFS 231 + +#define ENODATA 232 + +#define ENODEV 233 + +#define ENOENT 2 + +#define ENOEXEC 234 + +#define ENOLCK 235 + +#define ENOLINK 236 + +#define ENOMEM 4444 + +#define ENOMSG 237 + +#define ENOPROTOOPT 238 + +#define ENOSPC 28 + +#define ENOSR 239 + +#define ENOSTR 240 + +#define ENOSYS 71 + +#define ENOTCONN 241 + +#define ENOTDIR 242 + +#define ENOTEMPTY 243 + +#define ENOTSOCK 244 + +#define ENOTSUP 126 + +#define ENOTTY 245 + +#define ENXIO 246 + +#define EOPNOTSUPP 247 + +#define EOVERFLOW 248 + +#define EPERM 2222 + +#define EPIPE 249 + +#define EPROTO 250 + +#define EPROTONOSUPPORT 251 + +#define EPROTOTYPE 252 + +#define ERANGE 253 + +#define EROFS 254 + +#define ESPIPE 255 + +#define ESRCH 3 + +#define ESTALE 256 + +#define ETIME 257 + +#define ETIMEDOUT 5555 + +#define ETXTBSY 258 + +#define EWOULDBLOCK 259 + +#define EXDEV 260 + +#endif diff --git a/utility/rtos_compatibility_layers/posix/fcntl.h b/utility/rtos_compatibility_layers/posix/fcntl.h new file mode 100644 index 00000000..90c59021 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/fcntl.h @@ -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 */ +/** */ +/** POSIX Compliancy Wrapper (POSIX) */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKP DEFINITIONS RELEASE */ +/* */ +/* fcntl.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc.needed to */ +/* implement the Evacuation Kit for POSIX Users (POSIX) */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef _FCNTL_H +#define _FCNTL_H + +#define O_ACCMODE 0x0003 +#define O_RDONLY 0x0000 +#define O_WRONLY 0x0001 +#define O_RDWR 0x0002 +#define O_APPEND 0x0008 +#define O_SYNC 0x0010 +#define O_NONBLOCK 0x0080 +#define O_CREAT 0x0100 +#define O_TRUNC 0x0200 +#define O_EXCL 0x0400 +#define O_NOCTTY 0x0800 +#define FASYNC 0x1000 +#define O_LARGEFILE 0x2000 +#define O_DIRECT 0x8000 +#define O_DIRECTORY 0x10000 +#define O_NOFOLLOW 0x20000 + +#define O_NDELAY O_NONBLOCK + +#define F_DUPFD 0 +#define F_GETFD 1 +#define F_SETFD 2 +#define F_GETFL 3 +#define F_SETFL 4 +#define F_GETLK 14 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 24 +#define F_GETOWN 23 +#define F_SETSIG 10 +#define F_GETSIG 11 + +#define FD_CLOEXEC 1 + +# define POSIX_FADV_NORMAL 0 +# define POSIX_FADV_RANDOM 1 +# define POSIX_FADV_SEQUENTIAL 2 +# define POSIX_FADV_WILLNEED 3 +# define POSIX_FADV_DONTNEED 4 +# define POSIX_FADV_NOREUSE 5 + +/* no flock structure for Threadx at this time */ + +#endif diff --git a/utility/rtos_compatibility_layers/posix/posix_demo.c b/utility/rtos_compatibility_layers/posix/posix_demo.c new file mode 100644 index 00000000..339ad9bb --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/posix_demo.c @@ -0,0 +1,344 @@ +/* This is a small demo of the POSIX Compliancy Wrapper for the high-performance ThreadX kernel. */ +/* It includes examples of six pthreads of different priorities, using a message queue, semaphore and mutex. */ + +#include "pthread.h" + +#define DEMO_STACK_SIZE 2048 +#define MAX_MESSAGE_SIZE 50 +#define DEMO_BYTE_POOL_SIZE 9120 + +/* Define the POSIX pthread object control blocks ... */ + +pthread_t pthread_0; +pthread_t pthread_1; +pthread_t pthread_2; +pthread_t pthread_3; +pthread_t pthread_4; +pthread_t pthread_5; + +/* Define pthread attributes objects */ + +pthread_attr_t ptattr0; +pthread_attr_t ptattr1; +pthread_attr_t ptattr2; +pthread_attr_t ptattr3; +pthread_attr_t ptattr4; +pthread_attr_t ptattr5; + + +/* Define the message queue attribute. */ + +struct mq_attr queue_atrr; + +/* Define a queue descriptor. */ + +mqd_t q_des; + +/* Define a semaphore. */ + +sem_t *sem; + +/* Define a mutex */ + +pthread_mutex_t mutex1; + +/* Define a mutex attributes object */ + +pthread_mutexattr_t mta1; + + +/* Define the counters used in this demo application... */ + +ULONG pthread_0_counter; +ULONG pthread_1_counter; +ULONG pthread_2_counter; +ULONG pthread_3_counter; +ULONG pthread_4_counter; +ULONG pthread_5_counter; +ULONG pthread_1_message_sent; +ULONG pthread_2_message_received; + + +/* Define pthread function prototypes. */ + +VOID *pthread_0_entry(VOID *); +VOID *pthread_1_entry(VOID *); +VOID *pthread_2_entry(VOID *); +VOID *pthread_3_entry(VOID *); +VOID *pthread_4_entry(VOID *); +VOID *pthread_5_entry(VOID *); + + +/* Message to be sent. */ +CHAR *msg0 = "This is a test message"; + +/* Define main entry point. */ + +INT main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + +ULONG free_memory[192*1024 / sizeof(ULONG)]; +/* Define what the initial system looks like. */ +VOID tx_application_define(VOID *first_unused_memory) +{ + +VOID* storage_ptr; + + +struct sched_param param; + + queue_atrr.mq_maxmsg = 124; + queue_atrr.mq_msgsize = MAX_MESSAGE_SIZE; + + + /* Init POSIX Wrapper */ + storage_ptr = (VOID*) posix_initialize(free_memory); + + /* Put system definition stuff in here, e.g. pthread creates and other assoerted + create information. */ + + /* Create pthread attributes for pthread 0 to pthread 5 */ + pthread_attr_init(&ptattr0); + pthread_attr_init(&ptattr1); + pthread_attr_init(&ptattr2); + pthread_attr_init(&ptattr3); + pthread_attr_init(&ptattr4); + pthread_attr_init(&ptattr5); + + /* Create a sched_param structure */ + memset(¶m, 0, sizeof(param)); + + /* Now create all pthreads , firstly modify respective ptheread + attribute with desired priority and stack start address and then create the pthread */ + + /* Create pthread 0. */ + param.sched_priority = 10; + pthread_attr_setschedparam(&ptattr0, ¶m); + pthread_attr_setstackaddr(&ptattr0, storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL); + + /* Create pthread 1. */ + param.sched_priority = 15; + pthread_attr_setschedparam(&ptattr1, ¶m); + pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL); + + /* Create pthread 2. */ + param.sched_priority = 20; + pthread_attr_setschedparam(&ptattr2, ¶m); + pthread_attr_setstackaddr(&ptattr2, (VOID*) storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_2, &ptattr2,pthread_2_entry,NULL); + + /* Create pthread 3. */ + param.sched_priority = 25; + pthread_attr_setschedparam(&ptattr3, ¶m); + pthread_attr_setstackaddr(&ptattr3, (VOID*) storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_3, &ptattr3,pthread_3_entry,NULL); + + /* Create pthread 4. */ + param.sched_priority = 30; + pthread_attr_setschedparam(&ptattr4, ¶m); + pthread_attr_setstackaddr(&ptattr4, (VOID*) storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_4, &ptattr4,pthread_4_entry,NULL); + + /* Create pthread 5. */ + param.sched_priority = 5; + pthread_attr_setschedparam(&ptattr5, ¶m); + pthread_attr_setstackaddr(&ptattr5, (VOID*) storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_5, &ptattr5,pthread_5_entry,NULL); + + /* Create a Message queue. */ + q_des = mq_open("Queue",O_CREAT|O_RDWR,0,&queue_atrr); + + /* Create a Semaphore. */ + sem = sem_open("Sem0", O_CREAT | O_EXCL,0,1); + + /* Create a Mutex */ + pthread_mutex_init(&mutex1, NULL); + +} + +/* Define the test pthreads */ +INT pt0_status=0; + +VOID *pthread_0_entry(VOID *pthread0_input) +{ + + struct timespec thread_0_sleep_time={0,0}; + + /* This pthread simply sits in while-forever-sleep loop */ + while(1) + { + /* Increment the pthread counter.*/ + pthread_0_counter++; + /* sleep for a while */ + thread_0_sleep_time.tv_nsec = 999999999; + thread_0_sleep_time.tv_sec = 4; + pt0_status=nanosleep(&thread_0_sleep_time,0); + if(pt0_status) + break; + } + + return(&pt0_status); +} + + +INT pt1_status=0; + +VOID *pthread_1_entry(VOID *pthread1_input) +{ + + struct timespec thread_1_sleep_time={0,0}; + + /* This thread simply sends a messages to a queue shared by pthread 2. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_1_counter++; + /* Send message to queue 0. */ + pt1_status = mq_send(q_des,msg0,strlen(msg0),3); + + /* check status. */ + if(pt1_status) + break; + + /* Increment the message sent. */ + pthread_1_message_sent++; + + /* sleep for a while */ + thread_1_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_1_sleep_time,0); + } + return(&pt1_status); +} + + +INT pt2_status; + +VOID *pthread_2_entry(VOID *pthread2_input) +{ + +CHAR msgr0[MAX_MESSAGE_SIZE]; +ULONG priority; +struct timespec thread_2_sleep_time={0,0}; + + /* This pthread retrieves messages placed on the queue by pthread 1. */ + while(1 ) + { + /* Increment the thread counter. */ + pthread_2_counter++; + pt2_status = mq_receive(q_des,msgr0,MAX_MESSAGE_SIZE,&priority); + + if(pt2_status == ERROR) + break; + + /* Otherwise, it is OK to increment the received message count. */ + pthread_2_message_received++; + /* sleep for a while */ + thread_2_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_2_sleep_time,0); + } + return(&pt2_status); +} + +INT pt3_status; +VOID *pthread_3_entry(VOID *pthread3_input) +{ + + +struct timespec thread_3_sleep_time={0,0}; + + + /* This function compete for ownership of semaphore_0. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_3_counter++; + /* Get the semaphore with suspension. */ + pt3_status = sem_wait(sem); + + /* Check status. */ + if (pt3_status) + break; + + /* Sleep for a while to hold the semaphore. */ + thread_3_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_3_sleep_time,0); + + /* Release the semaphore. */ + pt3_status = sem_post(sem); + + /* Check status. */ + if (pt3_status ) + break; + } + return(&pt3_status); +} + +INT pt4_status; + +VOID *pthread_4_entry(VOID *pthread4_input) +{ + +struct timespec thread_4_sleep_time={0,0}; + + while(1) + { + + /* Increment the thread counter. */ + pthread_4_counter++; + /* now lock the mutex */ + pt4_status = pthread_mutex_lock(&mutex1); + if (pt4_status != OK) + break; + + /* sleep for a while */ + thread_4_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_4_sleep_time,0); + + pt4_status = pthread_mutex_unlock(&mutex1); + if (pt4_status != OK) + break; + } + return(&pt4_status); +} + +INT pt5_status; + +VOID *pthread_5_entry(VOID *pthread5_input) +{ + +struct timespec thread_5_sleep_time={0,0}; + + while(1) + { + /* Increment the thread counter. */ + pthread_5_counter++; + /* now lock the mutex */ + pt5_status = pthread_mutex_lock(&mutex1); + if (pt5_status != OK) + break; + + /* sleep for a while */ + thread_5_sleep_time.tv_nsec = 20000000; + nanosleep(&thread_5_sleep_time,0); + pt5_status = pthread_mutex_unlock(&mutex1); + if (pt5_status != OK) + break; + } + return(&pt5_status); +} + + diff --git a/utility/rtos_compatibility_layers/posix/posix_signal_nested_test.c b/utility/rtos_compatibility_layers/posix/posix_signal_nested_test.c new file mode 100644 index 00000000..70fb4887 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/posix_signal_nested_test.c @@ -0,0 +1,228 @@ +/* Simple nested-signaling test. */ + +#include "pthread.h" + +#define DEMO_STACK_SIZE 2048 +#define DEMO_BYTE_POOL_SIZE 9120 + + +/* Define the POSIX pthread object control blocks ... */ + +pthread_t pthread_0; + + +/* Define pthread attributes objects */ + + +pthread_attr_t ptattr0; + + +/* Define the counters used in this test application... */ + +ULONG pthread_0_counter; +ULONG pthread_0_signal_counter15; +ULONG pthread_0_signal_counter14; +ULONG pthread_0_signal_counter13; + + +/* Define pthread function prototypes. */ + +VOID *pthread_0_entry(VOID *); + + +/* Define signal handlers. */ + +VOID pthread_0_signal_handler15(int); +VOID pthread_0_signal_handler14(int); +VOID pthread_0_signal_handler13(int); + +ULONG free_memory[192*1024 / sizeof(ULONG)]; +/* Define main entry point. */ + +INT main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ +VOID tx_application_define(VOID *first_unused_memory) +{ + + VOID* storage_ptr; + + +struct sched_param param; + + + /* Init POSIX Wrapper */ + storage_ptr = (VOID*) posix_initialize((VOID* )free_memory); + + /* Put system definition stuff in here, e.g. pthread creates and other assoerted + create information. */ + + /* Create pthread attributes. */ + pthread_attr_init(&ptattr0); + + /* Create a sched_param structure */ + memset(¶m, 0, sizeof(param)); + + /* Now create all pthreads , firstly modify respective ptheread + attribute with desired priority and stack start address and then create the pthread */ + + /* Create pthread 0. */ + param.sched_priority = 10; + pthread_attr_setschedparam(&ptattr0, ¶m); + pthread_attr_setstackaddr(&ptattr0, storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL); +} + + +VOID error_handler(void) +{ + + while(1) + { + } +} + + +/* Define the signal handlers. */ + + +VOID pthread_0_signal_handler13(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 13) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter13++; +} + + +VOID pthread_0_signal_handler14(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 14) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter14++; + + /* Raise another signal for nesting test. */ + pthread_kill(pthread_0, 13); +} + + +VOID pthread_0_signal_handler15(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 15) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter15++; + + /* Raise another signal for nesting test. */ + pthread_kill(pthread_0, 14); +} + + +/* Define the test pthreads */ +INT pt0_status=0; + + +/* Self signal test. */ + +VOID *pthread_0_entry(VOID *pthread0_input) +{ + + /* Register the signal handlers. */ + pt0_status = signal(15, pthread_0_signal_handler15); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(14, pthread_0_signal_handler14); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(13, pthread_0_signal_handler13); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* This pthread simply sits in while-forever-sleep loop */ + while(1) + { + /* Increment the pthread counter.*/ + pthread_0_counter++; + + /* Raise the signal. */ + pt0_status = pthread_kill(pthread_0, 15); + + /* Check for errors. */ + if ((pt0_status) || + (pthread_0_counter != pthread_0_signal_counter15) || + (pthread_0_counter != pthread_0_signal_counter14) || + (pthread_0_counter != pthread_0_signal_counter13)) + { + + error_handler(); + break; + } + } + + return(&pt0_status); +} + diff --git a/utility/rtos_compatibility_layers/posix/posix_signal_resume_thread_test.c b/utility/rtos_compatibility_layers/posix/posix_signal_resume_thread_test.c new file mode 100644 index 00000000..d2548056 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/posix_signal_resume_thread_test.c @@ -0,0 +1,295 @@ +/* Simple resume from signal handler test. */ + +#include "pthread.h" + +#define DEMO_STACK_SIZE 2048 +#define DEMO_BYTE_POOL_SIZE 9120 + + +/* Define the POSIX pthread object control blocks ... */ + +pthread_t pthread_0; +pthread_t pthread_1; + + +/* Define pthread attributes objects */ + + +pthread_attr_t ptattr0; +pthread_attr_t ptattr1; + + +/* Define a semaphore. */ + +sem_t *sem; + + +/* Define the counters used in this test application... */ + +ULONG pthread_0_counter; +ULONG pthread_0_signal_counter15; +ULONG pthread_0_signal_counter14; +ULONG pthread_0_signal_counter13; + +ULONG pthread_1_counter; + + +/* Define pthread function prototypes. */ + +VOID *pthread_0_entry(VOID *); +VOID *pthread_1_entry(VOID *); + + +/* Define signal handlers. */ + +VOID pthread_0_signal_handler15(int); +VOID pthread_0_signal_handler14(int); +VOID pthread_0_signal_handler13(int); +ULONG free_memory[192*1024 / sizeof(ULONG)]; + +/* Define main entry point. */ + +INT main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ +VOID tx_application_define(VOID *first_unused_memory) +{ + + VOID* storage_ptr; + + +struct sched_param param; + + + /* Init POSIX Wrapper */ + storage_ptr = (VOID*) posix_initialize((VOID*)free_memory); + + /* Put system definition stuff in here, e.g. pthread creates and other assoerted + create information. */ + + /* Create pthread attributes. */ + pthread_attr_init(&ptattr0); + pthread_attr_init(&ptattr1); + + /* Create a sched_param structure */ + memset(¶m, 0, sizeof(param)); + + /* Now create all pthreads , firstly modify respective ptheread + attribute with desired priority and stack start address and then create the pthread */ + + /* Create pthread 0. */ + param.sched_priority = 15; + pthread_attr_setschedparam(&ptattr0, ¶m); + pthread_attr_setstackaddr(&ptattr0, storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL); + + + /* Create pthread 1. */ + param.sched_priority = 10; + pthread_attr_setschedparam(&ptattr1, ¶m); + pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL); + + + /* Create a Semaphore. */ + sem = sem_open("Sem0", O_CREAT | O_EXCL,0,1); +} + + +VOID error_handler(void) +{ + + while(1) + { + } +} + + + +/* Define the signal handlers. */ + + +VOID pthread_0_signal_handler13(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 13) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter13++; + + /* Release the semaphore, which will wakeup pthread 0. */ + sem_post(sem); +} + + +VOID pthread_0_signal_handler14(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 14) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter14++; + + /* Raise another signal for nesting test. */ + pthread_kill(pthread_0, 13); +} + + +VOID pthread_0_signal_handler15(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 15) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter15++; + + /* Raise another signal for nesting test. */ + pthread_kill(pthread_0, 14); +} + + +/* Define the test pthreads */ +INT pt0_status=0; + + +/* Self signal test. */ + +VOID *pthread_0_entry(VOID *pthread0_input) +{ + + /* Register the signal handlers. */ + pt0_status = signal(15, pthread_0_signal_handler15); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(14, pthread_0_signal_handler14); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(13, pthread_0_signal_handler13); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + + /* Get the semaphore with suspension. */ + pt0_status = sem_wait(sem); + + /* This pthread simply sits in while-forever-sleep loop */ + while(1) + { + /* Increment the pthread counter.*/ + pthread_0_counter++; + + /* Get the semaphore with suspension. */ + pt0_status = sem_wait(sem); + + /* Check for errors. */ + if ((pt0_status) || + (pthread_0_counter != pthread_0_signal_counter15) || + (pthread_0_counter != pthread_0_signal_counter14) || + (pthread_0_counter != pthread_0_signal_counter13)) + { + + /* In this test, this thread should never resume! */ + error_handler(); + + /* Break out of the loop. */ + break; + } + } + + return(&pt0_status); +} + + +INT pt1_status=0; + +VOID *pthread_1_entry(VOID *pthread1_input) +{ + + + /* This thread simply sends a messages to a queue shared by pthread 2. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_1_counter++; + + /* Raise the first signal for pthread 0. */ + pt1_status = pthread_kill(pthread_0, 15); + + /* Check for errors. */ + if ((pt1_status) || + (pthread_0_counter != (pthread_1_counter+1)) || + (pthread_1_counter != pthread_0_signal_counter15) || + (pthread_1_counter != pthread_0_signal_counter14) || + (pthread_1_counter != pthread_0_signal_counter13)) + { + + error_handler(); + break; + } + } + + return(&pt1_status); +} + diff --git a/utility/rtos_compatibility_layers/posix/posix_signal_self_send_test.c b/utility/rtos_compatibility_layers/posix/posix_signal_self_send_test.c new file mode 100644 index 00000000..24e86b95 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/posix_signal_self_send_test.c @@ -0,0 +1,436 @@ +/* Simple self-signaling test. */ + +#include "pthread.h" + +#define DEMO_STACK_SIZE 2048 +#if 0 +#define MAX_MESSAGE_SIZE 50 +#endif +#define DEMO_BYTE_POOL_SIZE 9120 + + +/* Define the POSIX pthread object control blocks ... */ + +pthread_t pthread_0; + +#if 0 +pthread_t pthread_1; +pthread_t pthread_2; +pthread_t pthread_3; +pthread_t pthread_4; +pthread_t pthread_5; +#endif + +/* Define pthread attributes objects */ + + +pthread_attr_t ptattr0; +#if 0 +pthread_attr_t ptattr1; +pthread_attr_t ptattr2; +pthread_attr_t ptattr3; +pthread_attr_t ptattr4; +pthread_attr_t ptattr5; + + +/* Define the message queue attribute. */ + +struct mq_attr queue_atrr; + +/* Define a queue descriptor. */ + +mqd_t q_des; + +/* Define a semaphore. */ + +sem_t *sem; + +/* Define a mutex */ + +pthread_mutex_t mutex1; + +/* Define a mutex attributes object */ + +pthread_mutexattr_t mta1; +#endif + +/* Define the counters used in this test application... */ + +ULONG pthread_0_counter; +ULONG pthread_0_signal_counter; + + +#if 0 +ULONG pthread_1_counter; +ULONG pthread_2_counter; +ULONG pthread_3_counter; +ULONG pthread_4_counter; +ULONG pthread_5_counter; +ULONG pthread_1_message_sent; +ULONG pthread_2_message_received; +#endif + +/* Define pthread function prototypes. */ + +VOID *pthread_0_entry(VOID *); + + +/* Define signal handlers. */ + +VOID pthread_0_signal_handler(int); + + +#if 0 +VOID *pthread_1_entry(VOID *); +VOID *pthread_2_entry(VOID *); +VOID *pthread_3_entry(VOID *); +VOID *pthread_4_entry(VOID *); +VOID *pthread_5_entry(VOID *); + + +/* Message to be sent. */ +CHAR *msg0 = "This is a test message"; +#endif +ULONG free_memory[192*1024 / sizeof(ULONG)]; + +/* Define main entry point. */ + +INT main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ +VOID tx_application_define(VOID *first_unused_memory) +{ + + VOID* storage_ptr; + + +struct sched_param param; + +#if 0 +queue_atrr.mq_maxmsg = 124; +queue_atrr.mq_msgsize = MAX_MESSAGE_SIZE; +#endif + + /* Init POSIX Wrapper */ + storage_ptr = (VOID*) posix_initialize((VOID*)free_memory); + + /* Put system definition stuff in here, e.g. pthread creates and other assoerted + create information. */ + + /* Create pthread attributes. */ + pthread_attr_init(&ptattr0); +#if 0 + pthread_attr_init(&ptattr1); + pthread_attr_init(&ptattr2); + pthread_attr_init(&ptattr3); + pthread_attr_init(&ptattr4); + pthread_attr_init(&ptattr5); +#endif + + /* Create a sched_param structure */ + memset(¶m, 0, sizeof(param)); + + /* Now create all pthreads , firstly modify respective ptheread + attribute with desired priority and stack start address and then create the pthread */ + + /* Create pthread 0. */ + param.sched_priority = 10; + pthread_attr_setschedparam(&ptattr0, ¶m); + pthread_attr_setstackaddr(&ptattr0, storage_ptr ); + storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL); + +#if 0 + /* Create pthread 1. */ + param.sched_priority = 15; + pthread_attr_setschedparam(&ptattr1, ¶m); + pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr ); + storage_ptr = storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL); + + /* Create pthread 2. */ + param.sched_priority = 20; + pthread_attr_setschedparam(&ptattr2, ¶m); + pthread_attr_setstackaddr(&ptattr2, (VOID*) storage_ptr ); + storage_ptr = storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_2, &ptattr2,pthread_2_entry,NULL); + + /* Create pthread 3. */ + param.sched_priority = 25; + pthread_attr_setschedparam(&ptattr3, ¶m); + pthread_attr_setstackaddr(&ptattr3, (VOID*) storage_ptr ); + storage_ptr = storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_3, &ptattr3,pthread_3_entry,NULL); + + /* Create pthread 4. */ + param.sched_priority = 30; + pthread_attr_setschedparam(&ptattr4, ¶m); + pthread_attr_setstackaddr(&ptattr4, (VOID*) storage_ptr ); + storage_ptr = storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_4, &ptattr4,pthread_4_entry,NULL); + + /* Create pthread 5. */ + param.sched_priority = 5; + pthread_attr_setschedparam(&ptattr5, ¶m); + pthread_attr_setstackaddr(&ptattr5, (VOID*) storage_ptr ); + storage_ptr = storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_5, &ptattr5,pthread_5_entry,NULL); + + /* Create a Message queue. */ + q_des = mq_open("Queue",O_CREAT|O_RDWR,0,&queue_atrr); + + /* Create a Semaphore. */ + sem = sem_open("Sem0", O_CREAT | O_EXCL,0,1); + + /* Create a Mutex */ + pthread_mutex_init(&mutex1, NULL); +#endif + +} + +VOID error_handler(void) +{ + + while(1) + { + } +} + + + +/* Define the signal handler. */ + +VOID pthread_0_signal_handler(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 15) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter++; +} + + + +#if 1 +/* Define the test pthreads */ +INT pt0_status=0; +#endif + +/* Self signal test. */ + +VOID *pthread_0_entry(VOID *pthread0_input) +{ + +// struct timespec thread_0_sleep_time={0,0}; + + /* Register the signal handler. */ + pt0_status = signal(15, pthread_0_signal_handler); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* This pthread simply sits in while-forever-sleep loop */ + while(1) + { + /* Increment the pthread counter.*/ + pthread_0_counter++; + + /* Raise the signal. */ + pt0_status = pthread_kill(pthread_0, 15); + + /* Check for errors. */ + if ((pt0_status) || (pthread_0_counter != pthread_0_signal_counter)) + { + error_handler(); + break; + } + +#if 0 + /* sleep for a while */ + thread_0_sleep_time.tv_nsec = 999999999; + thread_0_sleep_time.tv_sec = 4; + pt0_status=nanosleep(&thread_0_sleep_time,0); + if(pt0_status) + break; +#endif + + } + +#if 1 + return(&pt0_status); +#endif +} + +#if 0 +INT pt1_status=0; + +VOID *pthread_1_entry(VOID *pthread1_input) +{ + + struct timespec thread_1_sleep_time={0,0}; + + /* This thread simply sends a messages to a queue shared by pthread 2. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_1_counter++; + /* Send message to queue 0. */ + pt1_status = mq_send(q_des,msg0,strlen(msg0),3); + + /* check status. */ + if(pt1_status) + break; + + /* Increment the message sent. */ + pthread_1_message_sent++; + + /* sleep for a while */ + thread_1_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_1_sleep_time,0); + } + return(&pt1_status); +} + + +INT pt2_status; + +VOID *pthread_2_entry(VOID *pthread2_input) +{ + +CHAR msgr0[MAX_MESSAGE_SIZE]; +ULONG priority; +struct timespec thread_2_sleep_time={0,0}; + + /* This pthread retrieves messages placed on the queue by pthread 1. */ + while(1 ) + { + /* Increment the thread counter. */ + pthread_2_counter++; + pt2_status = mq_receive(q_des,msgr0,MAX_MESSAGE_SIZE,&priority); + + if(pt2_status != 0) + break; + + /* Otherwise, it is OK to increment the received message count. */ + pthread_2_message_received++; + /* sleep for a while */ + thread_2_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_2_sleep_time,0); + } + return(&pt2_status); +} + +INT pt3_status; +VOID *pthread_3_entry(VOID *pthread3_input) +{ + + +struct timespec thread_3_sleep_time={0,0}; + + + /* This function compete for ownership of semaphore_0. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_3_counter++; + /* Get the semaphore with suspension. */ + pt3_status = sem_wait(sem); + + /* Check status. */ + if (pt3_status) + break; + + /* Sleep for a while to hold the semaphore. */ + thread_3_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_3_sleep_time,0); + + /* Release the semaphore. */ + pt3_status = sem_post(sem); + + /* Check status. */ + if (pt3_status ) + break; + } + return(&pt3_status); +} + +INT pt4_status; + +VOID *pthread_4_entry(VOID *pthread4_input) +{ + +struct timespec thread_4_sleep_time={0,0}; + + while(1) + { + + /* Increment the thread counter. */ + pthread_4_counter++; + /* now lock the mutex */ + pt4_status = pthread_mutex_lock(&mutex1); + if (pt4_status != OK) + break; + + /* sleep for a while */ + thread_4_sleep_time.tv_nsec = 200000000; + nanosleep(&thread_4_sleep_time,0); + + pt4_status = pthread_mutex_unlock(&mutex1); + if (pt4_status != OK) + break; + } + return(&pt4_status); +} + +INT pt5_status; + +VOID *pthread_5_entry(VOID *pthread5_input) +{ + +struct timespec thread_5_sleep_time={0,0}; + + while(1) + { + /* Increment the thread counter. */ + pthread_5_counter++; + /* now lock the mutex */ + pt5_status = pthread_mutex_lock(&mutex1); + if (pt5_status != OK) + break; + + /* sleep for a while */ + thread_5_sleep_time.tv_nsec = 20000000; + nanosleep(&thread_5_sleep_time,0); + pt5_status = pthread_mutex_unlock(&mutex1); + if (pt5_status != OK) + break; + } + return(&pt5_status); +} +#endif + + diff --git a/utility/rtos_compatibility_layers/posix/posix_signal_sigmask_test.c b/utility/rtos_compatibility_layers/posix/posix_signal_sigmask_test.c new file mode 100644 index 00000000..2a7cf069 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/posix_signal_sigmask_test.c @@ -0,0 +1,450 @@ +/* Simple signal sigmask test. */ + +#include "pthread.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the POSIX pthread object control blocks ... */ + +pthread_t pthread_0; +pthread_t pthread_1; + + +/* Define pthread attributes objects */ + + +pthread_attr_t ptattr0; +pthread_attr_t ptattr1; + + +/* Define the counters used in this test application... */ + +ULONG pthread_0_counter; +ULONG pthread_0_signal_counter16; +ULONG pthread_0_signal_counter15; +ULONG pthread_0_signal_counter14; +ULONG pthread_0_signal_counter13; + +ULONG pthread_1_counter; + + +/* Define pthread function prototypes. */ + +VOID *pthread_0_entry(VOID *); +VOID *pthread_1_entry(VOID *); + + +/* Define signal handlers. */ + +VOID pthread_0_signal_handler16(int); +VOID pthread_0_signal_handler15(int); +VOID pthread_0_signal_handler14(int); +VOID pthread_0_signal_handler13(int); + +ULONG free_memory[192*1024 / sizeof(ULONG)]; +/* Define main entry point. */ + +INT main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ +VOID tx_application_define(VOID *first_unused_memory) +{ + + VOID* storage_ptr; + + +struct sched_param param; + + + /* Init POSIX Wrapper */ + storage_ptr = (VOID*) posix_initialize((VOID*)free_memory); + + /* Put system definition stuff in here, e.g. pthread creates and other assoerted + create information. */ + + /* Create pthread attributes. */ + pthread_attr_init(&ptattr0); + pthread_attr_init(&ptattr1); + + /* Create a sched_param structure */ + memset(¶m, 0, sizeof(param)); + + /* Now create all pthreads , firstly modify respective ptheread + attribute with desired priority and stack start address and then create the pthread */ + + /* Create pthread 0. */ + param.sched_priority = 15; + pthread_attr_setschedparam(&ptattr0, ¶m); + pthread_attr_setstackaddr(&ptattr0, storage_ptr ); + storage_ptr = (UINT *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL); + + + /* Create pthread 1. */ + param.sched_priority = 10; + pthread_attr_setschedparam(&ptattr1, ¶m); + pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr ); + storage_ptr = (UINT *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL); +} + +VOID error_handler(void) +{ + + while(1) + { + } +} + + + +/* Define the signal handlers. */ + + +VOID pthread_0_signal_handler13(int signo) +{ + +sigset_t wait_set; +int signal_received; +int status; + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 13) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter13++; + + /* Wait on signal 12. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 12); + status = sigwait(&wait_set, &signal_received); + + /* Check for an error. */ + if ((status) || (signal_received != 12)) + { + + /* Call error handler. */ + error_handler(); + } +} + + +VOID pthread_0_signal_handler14(int signo) +{ + +sigset_t wait_set; +int signal_received; +int status; + + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 14) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter14++; + + /* Wait on signal 13. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 13); + status = sigwait(&wait_set, &signal_received); + + /* Check for an error. */ + if ((status) || (signal_received != 13)) + { + + /* Call error handler. */ + error_handler(); + } +} + + +VOID pthread_0_signal_handler15(int signo) +{ + +sigset_t wait_set; +int signal_received; +int status; + + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 15) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter15++; + + /* Wait on signal 14. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 14); + status = sigwait(&wait_set, &signal_received); + + /* Check for an error. */ + if ((status) || (signal_received != 14)) + { + + /* Call error handler. */ + error_handler(); + } +} + + +VOID pthread_0_signal_handler16(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 16) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter16++; +} + + +/* Define the test pthreads */ +INT pt0_status=0; + + +/* Self signal test. */ + +VOID *pthread_0_entry(VOID *pthread0_input) +{ + +sigset_t wait_set; +sigset_t new_mask; +sigset_t old_mask; +int signal_received; + + + /* Register the signal handlers. */ + pt0_status = signal(16, pthread_0_signal_handler16); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(15, pthread_0_signal_handler15); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(14, pthread_0_signal_handler14); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(13, pthread_0_signal_handler13); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Setup block for signal 15, that won't actually be used until the sigwait occurs. */ + sigemptyset(&new_mask); + sigaddset(&new_mask, 15); + pt0_status = pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Setup a signal mask for signal 16. */ + sigemptyset(&new_mask); + sigaddset(&new_mask, 16); + pt0_status = pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Simply restore the signal for this first test. */ + pt0_status = pthread_sigmask(SIG_SETMASK, &old_mask, &old_mask); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Now do it again, but set a signal when the signal is masked. */ + pt0_status = pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Raise the first signal for pthread 0. */ + pt0_status = pthread_kill(pthread_0, 16); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Now unblock this signal to trigger the actual activation of the signal. */ + pt0_status = pthread_sigmask(SIG_UNBLOCK, &new_mask, &old_mask); + + /* Check for error. */ + if ((pt0_status) || (pthread_0_signal_counter16 != 1)) + error_handler(); + + /* Now do it all again, but perform a sigwait when the signal is masked and pending. */ + pt0_status = pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Raise the first signal for pthread 0. */ + pt0_status = pthread_kill(pthread_0, 16); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* Wait on signal 16. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 16); + + /* Now perform a sigwait on signal 16. */ + pt0_status = sigwait(&wait_set, &signal_received); + + /* Check for error. */ + if ((pt0_status) || (pthread_0_signal_counter16 != 2) || (signal_received != 16)) + error_handler(); + + /* Now unblock this signal to trigger the actual activation of the signal. */ + pt0_status = pthread_sigmask(SIG_UNBLOCK, &new_mask, &old_mask); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* This pthread simply sits in while-forever-sleep loop */ + while(1) + { + /* Increment the pthread counter.*/ + pthread_0_counter++; + + /* Wait on signal 15. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 15); + + /* Signal wait. */ + pt0_status = sigwait(&wait_set, &signal_received); + + /* Check for errors. */ + if ((pt0_status) || + (signal_received != 15) || + (pthread_0_counter != pthread_0_signal_counter15) || + (pthread_0_counter != pthread_0_signal_counter14) || + (pthread_0_counter != pthread_0_signal_counter13)) + { + + /* In this test, this thread should never resume! */ + error_handler(); + + /* Break out of the loop. */ + break; + } + } + + return(&pt0_status); +} + + +INT pt1_status=0; + +VOID *pthread_1_entry(VOID *pthread1_input) +{ + + + /* This thread simply sends a messages to a queue shared by pthread 2. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_1_counter++; + + /* Raise the first signal for pthread 0. */ + pt1_status = pthread_kill(pthread_0, 15); + + pt1_status += pthread_kill(pthread_0, 14); + + pt1_status += pthread_kill(pthread_0, 13); + + pt1_status += pthread_kill(pthread_0, 12); + + /* Check for errors. */ + if ((pt1_status) || + (pthread_0_counter != (pthread_1_counter+1)) || + (pthread_1_counter != pthread_0_signal_counter15) || + (pthread_1_counter != pthread_0_signal_counter14) || + (pthread_1_counter != pthread_0_signal_counter13)) + { + + error_handler(); + break; + } + } + + return(&pt1_status); +} diff --git a/utility/rtos_compatibility_layers/posix/posix_signal_sigwait_test.c b/utility/rtos_compatibility_layers/posix/posix_signal_sigwait_test.c new file mode 100644 index 00000000..80d6402a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/posix_signal_sigwait_test.c @@ -0,0 +1,338 @@ +/* Simple signal sigwait test. */ + +#include "pthread.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the POSIX pthread object control blocks ... */ + +pthread_t pthread_0; +pthread_t pthread_1; + + +/* Define pthread attributes objects */ + + +pthread_attr_t ptattr0; +pthread_attr_t ptattr1; + + +/* Define the counters used in this test application... */ + +ULONG pthread_0_counter; +ULONG pthread_0_signal_counter15; +ULONG pthread_0_signal_counter14; +ULONG pthread_0_signal_counter13; + +ULONG pthread_1_counter; + + +/* Define pthread function prototypes. */ + +VOID *pthread_0_entry(VOID *); +VOID *pthread_1_entry(VOID *); + + +/* Define signal handlers. */ + +VOID pthread_0_signal_handler15(int); +VOID pthread_0_signal_handler14(int); +VOID pthread_0_signal_handler13(int); +ULONG free_memory[192*1024 / sizeof(ULONG)]; + +/* Define main entry point. */ + +INT main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ +VOID tx_application_define(VOID *first_unused_memory) +{ + + VOID* storage_ptr; + + +struct sched_param param; + + + /* Init POSIX Wrapper */ + storage_ptr = (VOID*) posix_initialize((VOID*)free_memory); + + /* Put system definition stuff in here, e.g. pthread creates and other assoerted + create information. */ + + /* Create pthread attributes. */ + pthread_attr_init(&ptattr0); + pthread_attr_init(&ptattr1); + + /* Create a sched_param structure */ + memset(¶m, 0, sizeof(param)); + + /* Now create all pthreads , firstly modify respective ptheread + attribute with desired priority and stack start address and then create the pthread */ + + /* Create pthread 0. */ + param.sched_priority = 15; + pthread_attr_setschedparam(&ptattr0, ¶m); + pthread_attr_setstackaddr(&ptattr0, storage_ptr ); + storage_ptr = (UINT *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL); + + + /* Create pthread 1. */ + param.sched_priority = 10; + pthread_attr_setschedparam(&ptattr1, ¶m); + pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr ); + storage_ptr = (UINT *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL); +} + +VOID error_handler(void) +{ + + while(1) + { + } +} + + + +/* Define the signal handlers. */ + + +VOID pthread_0_signal_handler13(int signo) +{ + +sigset_t wait_set; +int signal_received; +int status; + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 13) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter13++; + + /* Wait on signal 12. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 12); + status = sigwait(&wait_set, &signal_received); + + /* Check for an error. */ + if ((status) || (signal_received != 12)) + { + + /* Call error handler. */ + error_handler(); + } +} + + +VOID pthread_0_signal_handler14(int signo) +{ + +sigset_t wait_set; +int signal_received; +int status; + + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 14) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter14++; + + /* Wait on signal 13. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 13); + status = sigwait(&wait_set, &signal_received); + + /* Check for an error. */ + if ((status) || (signal_received != 13)) + { + + /* Call error handler. */ + error_handler(); + } +} + + +VOID pthread_0_signal_handler15(int signo) +{ + +sigset_t wait_set; +int signal_received; +int status; + + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 15) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter15++; + + /* Wait on signal 14. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 14); + status = sigwait(&wait_set, &signal_received); + + /* Check for an error. */ + if ((status) || (signal_received != 14)) + { + + /* Call error handler. */ + error_handler(); + } +} + + +/* Define the test pthreads */ +INT pt0_status=0; + + +/* Self signal test. */ + +VOID *pthread_0_entry(VOID *pthread0_input) +{ + +sigset_t wait_set; +int signal_received; + + + /* Register the signal handlers. */ + pt0_status = signal(15, pthread_0_signal_handler15); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(14, pthread_0_signal_handler14); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(13, pthread_0_signal_handler13); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + /* This pthread simply sits in while-forever-sleep loop */ + while(1) + { + /* Increment the pthread counter.*/ + pthread_0_counter++; + + /* Wait on signal 15. */ + sigemptyset(&wait_set); + sigaddset(&wait_set, 15); + + /* Signal wait. */ + pt0_status = sigwait(&wait_set, &signal_received); + + /* Check for errors. */ + if ((pt0_status) || + (signal_received != 15) || + (pthread_0_counter != pthread_0_signal_counter15) || + (pthread_0_counter != pthread_0_signal_counter14) || + (pthread_0_counter != pthread_0_signal_counter13)) + { + + /* In this test, this thread should never resume! */ + error_handler(); + + /* Break out of the loop. */ + break; + } + } + + return(&pt0_status); +} + + +INT pt1_status=0; + +VOID *pthread_1_entry(VOID *pthread1_input) +{ + + + /* This thread simply sends a messages to a queue shared by pthread 2. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_1_counter++; + + /* Raise the first signal for pthread 0. */ + pt1_status = pthread_kill(pthread_0, 15); + + pt1_status += pthread_kill(pthread_0, 14); + + pt1_status += pthread_kill(pthread_0, 13); + + pt1_status += pthread_kill(pthread_0, 12); + + /* Check for errors. */ + if ((pt1_status) || + (pthread_0_counter != (pthread_1_counter+1)) || + (pthread_1_counter != pthread_0_signal_counter15) || + (pthread_1_counter != pthread_0_signal_counter14) || + (pthread_1_counter != pthread_0_signal_counter13)) + { + + error_handler(); + break; + } + } + + return(&pt1_status); +} + diff --git a/utility/rtos_compatibility_layers/posix/posix_signal_suspended_thread_test.c b/utility/rtos_compatibility_layers/posix/posix_signal_suspended_thread_test.c new file mode 100644 index 00000000..723c80db --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/posix_signal_suspended_thread_test.c @@ -0,0 +1,288 @@ +/* Simple nested-signaling test. */ + +#include "pthread.h" + +#define DEMO_STACK_SIZE 2048 +#define DEMO_BYTE_POOL_SIZE 9120 + + +/* Define the POSIX pthread object control blocks ... */ + +pthread_t pthread_0; +pthread_t pthread_1; + + +/* Define pthread attributes objects */ + + +pthread_attr_t ptattr0; +pthread_attr_t ptattr1; + + +/* Define a semaphore. */ + +sem_t *sem; + + +/* Define the counters used in this test application... */ + +ULONG pthread_0_counter; +ULONG pthread_0_signal_counter15; +ULONG pthread_0_signal_counter14; +ULONG pthread_0_signal_counter13; + +ULONG pthread_1_counter; + + +/* Define pthread function prototypes. */ + +VOID *pthread_0_entry(VOID *); +VOID *pthread_1_entry(VOID *); + + +/* Define signal handlers. */ + +VOID pthread_0_signal_handler15(int); +VOID pthread_0_signal_handler14(int); +VOID pthread_0_signal_handler13(int); + +ULONG free_memory[192*1024 / sizeof(ULONG)]; +/* Define main entry point. */ + +INT main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ +VOID tx_application_define(VOID *first_unused_memory) +{ + + VOID* storage_ptr; + + +struct sched_param param; + + + /* Init POSIX Wrapper */ + storage_ptr = (VOID*) posix_initialize((VOID*)free_memory); + + /* Put system definition stuff in here, e.g. pthread creates and other assoerted + create information. */ + + /* Create pthread attributes. */ + pthread_attr_init(&ptattr0); + pthread_attr_init(&ptattr1); + + /* Create a sched_param structure */ + memset(¶m, 0, sizeof(param)); + + /* Now create all pthreads , firstly modify respective ptheread + attribute with desired priority and stack start address and then create the pthread */ + + /* Create pthread 0. */ + param.sched_priority = 15; + pthread_attr_setschedparam(&ptattr0, ¶m); + pthread_attr_setstackaddr(&ptattr0, storage_ptr ); + storage_ptr = (UINT *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL); + + + /* Create pthread 1. */ + param.sched_priority = 10; + pthread_attr_setschedparam(&ptattr1, ¶m); + pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr ); + storage_ptr = (UINT *) storage_ptr + DEMO_STACK_SIZE; + pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL); + + + /* Create a Semaphore. */ + sem = sem_open("Sem0", O_CREAT | O_EXCL,0,1); +} + + +VOID error_handler(void) +{ + + while(1) + { + } +} + + +/* Define the signal handlers. */ + + +VOID pthread_0_signal_handler13(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 13) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter13++; +} + + +VOID pthread_0_signal_handler14(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 14) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter14++; + + /* Raise another signal for nesting test. */ + pthread_kill(pthread_0, 13); +} + + +VOID pthread_0_signal_handler15(int signo) +{ + + /* Check for pthread self call not pthread 0. The signal handler should appear to be + called from pthread 0. */ + if (pthread_self() != pthread_0) + { + + /* Call error handler. */ + error_handler(); + } + + /* Check for proper signal. */ + if (signo != 15) + { + + /* Call error handler. */ + error_handler(); + } + + /* Just increment the signal counter for this test. */ + pthread_0_signal_counter15++; + + /* Raise another signal for nesting test. */ + pthread_kill(pthread_0, 14); +} + + +/* Define the test pthreads */ +INT pt0_status=0; + + +/* Self signal test. */ + +VOID *pthread_0_entry(VOID *pthread0_input) +{ + + /* Register the signal handlers. */ + pt0_status = signal(15, pthread_0_signal_handler15); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(14, pthread_0_signal_handler14); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + pt0_status = signal(13, pthread_0_signal_handler13); + + /* Check for error. */ + if (pt0_status) + error_handler(); + + + /* Get the semaphore with suspension. */ + pt0_status = sem_wait(sem); + + /* This pthread simply sits in while-forever-sleep loop */ + while(1) + { + /* Increment the pthread counter.*/ + pthread_0_counter++; + + /* Get the semaphore with suspension. */ + pt0_status = sem_wait(sem); + + /* In this test, this thread should never resume! */ + error_handler(); + + /* Check for error condition. */ + if (pt0_status) + { + + /* Break out of the loop. */ + break; + } + } + + return(&pt0_status); +} + + +INT pt1_status=0; + +VOID *pthread_1_entry(VOID *pthread1_input) +{ + + + /* This thread simply sends a messages to a queue shared by pthread 2. */ + while(1) + { + + /* Increment the thread counter. */ + pthread_1_counter++; + + /* Raise the first signal for pthread 0. */ + pt1_status = pthread_kill(pthread_0, 15); + + /* Check for errors. */ + if ((pt1_status) || + (pthread_0_counter != 1) || + (pthread_1_counter != pthread_0_signal_counter15) || + (pthread_1_counter != pthread_0_signal_counter14) || + (pthread_1_counter != pthread_0_signal_counter13)) + { + + error_handler(); + break; + } + } + + return(&pt1_status); +} + diff --git a/ports/cortex_m33/ac5/inc/tx_secure_interface.h b/utility/rtos_compatibility_layers/posix/pthread.h similarity index 67% rename from ports/cortex_m33/ac5/inc/tx_secure_interface.h rename to utility/rtos_compatibility_layers/posix/pthread.h index 6fa51319..3217c858 100644 --- a/ports/cortex_m33/ac5/inc/tx_secure_interface.h +++ b/utility/rtos_compatibility_layers/posix/pthread.h @@ -9,52 +9,50 @@ /* */ /**************************************************************************/ - /**************************************************************************/ /**************************************************************************/ /** */ -/** ThreadX Component */ +/** ThreadX Component */ /** */ -/** Thread */ +/** POSIX Compliancy Wrapper (POSIX) */ /** */ /**************************************************************************/ /**************************************************************************/ - /**************************************************************************/ /* */ -/* COMPONENT DEFINITION RELEASE */ +/* EKP DEFINITIONS RELEASE */ /* */ -/* tx_secure_interface.h Cortex-M33 */ -/* 6.1 */ +/* sched.h PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This file defines the ThreadX secure thread stack components, */ -/* including data types and external references. */ -/* It is assumed that tx_api.h and tx_port.h have already been */ -/* included. */ +/* This file defines the constants, structures, etc.needed to */ +/* implement the Evacuation Kit for POSIX Users (POSIX) */ +/* */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ /* */ /**************************************************************************/ -#ifndef TX_SECURE_INTERFACE_H -#define TX_SECURE_INTERFACE_H +#ifndef _PTHREAD_H +#define _PTHREAD_H -/* Define internal secure thread stack function prototypes. */ +#include "tx_api.h" +#include "errno.h" +#include "fcntl.h" +#include "sched.h" +#include "time.h" +#include "signal.h" +#include "tx_posix.h" -extern void _tx_thread_secure_stack_initialize(void); -extern UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size); -extern UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr); -extern void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr); -extern void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr); #endif diff --git a/utility/rtos_compatibility_layers/posix/px_abs_time_to_rel_ticks.c b/utility/rtos_compatibility_layers/posix/px_abs_time_to_rel_ticks.c new file mode 100644 index 00000000..5cde9b2a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_abs_time_to_rel_ticks.c @@ -0,0 +1,92 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "time.h" +#include + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_abs_time_to_rel_ticks PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function converts the absolute time specified in a POSIX */ +/* timespec structure into the relative number of timer ticks until */ +/* that time will occur. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +ULONG posix_abs_time_to_rel_ticks(struct timespec *abs_timeout) +{ + ULONG current_ticks, ticks_ns, ticks_sec, timeout_ticks; + + current_ticks = tx_time_get(); + /* convert ns to ticks (will lose any ns < 1 tick) */ + ticks_ns = abs_timeout->tv_nsec / NANOSECONDS_IN_CPU_TICK; + /* + * if ns < 1 tick were lost, bump up to next tick so the delay is never + * less than what was specified. + */ + if (ticks_ns * NANOSECONDS_IN_CPU_TICK != abs_timeout->tv_nsec) + { + ++ticks_ns; + } + ticks_sec = (ULONG) (abs_timeout->tv_sec * CPU_TICKS_PER_SECOND); + /* add in sec. ticks, subtract current ticks to get relative value. */ + timeout_ticks = ticks_sec + ticks_ns - current_ticks; + /* + * Unless a relative timeout of zero was specified, bump up 1 tick to + * compensate for the fact that there is an unknown time between 0 and + * < 1 tick until the next tick. We never want the delay to be less than + * what was requested. + */ + if (timeout_ticks != 0) + { + ++timeout_ticks; + } + /* + * If the absolute time was in the past, then we need to set the + * relative time to zero; otherwise, we get an essentially infinite timeout. + */ + if (timeout_ticks > LONG_MAX) + { + timeout_ticks = 0; + } + + return timeout_ticks; +} diff --git a/utility/rtos_compatibility_layers/posix/px_clock_getres.c b/utility/rtos_compatibility_layers/posix/px_clock_getres.c new file mode 100644 index 00000000..fd5867df --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_clock_getres.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* clock_getres PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This subroutine returns the Clock resolution of the Threadx real */ +/* time clock in nanoseconds */ +/* */ +/* INPUT */ +/* */ +/* clockid_t, tspec */ +/* */ +/* OUTPUT */ +/* */ +/* error code */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT clock_getres(clockid_t t, struct timespec * tspec) +{ + + if(t==CLOCK_REALTIME) + { + if(tspec) tspec->tv_nsec= NANOSECONDS_IN_CPU_TICK; + return(OK); + } + else return(EINVAL); + +} diff --git a/utility/rtos_compatibility_layers/posix/px_clock_gettime.c b/utility/rtos_compatibility_layers/posix/px_clock_gettime.c new file mode 100644 index 00000000..5ce538f7 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_clock_gettime.c @@ -0,0 +1,85 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* clock_gettime PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This subroutine returns the time. The source of the time */ +/* is the internal Threadx timer variable, which keeps track */ +/* of the number of ticks of the Threadx timer ISR. */ +/* */ +/* INPUT */ +/* */ +/* clockid_t, tspec */ +/* */ +/* OUTPUT */ +/* */ +/* error code */ +/* */ +/* CALLS */ +/* */ +/* tx_time_get ThreadX function */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT clock_gettime(clockid_t t, struct timespec * tspec) +{ + ULONG tx_time; + + if(t==CLOCK_REALTIME) + { + tx_time=tx_time_get(); + + tspec->tv_sec = tx_time / CPU_TICKS_PER_SECOND; + + tspec->tv_nsec = (ULONG) ((tx_time - tspec->tv_sec*CPU_TICKS_PER_SECOND) * NANOSECONDS_IN_CPU_TICK); + + return(OK); + } + else return(EINVAL); + +} diff --git a/utility/rtos_compatibility_layers/posix/px_clock_settime.c b/utility/rtos_compatibility_layers/posix/px_clock_settime.c new file mode 100644 index 00000000..d2c0e7df --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_clock_settime.c @@ -0,0 +1,81 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* clock_settime PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This subroutine sets the internal Threadx timer tick variable */ +/* to the time specificed in the tspec variable after conversion */ +/* if tspec->tv_sec is 0 the clock with be set to the value of */ +/* tspec->tv_nsec */ +/* */ +/* INPUT */ +/* */ +/* clockid_t, tspec */ +/* */ +/* OUTPUT */ +/* */ +/* error code */ +/* */ +/* CALLS */ +/* */ +/* tx_time_set ThreadX function */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT clock_settime(clockid_t t, const struct timespec * tspec) +{ + ULONG tx_time; + + if(t==CLOCK_REALTIME) + { + tx_time=(ULONG)((tspec->tv_sec * CPU_TICKS_PER_SECOND) + (tspec->tv_nsec / NANOSECONDS_IN_CPU_TICK)); + tx_time_set( tx_time); + return(OK); + } + else return(EINVAL); +} diff --git a/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c b/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c new file mode 100644 index 00000000..e4520942 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c @@ -0,0 +1,147 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_cond_broadcast PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* These functions shall unblock all threads currently blocked on a */ +/* specified condition variable cond. */ +/* If more than one thread is blocked on a condition variable, */ +/* the scheduling policy shall determine the order in which threads are*/ +/* unblocked. When each thread unblocked as a result of this function */ +/* call returns from its call to pthread_cond_wait or */ +/* pthread_cond_timedwait, the thread shall own the mutex with which it*/ +/* called pthread_cond_wait or pthread_cond_timedwait. The thread(s) */ +/* that are unblocked shall contend for the mutex according to the */ +/* scheduling policy (if applicable), and as if each had called */ +/* pthread_mutex_lock.The pthread_cond_broadcast function may be called*/ +/* by a thread whether or not it currently owns the mutex that threads */ +/* calling pthread_cond_wait or pthread_cond_timedwait have associated */ +/* with the condition variable during their waits; however, */ +/* if predictable scheduling behavior is required, then that mutex */ +/* shall be locked by the thread calling pthread_cond_broadcast. */ +/* The pthread_cond_broadcast function shall have no effect if there */ +/* are no threads currently blocked on cond. */ +/* */ +/* INPUT */ +/* */ +/* cond condition variable */ +/* */ +/* OUTPUT */ +/* */ +/* Ok if successful */ +/* Error in case of any errors */ +/* */ +/* CALLS */ +/* */ +/* tx_semaphore_prioritize line up pthreads waiting at semaphore*/ +/* tx_thread_identify to check which pthread? */ +/* tx_thread_preemption_change to disable thread preemption */ +/* tx_semaphore_put ThreadX semaphore put service */ +/* tx_thread_preemption_change to enable thread preemption */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_cond_broadcast(pthread_cond_t *cond) +{ + +TX_SEMAPHORE *semaphore_ptr; +TX_THREAD *thread; +UINT status; +ULONG sem_count; +UINT old_threshold,dummy; + + + /* Get the condition variable's internal semaphore. */ + /* Simply convert the condition variable control block into a semaphore a cast */ + semaphore_ptr = (&( cond->cond_semaphore )); + sem_count = semaphore_ptr->tx_semaphore_suspended_count; + + if (!sem_count) + return(OK); + + status = tx_semaphore_prioritize(semaphore_ptr); + + if ( status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + /* get to know about current thread */ + thread = tx_thread_identify(); + + /* Got the current thread , now raise its preemption threshold */ + /* that way the current thread does not get descheduled when */ + /* threads with higher priority are activated */ + tx_thread_preemption_change(thread,0,&old_threshold); + + while( sem_count) + { + + status = tx_semaphore_put(semaphore_ptr); + if ( status != TX_SUCCESS) + { + + /* restore changed preemption threshold */ + tx_thread_preemption_change(thread,old_threshold,&dummy); + + posix_errno = EINVAL; + + posix_set_pthread_errno(EINVAL); + + return(EINVAL); + } + + sem_count--; + } + + /* restore changed preemption threshold */ + tx_thread_preemption_change(thread,old_threshold,&dummy); + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_cond_destroy.c b/utility/rtos_compatibility_layers/posix/px_cond_destroy.c new file mode 100644 index 00000000..ba7f1ece --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_cond_destroy.c @@ -0,0 +1,101 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_cond_destroy PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* The pthread_cond_destroy function shall destroy the given condition */ +/* variable specified by cond; the object becomes, in effect, */ +/* uninitialized. */ +/* A destroyed condition variable object can be reinitialized using */ +/* pthread_cond_init;referencing the object after it has been destroyed*/ +/* returns error. */ +/* */ +/* INPUT */ +/* */ +/* cond condition variable object */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* EINVAL If error */ +/* */ +/* CALLS */ +/* */ +/* tx_semaphore_delete Deletes a semaphore internal to */ +/* to the cond variable */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_cond_destroy(pthread_cond_t *cond) +{ + +TX_SEMAPHORE *semaphore_ptr; +UINT status; + + if (cond->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + cond->in_use = TX_FALSE; + /* Get the condition variable's internal semaphore. */ + /* Simply convert the Condition variable control block into a semaphore a cast */ + semaphore_ptr = (&( cond->cond_semaphore )); + status = tx_semaphore_delete(semaphore_ptr); + if (status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + return(OK); + } +} + diff --git a/utility/rtos_compatibility_layers/posix/px_cond_init.c b/utility/rtos_compatibility_layers/posix/px_cond_init.c new file mode 100644 index 00000000..f2a8649d --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_cond_init.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_cond_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall initialize the condition variable referenced by */ +/* cond with attributes referenced by attr. If attr is NULL,the default*/ +/* condition variable attributes shall be used; the effect is the same */ +/* as passing the address of a default condition variable attributes */ +/* object. Upon successful initialization, the state of the condition */ +/* variable shall become initialized. */ +/* */ +/* INPUT */ +/* */ +/* Nothing */ +/* */ +/* OUTPUT */ +/* */ +/* cond condition variable object */ +/* attr attributes */ +/* */ +/* CALLS */ +/* */ +/* tx_semaphore_create create a semaphore internal to */ +/* cond variable */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr) +{ + +TX_SEMAPHORE *semaphore_ptr; +UINT status; + + cond->in_use = TX_TRUE; + /* Get the condition variable's internal semaphore. */ + /* Simply convert the COndition variable control block into a semaphore a cast */ + semaphore_ptr = (&( cond->cond_semaphore )); + /* Now create the internal semaphore for this cond variable */ + status = tx_semaphore_create(semaphore_ptr,"csem",0); + if (status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_cond_signal.c b/utility/rtos_compatibility_layers/posix/px_cond_signal.c new file mode 100644 index 00000000..09938af2 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_cond_signal.c @@ -0,0 +1,113 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_cond_signal PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall unblock at least one of the threads that are */ +/* blocked on the specified condition variable cond */ +/* (if any threads are blocked on cond).If more than one thread is */ +/* blocked on a condition variable, the scheduling policy shall */ +/* determine the order in which threads are unblocked.When each thread */ +/* unblocked as a result of a pthread_cond_signal returns from its call*/ +/* to pthread_cond_wait or pthread_cond_timedwait, the thread shall own*/ +/* the mutex with which it called pthread_cond_wait or */ +/* pthread_cond_timedwait.The thread(s) that are unblocked shall */ +/* contend for the mutex according to the scheduling policy */ +/* (if applicable), and as if each had called pthread_mutex_lock. */ +/* The pthread_cond_broadcast or pthread_cond_signal functions may be */ +/* called by a thread whether or not it currently owns the mutex that */ +/* threads calling pthread_cond_wait or pthread_cond_timedwait have */ +/* associated with the condition variable during their waits; however, */ +/* if predictable scheduling behavior is required,then that mutex shall*/ +/* be locked by the thread calling pthread_cond_signal. */ +/* This function shall have no effect if there are no threads currently*/ +/* blocked on cond. */ +/* */ +/* INPUT */ +/* */ +/* Nothing */ +/* */ +/* OUTPUT */ +/* */ +/* Nothing */ +/* */ +/* CALLS */ +/* */ +/* tx_semaphore_prioritize line up pthreads waiting at semaphore*/ +/* tx_semaphore_put ThreadX semaphore put service */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_cond_signal(pthread_cond_t *cond) +{ + +TX_SEMAPHORE *semaphore_ptr; +UINT status; + + /* Get the condition variable's internal semaphore. */ + /* Simply convert the COndition variable control block into a semaphore a cast */ + semaphore_ptr = (&( cond->cond_semaphore )); + if ( semaphore_ptr->tx_semaphore_suspended_count) + { + status = tx_semaphore_prioritize(semaphore_ptr); + if ( status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + status = tx_semaphore_put(semaphore_ptr); + if ( status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + } + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_cond_timedwait.c b/utility/rtos_compatibility_layers/posix/px_cond_timedwait.c new file mode 100644 index 00000000..94ffe3b9 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_cond_timedwait.c @@ -0,0 +1,145 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_cond_timedwait PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall block on a condition variable. They shall be */ +/* called with mutex locked by the calling thread or undefined behavior*/ +/* results.These functions atomically release the mutex and cause the */ +/* calling thread to block on the condition variable cond; atomically */ +/* here means ‘‘atomically with respect to access by another */ +/* thread to the mutex and then the request for semaphore. */ +/* */ +/* Upon successful return, the mutex shall have been locked and shall */ +/* be owned by the calling thread. */ +/* */ +/* Upon successful return, the mutex shall have been locked and shall */ +/* be owned by the calling thread. */ +/* When using condition variables there is always a Boolean predicate */ +/* involving shared variables associated with each condition wait that */ +/* is true if the thread should proceed. Spurious wakeups from the */ +/* pthread_cond_timedwait or pthread_cond_wait functions may occur. */ +/* Since the return from pthread_cond_timedwait or pthread_cond_wait */ +/* does not imply anything about the value of this predicate, the */ +/* predicate should be re-evaluated upon such return. The effect of */ +/* using more than one mutex for concurrent pthread_cond_timedwait or */ +/* pthread_cond_wait operations on the same condition variable is */ +/* undefined; that is, a condition variable becomes bound to a unique */ +/* mutex when a thread waits on the condition variable, and this */ +/* (dynamic) binding shall end when the wait returns. */ +/* */ +/* INPUT */ +/* */ +/* cond condition variable */ +/* mutex mutex to be associated with condition */ +/* variable */ +/* abstime time interval for wait */ +/* */ +/* OUTPUT */ +/* */ +/* OK if succesfull */ +/* ERROR in case of any error */ +/* */ +/* CALLS */ +/* */ +/* pthread_mutex_unlock unlocks the mutex held by the caller */ +/* tx_semaphore_get try to get sempaphore internal to cond */ +/* tx_semaphore_prioritize prioritize all suspended pthreads */ +/* pthread_mutex_lock lock the mutex */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, + struct timespec *abstime) +{ + +TX_SEMAPHORE *semaphore_ptr; +ULONG wait_option; +UINT status; +UINT old_threshold,dummy; +TX_THREAD *thread; + + /* Find the current thread. */ + thread = tx_thread_identify(); + + /* Raise its preemption threshold so it does not get descheduled. */ + tx_thread_preemption_change(thread,0,&old_threshold); + + pthread_mutex_unlock(mutex); + semaphore_ptr = (&( cond->cond_semaphore )); + + wait_option = posix_abs_time_to_rel_ticks(abstime); + + status = tx_semaphore_get(semaphore_ptr, wait_option); + + /* Restore original preemption threshold */ + tx_thread_preemption_change(thread, old_threshold, &dummy); + + if( status == TX_NO_INSTANCE) + { + posix_errno = ETIMEDOUT; + posix_set_pthread_errno(ETIMEDOUT); + return(ETIMEDOUT); + } + else if ( status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + status = tx_semaphore_prioritize(semaphore_ptr); + if (status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + pthread_mutex_lock(mutex); + + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_cond_wait.c b/utility/rtos_compatibility_layers/posix/px_cond_wait.c new file mode 100644 index 00000000..120adfbd --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_cond_wait.c @@ -0,0 +1,135 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_cond_wait PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall block on a condition variable. They shall be */ +/* called with mutex locked by the calling thread or undefined behavior*/ +/* results. These functions atomically release the mutex and cause the */ +/* calling thread to block on the condition variable cond; atomically */ +/* here means atomically with respect to access by another thread to */ +/* the mutex and then the request for semaphore. */ +/* */ +/* Upon successful return, the mutex shall have been locked and shall */ +/* be owned by the calling thread. */ +/* */ +/* When using condition variables there is always a Boolean predicate */ +/* involving shared variables associated with each condition wait that */ +/* is true if the thread should proceed. Spurious wakeups from the */ +/* pthread_cond_timedwait or pthread_cond_wait functions may occur. */ +/* Since the return from pthread_cond_timedwait or pthread_cond_wait */ +/* does not imply anything about the value of this predicate, the */ +/* predicate should be re-evaluated upon such return. The effect of */ +/* using more than one mutex for concurrent pthread_cond_timedwait or */ +/* pthread_cond_wait operations on the same condition variable is */ +/* undefined; that is, a condition variable becomes bound to a unique */ +/* mutex when a thread waits on the condition variable, and this */ +/* (dynamic) binding shall end when the wait returns. */ +/* */ +/* INPUT */ +/* */ +/* cond condition variable */ +/* mutex mutex to be associated with condition */ +/* variable */ +/* */ +/* OUTPUT */ +/* */ +/* OK if succesfull */ +/* ERROR in case of any error */ +/* */ +/* CALLS */ +/* */ +/* pthread_mutex_unlock unlocks the mutex held by the caller */ +/* tx_semaphore_get try to get sempaphore internal to cond */ +/* tx_semaphore_prioritize prioritize all suspended pthreads */ +/* pthread_mutex_lock lock the mutex */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + +TX_SEMAPHORE *semaphore_ptr; +UINT status; +UINT old_threshold,dummy; +TX_THREAD *thread; + + /* Find the current thread. */ + thread = tx_thread_identify(); + + /* Raise its preemption threshold so it does not get descheduled. */ + tx_thread_preemption_change(thread,0,&old_threshold); + + pthread_mutex_unlock(mutex); + + semaphore_ptr = (&( cond->cond_semaphore )); + + status = tx_semaphore_get(semaphore_ptr, TX_WAIT_FOREVER); + + /* Restore original preemption threshold. */ + tx_thread_preemption_change(thread, old_threshold, &dummy); + + + if ( status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + status = tx_semaphore_prioritize(semaphore_ptr); + + if ( status != TX_SUCCESS) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + pthread_mutex_lock(mutex); + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_error.c b/utility/rtos_compatibility_layers/posix/px_error.c new file mode 100644 index 00000000..45fc4846 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_error.c @@ -0,0 +1,113 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_error_handler PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is invoked whenever an error is encountered */ +/* in the POSIX code. */ +/* */ +/* INPUT */ +/* */ +/* error_code Error code to handle */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_error_handler(ULONG error_code) +{ + while (error_code) { ; } +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_internal_error PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is invoked whenever an error is encountered */ +/* in the POSIX code. */ +/* */ +/* INPUT */ +/* */ +/* error_code Error code to handle */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_internal_error(ULONG error_code) +{ + while (error_code) { ; } +} diff --git a/utility/rtos_compatibility_layers/posix/px_in_thread_context.c b/utility/rtos_compatibility_layers/posix/px_in_thread_context.c new file mode 100644 index 00000000..d0bd888b --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_in_thread_context.c @@ -0,0 +1,107 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_in_thread_context PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines if the system is currently in "thread" */ +/* context, i.e. not timer routine, not ISR, not idling. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE | TX_FALSE */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +ULONG posix_in_thread_context(VOID) +{ + /* External variables, defined within ThreadX, needed here. */ + extern TX_THREAD * _tx_thread_current_ptr; + extern ULONG _tx_thread_system_state; +#ifndef TX_TIMER_PROCESS_IN_ISR + extern TX_THREAD _tx_timer_thread; +#endif + + /* Return TX_FALSE if any of the following are true: + - we are in the scheduling loop (not in a thread); + - we are in an ISR + - we are in a timer routine + Return TX_TRUE otherwise (we are in a thread.) + */ + + if (_tx_thread_system_state == TX_INITIALIZE_IN_PROGRESS) + { + + /* We are calling from initialization, return TRUE. */ + return(TX_TRUE); + } + else if ((!_tx_thread_current_ptr) /* Not in a thread */ + || (_tx_thread_system_state) /* In an ISR */ +#ifndef TX_TIMER_PROCESS_IN_ISR + /* Timer routine */ + || (_tx_thread_current_ptr == &_tx_timer_thread) +#endif + ) + + { + /* We are NOT in thread (thread) context. */ + return (TX_FALSE); + } + else + { + /* We ARE in thread (thread) context. */ + return (TX_TRUE); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_int.h b/utility/rtos_compatibility_layers/posix/px_int.h new file mode 100644 index 00000000..a4048c8c --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_int.h @@ -0,0 +1,213 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** POSIX Compliancy Wrapper (POSIX) */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKP DEFINITIONS RELEASE */ +/* */ +/* px_int.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc.needed to */ +/* implement the Evacuation Kit for POSIX Users (POSIX) */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef _TX_PX_INT_H +#define _TX_PX_INT_H + +#include "string.h" + +/* Define several ThreadX equates for use inside of POSIX. */ +#define TX_INITIALIZE_IN_PROGRESS 0xF0F0F0F0UL +#define TX_INITIALIZE_ALMOST_DONE 0xF0F0F0F1UL + +/* Include necessary definition for memory related routines(from tx_byt.c). */ +#define TX_BYTE_BLOCK_FREE 0xFFFFEEEEUL +#define TX_BYTE_BLOCK_ALLOC 0xAAAAAAAAUL +#define TX_BYTE_POOL_ID 0x42595445UL + +/* Threadx min and max priority */ +#define TX_HIGHEST_PRIORITY 1 +#define TX_LOWEST_PRIORITY 31 + +#define PX_HIGHEST_PRIORITY 31 +#define PX_LOWEST_PRIORITY 1 + +/************ Extern Variables **************/ +extern TX_THREAD * _tx_thread_current_ptr; +extern TX_THREAD * _tx_thread_execute_ptr; + + + +/* declares posix objects in the px_pth_init.c file */ +#ifdef PX_OBJECT_INIT +#define PX_OBJECT_DECLARE +#else +#define PX_OBJECT_DECLARE extern +#endif +/**************************************************************************/ +/* Global Definitions */ +/**************************************************************************/ + +/* The ThreadX work queue for the POSIX System Manager. */ +PX_OBJECT_DECLARE TX_QUEUE posix_work_queue; + +/* Define the thread for the System Manager functionality. */ +PX_OBJECT_DECLARE TX_THREAD posix_system_manager; + + +/**************************************************************************/ +/* Local definitions */ +/**************************************************************************/ + +/* Define a byte pool control block for the heap memory used + by POSIX. */ + +PX_OBJECT_DECLARE TX_BYTE_POOL posix_heap_byte_pool; + +/* Define a static pool of pthread Control Blocks (TCB). If more pthreades are + required the constant PTHREAD_THREADS_MAX (in tx_posix.h) may be modified. */ +PX_OBJECT_DECLARE POSIX_TCB ptcb_pool[PTHREAD_THREADS_MAX]; + +#if POSIX_MAX_QUEUES!= 0 +/* Define a static pool of queues.If more pthread message queues are required + the constant POSIX_MAX_QUEUES (in tx_posix.h) may be modified. */ +PX_OBJECT_DECLARE POSIX_MSG_QUEUE posix_queue_pool[POSIX_MAX_QUEUES]; +/* Define a queue attribute. */ +PX_OBJECT_DECLARE struct mq_attr posix_qattr_default; +#endif + +#if SEM_NSEMS_MAX != 0 +/* Define a static pool of semaphores. If more pthread semaphores required the + constant SEM_NSEMS_MAX (in tx_posix.h) may be modified. */ +PX_OBJECT_DECLARE sem_t posix_sem_pool[SEM_NSEMS_MAX]; + +#endif + +/* Define a default pthread attribute. */ +PX_OBJECT_DECLARE pthread_attr_t posix_default_pthread_attr; + +/* Define a default mutex attribute. */ +PX_OBJECT_DECLARE pthread_mutexattr_t posix_default_mutex_attr; + + + +/* Define a temporary posix errno. */ + +PX_OBJECT_DECLARE unsigned int posix_errno; + + +/**************************************************************************/ +/* Local prototypes */ +/**************************************************************************/ +/* Define Evacuation Kit for POSIX function prototypes. */ + +INT posix_get_pthread_errno(pthread_t ptid); + +POSIX_MSG_QUEUE *posix_mq_create ( const CHAR * mq_name, + struct mq_attr * msgq_attr); + +POSIX_MSG_QUEUE *posix_find_queue(const CHAR * mq_name); + +POSIX_MSG_QUEUE *posix_get_new_queue(ULONG maxnum); + +ULONG posix_arrange_msg( TX_QUEUE * Queue, ULONG * pMsgPrio ); + +ULONG posix_priority_search(mqd_t msgQId ,ULONG priority); + +VOID posix_queue_init(VOID); + +VOID posix_qattr_init(VOID); + +VOID posix_pthread_init(VOID); + +struct mq_des *posix_get_queue_des(POSIX_MSG_QUEUE * q_ptr); + +VOID posix_reset_queue(POSIX_MSG_QUEUE * q_ptr); + +VOID posix_memory_release(VOID * memory_ptr); + +VOID posix_internal_error(ULONG error_code); + +VOID posix_error_handler(ULONG error_code); + +INT posix_memory_allocate(ULONG size, VOID **memory_ptr); + +INT posix_queue_delete(POSIX_MSG_QUEUE * q_ptr); + +VOID posix_putback_queue(TX_QUEUE * qid); + +sem_t *posix_find_sem(const CHAR * name); + +VOID posix_set_sem_name(sem_t * sem, CHAR *name); + +TX_SEMAPHORE *posix_get_new_sem(VOID); + +VOID posix_sem_reset(sem_t *sem); + +ULONG posix_in_thread_context(VOID); + +VOID posix_reset_pthread_t(POSIX_TCB *ptcb); + +TX_THREAD *posix_tid2thread(pthread_t ptid); + +POSIX_TCB *posix_tid2tcb(pthread_t ptid); + +pthread_t posix_thread2tid(TX_THREAD *thread_ptr); + +POSIX_TCB *posix_thread2tcb(TX_THREAD *thread_ptr); + +TX_THREAD *posix_tcb2thread (POSIX_TCB *pthread_ptr); + +VOID posix_thread_wrapper(ULONG pthr_ptr); + +VOID set_default_pthread_attr(pthread_attr_t *attr); + +VOID set_default_mutexattr(pthread_mutexattr_t *attr); + +INT posix_allocate_pthread_t(POSIX_TCB **ptcb_ptr); + +VOID posix_copy_pthread_attr(POSIX_TCB *pthread_ptr,pthread_attr_t *attr); + +VOID posix_destroy_pthread(POSIX_TCB *pthread_ptr, VOID *value_ptr); + +VOID posix_do_pthread_delete(POSIX_TCB *pthread_ptr, VOID *value_ptr); + +VOID posix_system_manager_entry(ULONG input); + +INT posix_set_pthread_errno(ULONG errno_set); + +ULONG posix_abs_time_to_rel_ticks(struct timespec *abs_timeout); + +#endif diff --git a/utility/rtos_compatibility_layers/posix/px_internal_signal_dispatch.c b/utility/rtos_compatibility_layers/posix/px_internal_signal_dispatch.c new file mode 100644 index 00000000..7d6c5ac2 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_internal_signal_dispatch.c @@ -0,0 +1,167 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* internal_signal_dispatch PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Signal handler thread. */ +/* */ +/* INPUT */ +/* */ +/* id Signal */ +/* */ +/* OUTPUT */ +/* */ +/* none */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Generic error Handler */ +/* tx_thread_identify */ +/* tx_event_flags_set */ +/* tx_thread_resume */ +/* posix_destroy_pthread */ +/* tx_thread_suspend */ +/* */ +/* CALLED BY */ +/* */ +/* Internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +void internal_signal_dispatch(ULONG id) +{ + +TX_INTERRUPT_SAVE_AREA + +POSIX_TCB *signal_thread; +POSIX_TCB *target_thread; +VOID (*handler)(int); + + + /* Determine if the desired signal is valid. */ + if (id > SIGRTMAX) + { + + /* System error! */ + posix_internal_error(444); + return; + } + + /* Pickup signal thread. */ + signal_thread = (POSIX_TCB *) tx_thread_identify(); + + /* Is it non-NULL? */ + if (!signal_thread) + { + + /* System error! */ + posix_internal_error(444); + return; + } + + /* Pickup target thread. */ + target_thread = signal_thread -> signals.base_thread_ptr; + + /* Pickup signal handler function pointer. */ + handler = target_thread -> signals.signal_func[id]; + + /* See if there is a signal handler setup for this signal. */ + if (handler) + { + + /* Yes, there is a signal handler - call it! */ + (handler)((int) id); + } + + /* Set the event flag corresponding the signal. */ + tx_event_flags_set(&(target_thread -> signals.signal_event_flags), (((ULONG) 1) << id), TX_OR); + + /* Ensure the flag is left in a clear state. */ + tx_event_flags_set(&(target_thread -> signals.signal_event_flags), ~(((ULONG) 1) << id), TX_AND); + + /* Now we need to clear this signal and terminate this signal handler thread. */ + + /* Disable interrupts. */ + TX_DISABLE + + /* Clear this signal from the pending list. */ + target_thread -> signals.signal_pending.signal_set = target_thread -> signals.signal_pending.signal_set & ~(((unsigned long) 1) << id); + + /* Decrement the signal nesting count. */ + target_thread -> signals.signal_nesting_depth--; + + /* Is this the last nested signal leaving? */ + if (target_thread -> signals.signal_nesting_depth == 0) + { + + /* Clear the top signal thread link and resume the target thread. */ + target_thread -> signals.top_signal_thread = NULL; + + /* Restore interrupts. */ + TX_RESTORE + + /* Resume the target thread. */ + tx_thread_resume((TX_THREAD *) target_thread); + } + else + { + + /* Otherwise, there are more signal threads still active. */ + + /* Setup the new top signal thread pointer. */ + target_thread -> signals.top_signal_thread = signal_thread -> signals.next_signal_thread; + + /* Restore interrupts. */ + TX_RESTORE + + /* Resume the signal handler thread. */ + tx_thread_resume((TX_THREAD *) signal_thread -> signals.next_signal_thread); + } + + /* Now we need to mark this signal thread for destruction. */ + posix_destroy_pthread(signal_thread,(VOID *) 0); + + /* Self-suspend the current signal thread. */ + tx_thread_suspend((TX_THREAD *) signal_thread); +} diff --git a/utility/rtos_compatibility_layers/posix/px_memory_allocate.c b/utility/rtos_compatibility_layers/posix/px_memory_allocate.c new file mode 100644 index 00000000..1b1034a2 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_memory_allocate.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_memory_allocate PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to obtain the specified amount of memory */ +/* from the POSIX heap. */ +/* */ +/* INPUT */ +/* */ +/* size Number of bytes in the pool */ +/* memory_ptr Pointer to memory ptr variable*/ +/* */ +/* OUTPUT */ +/* */ +/* ERROR If error occurs */ +/* retval Return value */ +/* */ +/* CALLS */ +/* */ +/* tx_byte_allocate Allocate from the pool */ +/* posix_internal_error Generic posix error */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT posix_memory_allocate(ULONG size, VOID **memory_ptr) +{ + +INT retval; + + /* Init in case we fail. */ + *memory_ptr = (VOID *)0; + + /* Force all alignments to long word boundaries to be safe. */ + if (size & 0x03) + { + /* Bump size up to next 4 byte boundary. */ + size = ((size + 0x03) & ~0x03); + } + /* Attempt to allocate the desired memory from the POSIX heap. + Do not wait - if memory isn't available, flag an error. */ + retval = tx_byte_allocate((TX_BYTE_POOL *)&posix_heap_byte_pool, memory_ptr, + size, TX_NO_WAIT); + + /* Make sure the memory was obtained successfully. */ + if (retval) + { + /* Error obtaining memory. */ + posix_internal_error(555); + /* return error. */ + return(ERROR); + } + /* Return to caller. */ + return(retval); +} diff --git a/utility/rtos_compatibility_layers/posix/px_memory_release.c b/utility/rtos_compatibility_layers/posix/px_memory_release.c new file mode 100644 index 00000000..19ea8a27 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_memory_release.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_memory_release PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to return the specified memory region back */ +/* into the POSIX heap. */ +/* */ +/* INPUT */ +/* */ +/* memory_ptr Memory pointer to return */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* tx_byte_release Release the memory */ +/* posix_internal_error internal error handler */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_memory_release(VOID * memory_ptr) +{ + + /* Check if memory_ptr is part of the POSIX byte pool, + * if not just return */ + if (((CHAR *)memory_ptr >= + (CHAR *)&posix_heap_byte_pool.tx_byte_pool_start) || + ((CHAR *)memory_ptr <= + (CHAR *)posix_heap_byte_pool.tx_byte_pool_start + + posix_heap_byte_pool.tx_byte_pool_size)) { + tx_byte_release(memory_ptr); + } + + /* Return to caller. */ + return; +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c b/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c new file mode 100644 index 00000000..5f8a42c4 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c @@ -0,0 +1,178 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_arrange_msg PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* arrange messages from the queue */ +/* */ +/* INPUT */ +/* */ +/* Queue queue descriptor */ +/* *pMsgPrio If not NULL, priority of message */ +/* */ +/* OUTPUT */ +/* */ +/* OK Always return successful */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +ULONG posix_arrange_msg( TX_QUEUE *Queue, ULONG *pMsgPrio ) +{ + + ULONG* Qread; /* to store read ptr of the queue */ + ULONG* temp_q = TX_NULL; /* temp storage for the message pointer */ + ULONG numMsgs; /* no of messages queued */ + ULONG msg; /* temp variable for thr for loop */ + ULONG priority; /* priority of the message */ + ULONG maxPrio; /* max. priority of the messages in queue*/ + ULONG number2; /* messages */ + ULONG minNo; /* oldest message in the same priority */ + ULONG swap; /* temp.variable for the swapping of the */ + /* messages */ + + /* initialize the priority to the lowest priority. */ + maxPrio = 0; + minNo=0; + + /* Copy read pointer to the temporary variable. */ + Qread = Queue -> tx_queue_read; + + /* Copy no. of messages in the queue to the temporary variable. */ + numMsgs = Queue -> tx_queue_enqueued; + + if( numMsgs == 0 ) + return(OK); + + for( msg = 0; msg < numMsgs; msg ++) + { + + /* Advance Qread by two pointers to read the priority of the message. */ + Qread = Qread + 2 ; + + /* Priority of the message queued. */ + priority = *Qread; + + /* check with maxpriority. */ + if( priority > maxPrio ) + { + /* copy read pointer to temporary buffer. */ + temp_q = Qread-2; + /* increment read pointer to point to order. */ + Qread++; + + /* copy FIFO order to the message */ + minNo = *Qread; + /* Found higher priority message. */ + maxPrio = priority; + + Qread++; + } + + /* if more than one same priority messages are in the queue + then check if this the oldest one. */ + else if ( priority == maxPrio ) + { + /* increment read pointer to point to read FIFO order */ + Qread++; + + /* copy number to the local varialble. */ + number2 = *Qread; + Qread++; + /* find the oldest of the messages in this priority level. */ + if( number2 < minNo ) + { + /* founder older one */ + minNo = number2; + /* copy read pointer to temporary buffer. */ + temp_q = Qread - 4; + } + + } + + else + Qread = Qread + 2; + + /* Determine if we are at the end. */ + if ( Qread >= Queue ->tx_queue_end) + + /* Yes, wrap around to the beginning. */ + Qread = Queue -> tx_queue_start; + } + + /* All messages checked temp holds address of highest priority message and + maxPrio holds the highest priority*/ + + if( pMsgPrio != NULL ) + { + /* copy message priority. */ + *pMsgPrio = maxPrio; + } + + /* Get the current queue read pointer */ + Qread = Queue -> tx_queue_read; + + /* if(*pMsgPrio != *(Qread + 2) || minNo < *(Qread + 3))*/ + { + /* Swap the messages. */ + for ( msg = 0; msg < 4; msg++) + { + + swap = *temp_q; + *temp_q = *Qread; + *Qread = swap; + temp_q++; + Qread++; + } + } + + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_attr_init.c b/utility/rtos_compatibility_layers/posix/px_mq_attr_init.c new file mode 100644 index 00000000..78aa23b3 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_attr_init.c @@ -0,0 +1,80 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_qattr_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the mq_attr structure a ThreadX queue */ +/* into the POSIX variable length message queue pool. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_qattr_init(VOID) +{ + +struct mq_attr * q_attr; + + q_attr = &(posix_qattr_default); + + /* This queue is not currently in use. */ + q_attr->mq_flags = MQ_FLAGS; + q_attr->mq_maxmsg = MQ_MAXMSG; + q_attr->mq_msgsize = MQ_MSGSIZE; + return; +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_close.c b/utility/rtos_compatibility_layers/posix/px_mq_close.c new file mode 100644 index 00000000..ab5d4b2d --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_close.c @@ -0,0 +1,146 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* mq_close PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* close a message queue */ +/* */ +/* INPUT */ +/* */ +/* mqdes message queue descriptor */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Generic error handler */ +/* tx_byte_release Release bytes */ +/* tx_thread_identify Returns currently running thread */ +/* posix_queue_delete Deletes specific queue */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT mq_close(mqd_t mqdes) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_QUEUE * Queue; +POSIX_MSG_QUEUE * q_ptr; + + /* Assign a temporary variable for clarity. */ + Queue = &(mqdes->f_data->queue); + q_ptr = (POSIX_MSG_QUEUE * )Queue; + + /* First, check for an invalid queue pointer. */ + if ( (!q_ptr) || ( (q_ptr -> px_queue_id) != PX_QUEUE_ID)) + { + /* Queue pointer is invalid, return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + return(ERROR); + } + + /* If we are not calling this routine from a thread context. */ + if (!(tx_thread_identify())) + { + /* return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + return(ERROR); + } + + /* Free the system resource allocated by open call. */ + if( tx_byte_release( ( VOID *) mqdes )) + { + /* return generic error. */ + posix_internal_error(100); + + /* Return error. */ + return(ERROR); + } + + /* Disable interrupts. */ + TX_DISABLE + + /* Decrement ref count. */ + if( q_ptr->open_count ) + + q_ptr ->open_count--; + + /* Destroy the basic Queue is the ref count is zero and + it is marked by unlink. */ + if( (! q_ptr ->open_count ) && (q_ptr->unlink_flag == TX_TRUE)) + { + /* Free the system resource allocated by open call. */ + if( posix_queue_delete( q_ptr )) + { + + /* Restore interrupts. */ + TX_RESTORE + + /* return generic type. */ + posix_internal_error(100); + + /* Return error. */ + return(ERROR); + } + } + /* Restore interrupts. */ + TX_RESTORE + + /* Return OK. */ + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_create.c b/utility/rtos_compatibility_layers/posix/px_mq_create.c new file mode 100644 index 00000000..6b4f10eb --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_create.c @@ -0,0 +1,225 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_mq_create PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This subroutine creates and initializes a message queue */ +/* As the message length is user defined, message pointer and message */ +/* length is stored in a ThreadX queue(instead of the actual message) */ +/* The actual message is stored in a dedicated byte pool for the */ +/* queue */ +/* */ +/* */ +/* INPUT */ +/* */ +/* mq_name name of the Queue */ +/* msgq_attr Pointer to mq_attr structure */ +/* */ +/* OUTPUT */ +/* */ +/* posix_q If success */ +/* NULL If failure */ +/* */ +/* CALLS */ +/* */ +/* posix_in_thread_context Make sure caller is thread */ +/* tx_queue_create to create a ThreadX Queue */ +/* posix_internal_error Generic error Handler */ +/* posix_memory_allocate to create a byte pool */ +/* tx_queue_delete to delete the queue */ +/* posix_putback_queue to delete the queue */ +/* tx_byte_pool_create to create a byte pool */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +POSIX_MSG_QUEUE * posix_mq_create (const CHAR * mq_name, + struct mq_attr * msgq_attr) +{ + +TX_INTERRUPT_SAVE_AREA + +POSIX_MSG_QUEUE *posix_q; +UINT temp1; +VOID *bp; +INT retval; +ULONG size; +TX_QUEUE *TheQ; + + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + + /* return error. */ + return ((POSIX_MSG_QUEUE *)ERROR); + } + /* Disable interrupts.*/ + TX_DISABLE + + /* Get a new queue from the POSIX queue pool. */ + /* Make sure we have enough space for the size. */ + + posix_q = posix_get_new_queue(msgq_attr->mq_maxmsg); + + /* Make sure we actually got a queue. */ + if (!posix_q) + { + /* Restore interrupts. */ + TX_RESTORE + + /* User configuration error - not enough memory. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + return(TX_NULL); + } + + /* Now create a ThreadX message queue. + to store only the message pointer and message length. */ + temp1 = tx_queue_create((&(posix_q->queue)), + (CHAR *)mq_name, + TX_4_ULONG, + posix_q->storage, + (msgq_attr->mq_maxmsg * 16)); + + /* Make sure it worked. */ + if (temp1 != TX_SUCCESS) + { + /*. Return generic error. */ + posix_internal_error(188); + + /* Restore interrupts. */ + TX_RESTORE + + /* Return ERROR. */ + return(TX_NULL); + } + /* Restore no. of maximum messages. */ + posix_q->q_attr.mq_maxmsg = msgq_attr->mq_maxmsg; + + /* Restore maximum message length. */ + posix_q->q_attr.mq_msgsize = msgq_attr->mq_msgsize; + + /* Flags are stored in que descriptor structure and + not in mq_att structure. */ + + /* Create a byte pool for the queue. + Determine how much memory we need to store all messages in this queue. + 11 bytes are added to counter overhead as well as alignment problem if any. */ + size = ( ((msgq_attr->mq_maxmsg) + 1) * (msgq_attr->mq_msgsize + 11) ); + + if(size < 100) + size = 100; + + /* Now attempt to allocate that much memory for the queue. */ + + retval = posix_memory_allocate(size,&bp); + + /* Make sure we obtained the memory we requested. */ + if (retval) + { + /* Created queue Control block, got memory to store message pointers + and lengths which means that created a fixed length message queue but + not enough memory to store actual messages. */ + + /* Delete the queue. */ + + /* Assign a temporary variable for clarity. */ + TheQ = (TX_QUEUE * )posix_q; + retval = tx_queue_delete(TheQ); + + /* Make sure the queue was deleted. */ + if (retval != TX_SUCCESS) + { + /* Return generic error. */ + posix_internal_error(799); + + /* Restore interrupts. */ + TX_RESTORE + + /* Return ERROR. */ + return(TX_NULL); + } + /* Put the queue back into the POSIX queue pool. */ + posix_putback_queue(TheQ); + + /* User configuration error - not enough memory. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + TX_RESTORE; + + /* Return ERROR. */ + return(TX_NULL); + } + /* Create a ThreadX byte pool that will provide memory needed by the queue. */ + retval = tx_byte_pool_create((&(posix_q->vq_message_area)), "POSIX Queue", + bp, size); + + /* Make sure the byte pool was created successfully. */ + if (retval) + { + /* Error creating byte pool. */ + posix_internal_error(9999); + + /* Restore interrupts. */ + TX_RESTORE + + /* Return ERROR.*/ + return(TX_NULL); + } + + posix_q->name = (CHAR*) mq_name; + + /* Restore interrupts. */ + TX_RESTORE + + /* All done. */ + return(posix_q); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_find_queue.c b/utility/rtos_compatibility_layers/posix/px_mq_find_queue.c new file mode 100644 index 00000000..b40cde38 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_find_queue.c @@ -0,0 +1,113 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_find_queue PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine returns queue descriptor indicating that name of */ +/* in the message queue.exists. */ +/* */ +/* INPUT */ +/* */ +/* const char * mq_name Name of the message queue */ +/* */ +/* OUTPUT */ +/* */ +/* q_ptr If successful */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +POSIX_MSG_QUEUE * posix_find_queue(const CHAR *mq_name) +{ + +POSIX_MSG_QUEUE *q_ptr; +ULONG index; +ULONG match; +CHAR *dummy_name; +CHAR *dummy_queue_name; +ULONG namelength; + + q_ptr = (POSIX_MSG_QUEUE*)NULL; + + /* For checking the name. */ + for(index = 0,q_ptr = posix_queue_pool;index < POSIX_MAX_QUEUES ;index ++,q_ptr ++) + { + /* Assume the worst case. */ + match = TX_FALSE; + if(q_ptr->in_use == TX_TRUE) + { + dummy_queue_name = q_ptr->name; + for(namelength = 0 ,dummy_name = (CHAR *) mq_name ; namelength < PATH_MAX ; + namelength ++, dummy_name++,dummy_queue_name ++) + { + /* Copy name. */ + if (*dummy_name == *dummy_queue_name) + { + /* End of the string. */ + if(*dummy_name == '\0') + { + match = TX_TRUE; + break; + } + }/* Copy name. */ + else + break; + } + } + if(match==TX_TRUE) + break; + } + /* For each message queue. */ + if(match==TX_TRUE) + return(q_ptr); + /* Returns NULL if match not found. */ + q_ptr = (POSIX_MSG_QUEUE*)NULL; + return (q_ptr); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_get_new_queue.c b/utility/rtos_compatibility_layers/posix/px_mq_get_new_queue.c new file mode 100644 index 00000000..bc907840 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_get_new_queue.c @@ -0,0 +1,121 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_get_new_queue PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to build a ThreadX message queue */ +/* for variable length message queues */ +/* */ +/* INPUT */ +/* */ +/* maxnum Number of queue entries */ +/* */ +/* OUTPUT */ +/* */ +/* q_ptr Pointer to posix queue */ +/* */ +/* CALLS */ +/* */ +/* posix_memory_allocate Memory allocate */ +/* posix_memory_release Memory free */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +POSIX_MSG_QUEUE * posix_get_new_queue(ULONG maxnum) +{ + +ULONG i; +POSIX_MSG_QUEUE *q_ptr; +VOID *bp; +INT retval; +ULONG size; + + + /* Determine how much memory we need for the queue. + The queue holds "maxnum" entries; each entry is 2 ULONG. */ + size = (maxnum * (TX_4_ULONG * sizeof(ULONG))); + + /* Now attempt to allocate memory for the queue. */ + retval = posix_memory_allocate(size, &bp); + + /* Make sure we obtained the memory we requested. */ + if (retval) + { + return((POSIX_MSG_QUEUE *)NULL); + } + /* Loop through the list of queues - */ + /* try to find one that is not "in use". */ + /* Search the queue pool for an available queue. */ + for (i = 0, q_ptr = &(posix_queue_pool[0]); + i < POSIX_MAX_QUEUES; + i++, q_ptr++) + { + /* Make sure the queue is not "in use". */ + if (q_ptr->in_use == TX_FALSE) + { + /* This queue is now in use. */ + q_ptr->in_use = TX_TRUE; + + /* Point to allocated memory. */ + q_ptr->storage = bp; + + q_ptr->px_queue_id = PX_QUEUE_ID; + + /* Stop searching. */ + break; + } + } + /* If we didn't find a free queue, free the allocated memory. */ + if ( i >= POSIX_MAX_QUEUES) + { + posix_memory_release(bp); + return((POSIX_MSG_QUEUE *)0); + } + /* Return home. */ + return(q_ptr); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_get_queue_desc.c b/utility/rtos_compatibility_layers/posix/px_mq_get_queue_desc.c new file mode 100644 index 00000000..4946b851 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_get_queue_desc.c @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_get_queue_desc PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns a message queue descriptor pointer of valid */ +/* message queue */ +/* */ +/* INPUT */ +/* */ +/* q_ptr message queue pointer */ +/* */ +/* OUTPUT */ +/* */ +/* q_des message queue descriptor */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Returns a Generic error */ +/* tx_byte_allocate Allocates bytes */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +struct mq_des * posix_get_queue_des(POSIX_MSG_QUEUE * q_ptr) +{ + +struct mq_des *q_des = NULL; +VOID *bp; + + /* allocate the system resource allocated by open call. */ + if( tx_byte_allocate((TX_BYTE_POOL *)&posix_heap_byte_pool, &bp, + sizeof(struct mq_des), TX_NO_WAIT)) + { + /* return generic error. */ + posix_internal_error(100); + /* Return error. */ + return((struct mq_des *)ERROR); + } + q_des = (struct mq_des *)bp; + /* Get message queue data to mq_des structure. */ + q_des->f_data = q_ptr; + return(q_des); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_open.c b/utility/rtos_compatibility_layers/posix/px_mq_open.c new file mode 100644 index 00000000..c030218b --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_open.c @@ -0,0 +1,202 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* mq_open PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine establishes connection between a named message queue */ +/* and the calling a thread */ +/* */ +/* INPUT */ +/* */ +/* mqName name of the queue to open. */ +/* oflags O_RDONLY, O_WRONLY, O_RDWR, or O_CREAT, */ +/* O_EXCEL,O_NONBLOCK. */ +/* extra optional parameters. */ +/* */ +/* OUTPUT */ +/* */ +/* queue_des If successful */ +/* ERROR If fails */ +/* */ +/* CALLS */ +/* */ +/* posix_find_queue find queue of given name */ +/* posix_mq_create create a queue */ +/* posix_get_queue_des gets a queue-descriptor for Queue */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +mqd_t mq_open(const CHAR * mqName, ULONG oflags,...) +{ + +POSIX_MSG_QUEUE *posix_queue; +struct mq_des *queue_des; +struct mq_attr *q_attr; +mode_t mode; +va_list create_queue; +ULONG len; +ULONG temp1; + + len = strlen(mqName); + if(len > PATH_MAX) + { + /* Return error. */ + posix_errno = ENAMETOOLONG; + posix_set_pthread_errno(ENAMETOOLONG); + + /*. Return error. */ + return((struct mq_des *)ERROR); + } + switch(oflags & 0xFF00) + { + case O_CREAT: + + case (O_EXCL | O_CREAT): + + va_start(create_queue, oflags); + mode = va_arg(create_queue, mode_t); + mode = mode; /* just to keep the complier happy */ + q_attr = va_arg(create_queue, struct mq_attr *); + va_end(create_queue); + + /* Check for valid messages and its size. */ + if(!q_attr || q_attr->mq_maxmsg > MQ_MAXMSG || q_attr->mq_msgsize > MQ_MSGSIZE) + { + /* return POSIX error.for invalid oflag. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + /* return error. */ + return ((struct mq_des *)ERROR); + } + + /* Check if name is exist. NULL if successful. */ + if(posix_queue = posix_find_queue(mqName)) + { + if(posix_queue->unlink_flag == TX_TRUE) + { + /* return POSIX error. */ + posix_errno = ENOENT; + posix_set_pthread_errno(ENOENT); + /* return error. */ + return ((struct mq_des *)ERROR); + } + + /* Set Posix error if name exist. */ + posix_errno = EEXIST; + posix_set_pthread_errno(EEXIST); + /* return error */ + return((struct mq_des *)ERROR); + } + + /* If q_attr is NULL then the default attributes of the struct + mq_attr are used */ + if(q_attr == NULL) + { + q_attr = &(posix_qattr_default); + temp1 = q_attr->mq_maxmsg; + temp1= temp1 ; /* Just to keep complier happy */ + } + + /* Create a queue which returns posix queue if successful and + NULL if fails. */ + if(!(posix_queue = posix_mq_create(mqName, q_attr))) + { + + /* posix_errno is filled up in mq_create. */ + return((struct mq_des *)ERROR); + } + /* open count incremented by one. */ + posix_queue->open_count += 1; + break; + + case O_EXCL: + /* Check if name is exist. NULL if successful. */ + if(!(posix_queue = posix_find_queue(mqName))) + { + /* return POSIX error. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + /* return error. */ + return ((struct mq_des *)ERROR); + } + + return(OK); + + case O_RDONLY: + case O_WRONLY: + case O_RDWR: + case O_NONBLOCK: + /* Check if name is exist. NULL if successful. */ + if(posix_queue = posix_find_queue(mqName)) + { + if(posix_queue->unlink_flag == TX_TRUE) + { + /* return POSIX error. */ + posix_errno = ENOENT; + posix_set_pthread_errno(ENOENT); + /* return error. */ + return ((struct mq_des *)ERROR); + } + /* open count incremented by one. */ + posix_queue->open_count += 1; + } + break; + + default: + /* return POSIX error.for invalid oflag. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + /* return error. */ + return ((struct mq_des *)ERROR); + } + + queue_des = posix_get_queue_des(posix_queue); + /* Store the flags. */ + queue_des->f_flag = oflags; + return(queue_des); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_priority_search.c b/utility/rtos_compatibility_layers/posix/px_mq_priority_search.c new file mode 100644 index 00000000..64a82374 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_priority_search.c @@ -0,0 +1,104 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_priority_search PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine returns the no. of messages of the same priority */ +/* in the message queue. */ +/* */ +/* INPUT */ +/* */ +/* msgQId message queue ID */ +/* priority priority of the message */ +/* */ +/* OUTPUT */ +/* */ +/* order Returns the number of same priority messages.*/ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +ULONG posix_priority_search(mqd_t msgQId ,ULONG priority) +{ + +TX_QUEUE *queue; +POSIX_MSG_QUEUE *q_ptr; +ULONG order; +ULONG numMsgs; +UINT index; +ULONG *source; +ULONG msgp; + + queue = &(msgQId->f_data->queue); + q_ptr = (POSIX_MSG_QUEUE * )queue; + + /* No. of messages in the queue. */ + numMsgs = q_ptr -> queue.tx_queue_enqueued; + + /* retrieving the message pointer. */ + source = q_ptr->queue.tx_queue_read; + + /* check for same priority. */ + for(index = 0,order = 1;index <= numMsgs ;index++) + { + source += 2; + msgp = *source; + source += 2; + + if(source == q_ptr->queue.tx_queue_end) + source = q_ptr->queue.tx_queue_start; + + if(priority == msgp) + order += 1; + } + /* Returns the number of same priority messages. */ + return(order); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_putback_queue.c b/utility/rtos_compatibility_layers/posix/px_mq_putback_queue.c new file mode 100644 index 00000000..dcfb28d1 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_putback_queue.c @@ -0,0 +1,81 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_putback_queue PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function "puts back" a ThreadX queue into the POSIX */ +/* variable length message queue pool. */ +/* */ +/* INPUT */ +/* */ +/* qid Queue ID */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* posix_memory_putback Free memory */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_putback_queue(TX_QUEUE * qid) +{ + +POSIX_MSG_QUEUE * q_ptr; + + /* Convert TX_QUEUE into POSIX_QUEUE datatype. */ + q_ptr = MAKE_POSIX_QUEUE(qid); + + /* Free the queue's memory. */ + posix_memory_release(q_ptr->storage); + + /* This queue is no longer in use. */ + q_ptr->in_use = TX_FALSE; + return; +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_queue_delete.c b/utility/rtos_compatibility_layers/posix/px_mq_queue_delete.c new file mode 100644 index 00000000..1c55ab10 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_queue_delete.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_queue_delete PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* deletes a message queue */ +/* */ +/* INPUT */ +/* */ +/* q_ptr message queue pointer */ +/* */ +/* OUTPUT */ +/* */ +/* ERROR If fails */ +/* OK If successful */ +/* */ +/* CALLS */ +/* */ +/* tx_queue_delete Detectes a Queue */ +/* posix_internal_error Generic error */ +/* posix_reset queue Resets queue structure */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT posix_queue_delete(POSIX_MSG_QUEUE * q_ptr) +{ + +TX_QUEUE *queue; + + queue = &(q_ptr->queue); + + /* Delete the Threadx queue. */ + if(tx_queue_delete(queue)) + { + /* return generic error. */ + posix_internal_error(444); + /* return error. */ + return(ERROR); + } + + /* Release the queue back to the pool. */ + posix_reset_queue(q_ptr); + q_ptr = NULL; + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_queue_init.c b/utility/rtos_compatibility_layers/posix/px_mq_queue_init.c new file mode 100644 index 00000000..2bdf152b --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_queue_init.c @@ -0,0 +1,85 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_queue_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the POSIX's internal variable length */ +/* message queue pool. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_queue_init(VOID) +{ + +ULONG i; +POSIX_MSG_QUEUE *queue_ptr; + + for (i = 0, queue_ptr = &(posix_queue_pool[0]); + i < POSIX_MAX_QUEUES; + i++, queue_ptr++) + { + /* This queue is not currently in use.*/ + queue_ptr->in_use = TX_FALSE; + queue_ptr->name = ""; + queue_ptr->open_count = 0; + queue_ptr->storage = NULL; + queue_ptr->unlink_flag = TX_FALSE; + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_receive.c b/utility/rtos_compatibility_layers/posix/px_mq_receive.c new file mode 100644 index 00000000..4d930958 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_receive.c @@ -0,0 +1,264 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* mq_receive PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* */ +/* Receive a message from a message queue. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* mqdes message queue descriptor */ +/* *pMsg buffer to receive message */ +/* msgLen size of buffer, in bytes */ +/* *pMsgPrio If not NULL, return message priority */ +/* */ +/* OUTPUT */ +/* */ +/* temp1 no of bytes received */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Generic error handler */ +/* tx_queue_receive ThreadX queue receive */ +/* tx_byte_release Release bytes */ +/* posix_memory_allocate Allocate memory */ +/* tx_thread_identify Returns currently running thread */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +ssize_t mq_receive( mqd_t mqdes, VOID * pMsg, size_t msgLen, ULONG *pMsgPrio) +{ + +TX_QUEUE * Queue; +POSIX_MSG_QUEUE * q_ptr; +INT temp1, retval = ERROR; +ULONG wait_option,length_of_message, priority_of_message,mycount; +ULONG * my_ptr; +CHAR * this_ptr; +VOID * msgbuf1; +UCHAR * msgbuf2; +VOID * message_source; + + /* Assign a temporary variable for clarity. */ + Queue = &(mqdes->f_data->queue); + q_ptr = (POSIX_MSG_QUEUE * )mqdes->f_data; + + /* First, check for an invalid queue pointer. */ + if ((!q_ptr) || ( (q_ptr -> px_queue_id) != PX_QUEUE_ID)) + { + /* Queue pointer is invalid, return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + /* Return ERROR. */ + return(ERROR); + } + + if(((mqdes ->f_flag & O_RDONLY) != O_RDONLY ) && ((mqdes->f_flag & O_RDWR) != O_RDWR)) + { + /* Queue pointer is invalid, return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + return(ERROR); + } + + /* Check if message length provided is less q size provided while creation. */ + if( msgLen < q_ptr -> q_attr.mq_msgsize ) + { + /* Return appropriate error. */ + posix_errno = EMSGSIZE; + posix_set_pthread_errno(EMSGSIZE); + + /* Return error. */ + return(ERROR); + } + + /* User has indicated a wait is acceptable. */ + /* if a message is not immediately available. */ + /* If we are not calling this routine from a thread context. */ + if (!(tx_thread_identify())) + { + /* return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + /* Return ERROR. */ + return(ERROR); + } + if ( ( mqdes ->f_flag & O_NONBLOCK ) == O_NONBLOCK ) + wait_option = TX_NO_WAIT; + else + wait_option = TX_WAIT_FOREVER; + + + /* Try to get a message from the message queue. */ + /* Create a temporary buffer to get message pointer and message length. */ + temp1 = posix_memory_allocate((sizeof(ULONG)) * 4 , (VOID**)&msgbuf1); + if(temp1 != TX_SUCCESS ) + { + /* Return generic error. */ + posix_internal_error(100); + + /* Return error. */ + return(ERROR); + } + /* Arrange the messages in the queue as per the required priority. */ + temp1 = posix_arrange_msg( Queue, pMsgPrio ); + /* Receive the message */ + temp1 = tx_queue_receive(Queue, msgbuf1, wait_option); + /* Some ThreadX error codes map to posix error codes. */ + switch(temp1) + { + case TX_SUCCESS: + { + + /* All ok */ + temp1 = OK; + break; + } + + case TX_DELETED: + { + break; + } + + case TX_QUEUE_EMPTY: + { + if (wait_option == TX_NO_WAIT) + { + /* No message to receive while NO_WAIT option is set */ + posix_errno = EAGAIN; + posix_set_pthread_errno(EAGAIN); + + /* Return error */ + temp1 = ERROR; + return(temp1); + } + break; + } + case TX_QUEUE_ERROR: + case TX_PTR_ERROR: + { + /* Queue pointer is invalid, return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + temp1 = ERROR; + return(temp1); + } + + default: + { + /* should not come here but send the default error. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return error. */ + temp1 = ERROR; + return(temp1); + } + } + + /* Assign a variable for clarity. */ + my_ptr = ( ULONG *)msgbuf1; + + /* Retrieve Message pointer, message Length and message priority. */ + this_ptr = (CHAR *)(*my_ptr); + message_source = (VOID *)this_ptr; + length_of_message = *(++my_ptr); + priority_of_message = *(++my_ptr); + + /* Copy message into supplied buffer. */ + msgbuf2 = (UCHAR *)pMsg; + + /* Release memory after storing data into destination. */ + retval = tx_byte_release(msgbuf1); + + if( retval) + { + /* return generic error. */ + posix_internal_error(100); + + /* Return error. */ + return(ERROR); + } + + if ( temp1 == OK) + { + for (mycount = 0; ( (mycount < length_of_message) && (mycount < msgLen)); mycount++) + { + *(msgbuf2++) = *((UCHAR *)(this_ptr++)); + } + + temp1 = mycount; + } + + retval = tx_byte_release(message_source); + + if( retval) + { + /* return generic error. */ + posix_internal_error(100); + + /* Return error. */ + return(ERROR); + } + + /* Copy message priority */ + if (pMsgPrio) + { + *pMsgPrio = priority_of_message; + } + + /* All done */ + return(length_of_message); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_reset_queue.c b/utility/rtos_compatibility_layers/posix/px_mq_reset_queue.c new file mode 100644 index 00000000..06576222 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_reset_queue.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_reset_queue PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets a message queue structure */ +/* */ +/* INPUT */ +/* */ +/* q_ptr q_ptr */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* tx_byte_pool_delete Deletes byte pool */ +/* posix_internal_error Returns generic error */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_reset_queue(POSIX_MSG_QUEUE * q_ptr) +{ + /* Indicate this entry is not in use. */ + q_ptr->in_use = TX_FALSE; + + /* Reset thread name to NULL string. */ + q_ptr -> name = NULL; + + /* Reset open count. */ + q_ptr -> open_count = 0; + + /* Reset storage */ + q_ptr -> storage = NULL; + + /* Delete message area. */ + if (tx_byte_pool_delete(&(q_ptr ->vq_message_area))) + { + /* Internal error. */ + posix_internal_error(444); + } + /* Reset queue id. */ + q_ptr -> px_queue_id = 0; + + /* Reset Unlink Flag */ + q_ptr -> unlink_flag = TX_FALSE; +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_send.c b/utility/rtos_compatibility_layers/posix/px_mq_send.c new file mode 100644 index 00000000..f75e46ac --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_send.c @@ -0,0 +1,214 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* mq_send PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* The mq_send() function puts a message of size msg_len and pointed to*/ +/* by msg_ptr into the queue indicated by mqdes. The new message has a */ +/* priority of msg_prio. */ +/* The queue maintained is in priority order (priorities may range from*/ +/* 0 to MQ_PRIO_MAX), and in FIFO order within the same priority. */ +/* */ +/* INPUT */ +/* */ +/* mqdes Queue descriptor */ +/* msg_ptr Message pointer */ +/* msg_len length of message */ +/* msg_prio Priority of the message */ +/* */ +/* OUTPUT */ +/* */ +/* OK no of bytes received */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify returns currently running thread */ +/* tx_byte_allocate allocate memory */ +/* tx_queue_send ThreadX queue send */ +/* posix_priority_search search message for same priority */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT mq_send( mqd_t mqdes, const CHAR * msg_ptr, size_t msg_len, + ULONG msg_prio ) +{ + +TX_QUEUE *Queue; +UINT temp1; +POSIX_MSG_QUEUE *q_ptr; +VOID *bp; +UCHAR *source; +UCHAR *destination; +UCHAR *save_ptr; +ULONG mycount; +ULONG msg[4]; + + /* Assign a temporary variable for clarity. */ + Queue = &(mqdes->f_data->queue); + q_ptr = (POSIX_MSG_QUEUE * )mqdes->f_data; + + /* First, check for an invalid queue pointer. */ + if ( (!q_ptr) || ( (q_ptr -> px_queue_id) != PX_QUEUE_ID)) + { + /* Queue pointer is invalid, return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + return(ERROR); + } + /* Make sure if we're calling this routine from a ISR timeout + is set to zero. */ + if (!(tx_thread_identify())) + { + /* POSIX doesn't have error for this, hence give default. */ + posix_errno = EINTR ; + posix_set_pthread_errno(EINTR); + + /* Return ERROR. */ + return(ERROR); + } + + /* First, check for an invalid queue pointer. */ + if ( (!q_ptr) || ( (q_ptr->queue.tx_queue_id) != TX_QUEUE_ID)) + { + /* Queue descriptor is invalid, set appropriate error code. */ + posix_errno = EBADF ; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + return(ERROR); + } + if(((mqdes->f_flag & O_WRONLY) != O_WRONLY) && ((mqdes->f_flag & O_RDWR) != O_RDWR)) + { + /* Queue pointer is invalid, return appropriate error code. */ + posix_errno = EBADF; + posix_set_pthread_errno(EBADF); + + /* Return ERROR. */ + return(ERROR); + } + if( msg_prio > MQ_PRIO_MAX) + { + /* Return appropriate error. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + + /* Return error. */ + return(ERROR); + } + /* Check for an invalid source for message. */ + if (! msg_ptr) + { + /* POSIX doesn't have error for this, hence give default. */ + posix_errno = EINTR ; + posix_set_pthread_errno(EINTR); + + /* Return ERROR. */ + return(ERROR); + } + + /* Now check the length of message. */ + if ( msg_len > (q_ptr->q_attr.mq_msgsize ) ) + { + /* Return message length exceeds max length. */ + posix_errno = EMSGSIZE ; + posix_set_pthread_errno(EMSGSIZE); + + /* Return ERROR. */ + return(ERROR); + } + + /* Now try to allocate memory to save the message from the + queue's byte pool. */ + temp1 = tx_byte_allocate((TX_BYTE_POOL * )&(q_ptr->vq_message_area), &bp, + msg_len, TX_NO_WAIT); + + if (temp1 != TX_SUCCESS) + { + posix_internal_error(9999); + } + /* Got the memory , Setup source and destination pointers + Cast them in UCHAR as message length is in bytes. */ + source = (UCHAR * ) msg_ptr; + destination = (UCHAR * ) bp; + + /* Save start of message storage. */ + save_ptr = destination; + + /* Copy the message into private buffer. */ + for ( mycount = 0; mycount < msg_len; mycount++) + { + + * destination++ = * source++; + } + /* Restore the pointer of save message. */ + source = save_ptr ; + /* Create message that holds saved message pointer and message length. */ + msg[0] = (ULONG)source; + msg[1] = msg_len; + msg[2] = msg_prio; + msg[3] = posix_priority_search(mqdes, msg_prio); + + /* Attempt to post the message to the queue. */ + temp1 = tx_queue_send(Queue, msg, TX_WAIT_FOREVER); + if ( temp1 != TX_SUCCESS) + { + /* POSIX doesn't have error for this, hence give default. */ + posix_errno = EINTR ; + posix_set_pthread_errno(EINTR); + + /* Return ERROR. */ + return(ERROR); + } + + /* All done. */ + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mq_unlink.c b/utility/rtos_compatibility_layers/posix/px_mq_unlink.c new file mode 100644 index 00000000..41147275 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mq_unlink.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* mq_unlink PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine removes the named message queue */ +/* */ +/* INPUT */ +/* */ +/* const CHAR * mqName Message Queue name. */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR IF fails */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Generic error handler */ +/* posix_find_queue Finds the required queue */ +/* posix_queue_delete Deletes specific queue */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT mq_unlink(const CHAR * mqName) +{ + +POSIX_MSG_QUEUE *q_ptr; +ULONG len; +ULONG temp1; + + /* Checking for the invalid length. */ + len = strlen(mqName); + if(len > 10) + { + /* Return appropriate error. */ + posix_errno = ENAMETOOLONG; + posix_set_pthread_errno(ENAMETOOLONG); + + /* Return Error. */ + return(ERROR); + } + + /* For checking the name. */ + if(!(q_ptr = posix_find_queue(mqName))) + { + /* Set Posix error if name exist. */ + posix_errno = EEXIST; + posix_set_pthread_errno(EEXIST); + + /* Return error. */ + return(ERROR); + } + + if(q_ptr) + /* Unlinks the message Queue. */ + q_ptr->unlink_flag = TX_TRUE; + + /* check if the message queue is not open in any task. */ + if(q_ptr->open_count == 0) + { + /* Free the system resource allocated by open call. */ + temp1 = posix_queue_delete( q_ptr ); + + if( temp1 != TX_SUCCESS) + { + /*. Return generic error. */ + posix_internal_error(100); + + /* Return error. */ + return(ERROR); + } + } + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_destroy.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_destroy.c new file mode 100644 index 00000000..5ea9f9c2 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_destroy.c @@ -0,0 +1,91 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_destroy PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall destroy a mutex attributes object; the object */ +/* becomes,in effect,uninitialized.A destroyed attr attributes object */ +/* can be reinitialized using pthread_mutexattr_init(); */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the mutex attributes */ +/* object to be destroyed. */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error or the results */ +/* of referencing the object after it */ +/* has been destroyed. */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_destroy(pthread_mutexattr_t *attr) +{ + + /* Clear the flag and make this pthread_mutexattr structure free */ + /* First check the attribute object is already destroyed? */ + if (attr->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + /* No then destroy the attributes object */ + attr->in_use = TX_FALSE; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_getprotocol.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_getprotocol.c new file mode 100644 index 00000000..afaa7f91 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_getprotocol.c @@ -0,0 +1,87 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_getprotocol PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall gets the mutex protocol attribute. */ +/* The protocol of a mutex is contained in the protocol attribute. */ +/* attributes. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Pointer to the mutex attributes */ +/* protocol Pointer to return mutex protocol */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_getprotocol( pthread_mutexattr_t *attr, INT *protocol) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *protocol = attr->protocol; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_getpshared.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_getpshared.c new file mode 100644 index 00000000..7859efbd --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_getpshared.c @@ -0,0 +1,87 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_getpshared PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall gets the mutex protocol attribute. */ +/* The protocol of a mutex is contained in the protocol attribute. */ +/* attributes. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Pointer to the mutex attributes */ +/* pshared Pointer to return mutex pshared attr */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_getpshared( pthread_mutexattr_t *attr, INT *pshared) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *pshared = attr->pshared; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_gettype.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_gettype.c new file mode 100644 index 00000000..634aa551 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_gettype.c @@ -0,0 +1,87 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_gettype PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall gets the mutex type attribute. */ +/* The type of mutex is contained in the type attribute of the mutex */ +/* attributes. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the mutex attributes */ +/* type Pointer to return mutex type */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_gettype( pthread_mutexattr_t *attr, INT *type) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *type = attr->type ; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_initi.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_initi.c new file mode 100644 index 00000000..f68eba14 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_initi.c @@ -0,0 +1,92 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes a pthread mutex attributes object to */ +/* default values, if the object is already created this call will */ +/* return an error. */ +/* */ +/* INPUT */ +/* */ +/* attr Pointer to a mutex attributes */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* posix_allocate_pthread_mutexattr Get a new mutexattr object */ +/* set_default_mutexattr Set mutexattr with default values */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_init(pthread_mutexattr_t *attr) +{ + +TX_INTERRUPT_SAVE_AREA + + + /* Disable interrupts. */ + TX_DISABLE + + /* Check this attributes object exists ? */ + if (attr->in_use == TX_TRUE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + TX_RESTORE + return (EINVAL); + } + attr->in_use = TX_TRUE; + set_default_mutexattr(attr); + TX_RESTORE + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_setprotocol.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_setprotocol.c new file mode 100644 index 00000000..6a3d9bf7 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_setprotocol.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_setprotocol PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall sets the mutex protocol attribute. */ +/* The protocol of a mutex is contained in the protocol attribute of */ +/* the mutex attributes */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Pointer to the mutex attributes */ +/* protocol mutex protocol */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, INT protocol) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + if (protocol == PTHREAD_PRIO_INHERIT ) + { + attr->protocol = protocol; + return(OK); + } + else + { + posix_errno = ENOSYS; + posix_set_pthread_errno(ENOSYS); + return(ENOSYS); + } + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_setpshared.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_setpshared.c new file mode 100644 index 00000000..ff4ded26 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_setpshared.c @@ -0,0 +1,94 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_setpshared PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall sets the mutex pshared attribute. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Pointer to the mutex attributes */ +/* pshared mutex pshared attr */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, INT pshared) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + if ((pshared == PTHREAD_PROCESS_PRIVATE)||(pshared == PTHREAD_PROCESS_SHARED) ) + { + attr->type = pshared; + return(OK); + } + else + { + posix_errno = ENOSYS; + posix_set_pthread_errno(ENOSYS); + return(ENOSYS); + } + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_attr_settype.c b/utility/rtos_compatibility_layers/posix/px_mx_attr_settype.c new file mode 100644 index 00000000..11a1405e --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_attr_settype.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutexattr_settype PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall sets the mutex type attribute. */ +/* The type of mutex is contained in the type attribute of the mutex */ +/* attributes. */ +/* ***** Only PTHREAD_MUTEX_RECURSIVE type is supported ****** */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the mutex attributes */ +/* type mutex type. */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutexattr_settype( pthread_mutexattr_t *attr, INT type) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->in_use == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + if (type == PTHREAD_MUTEX_RECURSIVE) + { + attr->type = type ; + return(OK); + } + else + { + posix_errno = ENOSYS; + posix_set_pthread_errno(ENOSYS); + return(ENOSYS); + } + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_destroy.c b/utility/rtos_compatibility_layers/posix/px_mx_destroy.c new file mode 100644 index 00000000..a2275bb4 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_destroy.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutex_destroy PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall destroy the mutex object referenced by mutex; */ +/* the mutex object becomes,in effect, uninitialized.A destroyed mutex */ +/* object can be reinitialized using pthread_mutex_init() */ +/* It shall be safe to destroy an initialized mutex that is unlocked. */ +/* Attempting to destroy a locked mutex results in undefined behavior. */ +/* */ +/* INPUT */ +/* */ +/* mutex Address of the mutex */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* tx_mutex_delete ThreadX Mutex service */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_MUTEX *mutex_ptr; +INT status,retval; + + /* Disable interrupts. */ + TX_DISABLE + + mutex_ptr = (TX_MUTEX*) mutex; + + status = tx_mutex_delete(mutex_ptr); + if (status == TX_SUCCESS) + { + mutex->in_use = TX_FALSE; + retval = OK; + } + else + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + } + + TX_RESTORE + return(retval); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_init.c b/utility/rtos_compatibility_layers/posix/px_mx_init.c new file mode 100644 index 00000000..2daf45d6 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_init.c @@ -0,0 +1,136 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutex_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall init the mutex object referenced by mutex with */ +/* attributes specified by attr. */ +/* If attr is NULL, the default mutex attributes are used; the effect */ +/* shall be the same as passing the address of a default mutex */ +/* attributes object. Upon successful initialization,the state of the */ +/* mutex becomes initialized and unlocked. */ +/* */ +/* INPUT */ +/* */ +/* mutex Pointer to a pthread mutex object */ +/* attr Pointer to mutex attributes */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error In case of some special errors */ +/* posix_in_thread_context Check whether called from a thread */ +/* tx_mutex_create Create a ThreadX Mutex object */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutex_init(pthread_mutex_t *mutex ,pthread_mutexattr_t *attr) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_MUTEX *mutex_ptr; +ULONG status,retval; + + + + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + } + + /* Disable interrupts. */ + TX_DISABLE + + /* Check for any pthread_mutexattr_t suggested */ + if (!attr) + { + /* no attributes passed so assume default attributes */ + attr = &(posix_default_mutex_attr); + } + else + { + /* attributes passed , check for validity */ + if (( (attr->in_use) == TX_FALSE)|| (attr->type!=PTHREAD_MUTEX_RECURSIVE)) + { + /* attributes passed is not valid, return with an error */ + /* Restore interrupts. */ + TX_RESTORE + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + } + + mutex_ptr = (&(mutex->mutex_info)) ; + + /* Now actually create the mutex */ + status = tx_mutex_create(mutex_ptr, "PMTX", TX_INHERIT); + + if ( status == TX_SUCCESS) + { + mutex->in_use = TX_TRUE; + retval = OK; + } + else + { + mutex->in_use = TX_FALSE; + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + } + + TX_RESTORE + return(retval); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_lock.c b/utility/rtos_compatibility_layers/posix/px_mx_lock.c new file mode 100644 index 00000000..56404dd1 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_lock.c @@ -0,0 +1,103 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutex_lock PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function locks the mutex object referenced. If the mutex is */ +/* already locked, the calling thread shall block until the mutex */ +/* becomes available. This operation shall return with the mutex object*/ +/* referenced by mutex in the locked state with the calling thread as */ +/* its owner. */ +/* */ +/* INPUT */ +/* */ +/* mutex Address of the mutex */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify Get calling thread's pointer */ +/* tx_mutex_get ThreadX Mutex Service */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutex_lock(pthread_mutex_t *mutex ) +{ + +TX_MUTEX *mutex_ptr; +TX_THREAD *thread_ptr; +INT retval,status; + + mutex_ptr = (TX_MUTEX*)mutex; + + thread_ptr = tx_thread_identify(); + if ( (mutex_ptr->tx_mutex_ownership_count > 0 ) && (thread_ptr == (mutex_ptr->tx_mutex_owner ))) + { + posix_errno = EDEADLK; + posix_set_pthread_errno(EINVAL); + return (EDEADLK); + } + status = tx_mutex_get( mutex_ptr, TX_WAIT_FOREVER); + switch ( status) + { + case TX_SUCCESS: + retval = OK; + break; + + default: + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + break; + } + return(retval); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_set_default_mutexattr.c b/utility/rtos_compatibility_layers/posix/px_mx_set_default_mutexattr.c new file mode 100644 index 00000000..29a51b4e --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_set_default_mutexattr.c @@ -0,0 +1,75 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* set_default_mutexattr PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets default mutex attr w/ default information. */ +/* */ +/* INPUT */ +/* */ +/* mutexattr mutex attr object pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID set_default_mutexattr(pthread_mutexattr_t *mutexattr) +{ + mutexattr->type = PTHREAD_MUTEX_DEFAULT; + mutexattr->protocol = PTHREAD_PRIO_INHERIT; + mutexattr->pshared = PTHREAD_PROCESS_PRIVATE; + mutexattr->in_use = TX_TRUE; + return; +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_timedlock.c b/utility/rtos_compatibility_layers/posix/px_mx_timedlock.c new file mode 100644 index 00000000..8f18408d --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_timedlock.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutex_timedlock PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function locks the mutex object referenced. If the mutex is */ +/* already locked, the calling thread shall block until the mutex */ +/* becomes available as in the pthread_mutex_lock( ) function. If the */ +/* mutex cannot be locked without waiting for another thread to unlock */ +/* the mutex, this wait shall be terminated when the specified timeout */ +/* expires. This operation shall return with the mutex object */ +/* referenced by mutex in the locked state with the calling thread as */ +/* its owner. */ +/* */ +/* INPUT */ +/* */ +/* mutex Address of the mutex */ +/* timespec Pointer to timespec structure which */ +/* holds timeout period in clock ticks */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify Get calling thread's pointer */ +/* tx_mutex_get ThreadX Mutex Service */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout) +{ + + TX_MUTEX *mutex_ptr; + TX_THREAD *thread_ptr; + INT retval,status; + ULONG timeout_ticks; + + + mutex_ptr = (TX_MUTEX*)mutex; + + thread_ptr = tx_thread_identify(); + if ( (mutex_ptr->tx_mutex_ownership_count > 0 ) && (thread_ptr == (mutex_ptr->tx_mutex_owner ))) + { + posix_errno = EDEADLK; + posix_set_pthread_errno(EDEADLK); + return (EDEADLK); + } + + timeout_ticks = posix_abs_time_to_rel_ticks(abs_timeout); + + status = tx_mutex_get( mutex_ptr, timeout_ticks); + + switch ( status) + { + case TX_SUCCESS: + retval = OK; + break; + + case TX_NOT_AVAILABLE: + posix_errno = ETIMEDOUT; + posix_set_pthread_errno(ETIMEDOUT); + retval = ETIMEDOUT; + break; + + default: + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + break; + } + return(retval); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_trylock.c b/utility/rtos_compatibility_layers/posix/px_mx_trylock.c new file mode 100644 index 00000000..d4c0b9c7 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_trylock.c @@ -0,0 +1,111 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutex_trylock PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall be equivalent to pthread_mutex_lock(), except */ +/* that if the mutex object referenced by mutex is currently locked */ +/* (by any thread,including the current thread), the call shall return */ +/* immediately. If the mutex type is PTHREAD_MUTEX_RECURSIVE and the */ +/* mutex is currently owned by the calling thread,the mutex lock count */ +/* shall be incremented by one and the pthread_mutex_trylock()function */ +/* shall immediately return success. */ +/* */ +/* INPUT */ +/* */ +/* mutex Pointer to the mutex object */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error */ +/* */ +/* CALLS */ +/* */ +/* tx_mutex_get ThreadX Mutex get service. */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + +TX_MUTEX *mutex_ptr; +INT retval,status; + + /* convert pthread mutex object to ThreadX mutex */ + mutex_ptr = (TX_MUTEX *)mutex; + + /* Try to get the mutex */ + status = tx_mutex_get( mutex_ptr, TX_NO_WAIT); + + switch ( status) + { + case TX_SUCCESS: + retval = OK; + break; + + case TX_DELETED: + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + break; + + case TX_NOT_AVAILABLE: + posix_errno = EBUSY; + posix_set_pthread_errno(EBUSY); + retval = EBUSY; + break; + + default: + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + break; + } + return (retval); +} diff --git a/utility/rtos_compatibility_layers/posix/px_mx_unlock.c b/utility/rtos_compatibility_layers/posix/px_mx_unlock.c new file mode 100644 index 00000000..d1afae7a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_mx_unlock.c @@ -0,0 +1,108 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_mutex_unlock PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall release the mutex object referenced by mutex. */ +/* The manner in which a mutex is released is dependent upon the mutex */ +/* type attribute. If there are threads blocked on the mutex object */ +/* referenced by mutex when pthread_mutex_unlock() is called,resulting */ +/* in the mutex becoming available,the scheduling policy shall */ +/* determine which thread shall acquire the mutex. */ +/* */ +/* INPUT */ +/* */ +/* mutex Address of the mutex */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* tx_mutex_put ThreadX Mutex service */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_mutex_unlock(pthread_mutex_t *mutex ) +{ + +TX_MUTEX *mutex_ptr; +INT retval,status; + + + /* convert pthread mutex object to ThreadX mutex */ + mutex_ptr = (TX_MUTEX*)mutex; + status = tx_mutex_put( mutex_ptr); + switch ( status) + { + case TX_SUCCESS: + retval = OK; + break; + + case TX_MUTEX_ERROR: + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + break; + + case TX_NOT_OWNED: + posix_errno = EPERM; + posix_set_pthread_errno(EPERM); + retval = EPERM; + break; + + default: + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + retval = EINVAL; + break; + } + return (retval); +} diff --git a/utility/rtos_compatibility_layers/posix/px_nanosleep.c b/utility/rtos_compatibility_layers/posix/px_nanosleep.c new file mode 100644 index 00000000..d61d7c4e --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_nanosleep.c @@ -0,0 +1,113 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* nanosleep PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall cause the current thread to be suspended from */ +/* execution until the time interval specified by the req argument has */ +/* elapsed */ +/* */ +/* INPUT */ +/* */ +/* req Is the number of real-time (as opposed */ +/* to CPU-time) seconds and nanoseconds to */ +/* suspend the calling thread. */ +/* rem Points to a structure to receive the */ +/* remaining time if the function is */ +/* interrupted by a signal. This pointer */ +/* may be NULL. */ +/* */ +/* OUTPUT */ +/* */ +/* zero If the function returns because the */ +/* requested time has elapsed. */ +/* */ +/* -1 If this functions fails if req argument */ +/* specified a value less than zero or */ +/* greater than or equal to 1 000 million. */ +/* */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_sleep ThreadX thread sleep service */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT nanosleep(struct timespec *req, struct timespec *rem) +{ + +ULONG timer_ticks; + + /* Check for valid inputs */ + /* The nanosecond value must be greater than zero or less than 1 000 million. */ + if ( (!req) || ((req->tv_nsec) <= 0) || (req->tv_nsec > 999999999 )) /* 08-11-2005 */ + + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(ERROR); + } + + /* Convert sleep time into Clock ticks */ + /* Also add some padding so that the thread will sleep no less than the + specified time */ + + timer_ticks = (ULONG) ( ( req->tv_sec * CPU_TICKS_PER_SECOND ) + ( req->tv_nsec/ NANOSECONDS_IN_CPU_TICK) + 1 ); /* 08-11-2005 */ + + /* Now call ThreadX thread sleep service */ + tx_thread_sleep(timer_ticks); + + /* Sleep completed */ + if ( rem ) /* 08-11-2005 */ + { + rem->tv_nsec = 0; + rem->tv_sec = 0; /* 08-11-2005 */ + } + return(OK); + +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_destroy.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_destroy.c new file mode 100644 index 00000000..37861f7a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_destroy.c @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_destroy PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function destroys a pthread attributes object and allows the */ +/* system to reclaim any resources associated with that pthread */ +/* attributes object.This doesn't have an effect on any threads created*/ +/* using this pthread attributes object. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the pthread attributes */ +/* object to be destroyed. */ +/* */ +/* OUTPUT */ +/* */ +/* 0 If successful */ +/* Value In case of any error or the results */ +/* of referencing the object after it */ +/* has been destroyed. */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_destroy(pthread_attr_t *attr) +{ + + /* Clear the flag and make this pthread_attr structure free */ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + return(EINVAL); + else + { + /* No then destroy the attributes object */ + attr->inuse = TX_FALSE; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_getdetachstate.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_getdetachstate.c new file mode 100644 index 00000000..bf3b0351 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_getdetachstate.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_getdetachstate PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the detach state attribute from a pthread */ +/* attributes object specified.The detach state of a thread indicates */ +/* whether the system is allowed to free thread resources when the */ +/* thread terminates. */ +/* The detach state specifies one of: */ +/* PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE. */ +/* The default detach state (DEFAULT_DETACHSTATE) is: */ +/* PTHREAD_CREATE_JOINABLE. */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* detachstate Address of variable to contain the */ +/* returned detach state */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_getdetachstate( pthread_attr_t *attr,INT *detachstate) +{ + /* First check the attribute object is already destroyed? */ + + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *detachstate = attr->detach_state ; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_getinheritsched.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_getinheritsched.c new file mode 100644 index 00000000..b0999a36 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_getinheritsched.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_getinheritsched PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the inheritsched attribute from the thread */ +/* attributes object specified.The inheritsched attribute will be one */ +/* of PTHREAD_EXPLICIT_SCHED or PTHREAD_INHERIT_SCHED. */ +/* The default inheritsched attribute is PTHREAD_EXPLICIT_SCHED, */ +/* with a default priority of 0. */ +/* Use the inheritsched parameter to inherit or explicitly specify the */ +/* scheduling attributes when creating new threads. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* inheritsched Address of variable to contain the */ +/* returned inheritsched attribute */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_getinheritsched(pthread_attr_t *attr, INT *inheritsched) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *inheritsched = attr->inherit_sched ; + return(OK); + } +} + diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_getschedparam.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_getschedparam.c new file mode 100644 index 00000000..ee7d64bc --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_getschedparam.c @@ -0,0 +1,87 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_getschedparam PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the scheduling parameters attribute from the */ +/* pthread attributes object. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* sched_param Address of structure to contain the */ +/* returned scheduling parameters */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + param->sched_priority = attr->sched_attr.sched_priority; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_getschedpolicy.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_getschedpolicy.c new file mode 100644 index 00000000..29237cc5 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_getschedpolicy.c @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_getschedpolicy PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the scheduling policy from the pthread */ +/* attributes object. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* policy Address of variable to contain the */ +/* returned scheduling policy */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_getschedpolicy(pthread_attr_t *attr, INT *policy) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *policy = attr->sched_policy; + return(OK); + } +} + + diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_getstack.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_getstack.c new file mode 100644 index 00000000..400de46a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_getstack.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_getstack PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the thread creation stack attributes stackaddr */ +/* and stacksize in the attr object. */ +/* The stack attributes specify the area of storage to be used for the*/ +/* created thread's stack. The base (lowest addressable byte) of the */ +/* storage shall be stackaddr , and the size of the storage shall be */ +/* stacksize bytes. */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* stackaddr Pointer to hold Address of stack */ +/* stacksize Holds the stack size */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_getstack( pthread_attr_t *attr,void **stackaddr, + size_t *stacksize) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *stackaddr = attr->stack_address; + *stacksize = attr->stack_size ; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_getstackaddr.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_getstackaddr.c new file mode 100644 index 00000000..9218b120 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_getstackaddr.c @@ -0,0 +1,85 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_getstackaddr PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the stack address associated with a pthread */ +/* attributes */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* stackaddr Address of variable to contain the */ +/* returned stack address */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_getstackaddr( pthread_attr_t *attr,void **stackaddr) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *stackaddr = attr->stack_address ; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_getstacksize.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_getstacksize.c new file mode 100644 index 00000000..cd7c2d28 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_getstacksize.c @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_getstacksize PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the stack size associated with a pthread */ +/* The stacksize is the minimum stack size (in bytes) allocated for */ +/* the created threads stack. */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* stacksize Address of variable to contain the */ +/* returned stack size */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + *stacksize = attr->stack_size; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_init.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_init.c new file mode 100644 index 00000000..317a8d3a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_init.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes a pthread attributes object to default */ +/* values,if the object is already created this call will reinitialize */ +/* it else it will create a new attr object and initializes it. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* set_default_pthread_attr to reset with defualt parameters */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_init(pthread_attr_t *attr) +{ + +TX_INTERRUPT_SAVE_AREA + + TX_DISABLE + + /* Check this attributes object exists ? */ + if (attr->inuse == TX_FALSE) + attr->inuse = TX_TRUE; + + set_default_pthread_attr(attr); + + TX_RESTORE + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_setdetachstate.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_setdetachstate.c new file mode 100644 index 00000000..af2f7165 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_setdetachstate.c @@ -0,0 +1,92 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_setdetachstate PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the detach state attribute from a pthread */ +/* attributes object specified.The detach state of a thread indicates */ +/* whether the system is allowed to free thread resources when the */ +/* thread terminates. */ +/* The detach state specifies one of: */ +/* PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE. */ +/* The default detach state (DEFAULT_DETACHSTATE) is: */ +/* PTHREAD_CREATE_JOINABLE. */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* detachstate detach state to set */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +INT pthread_attr_setdetachstate(pthread_attr_t *attr,INT detachstate) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + attr->detach_state = detachstate ; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_setinheritsched.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_setinheritsched.c new file mode 100644 index 00000000..e4919f61 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_setinheritsched.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_setinheritsched PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the inheritsched attribute from the thread */ +/* attributes object specified.The inheritsched attribute will be one */ +/* of PTHREAD_EXPLICIT_SCHED or PTHREAD_INHERIT_SCHED. */ +/* The default inheritsched attribute is PTHREAD_EXPLICIT_SCHED, */ +/* with a default priority of 0. */ +/* Use the inheritsched parameter to inherit or explicitly specify the */ +/* scheduling attributes when creating new threads. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* inheritsched inheritsched attribute to set */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_setinheritsched(pthread_attr_t *attr, INT inheritsched) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + attr->inherit_sched = inheritsched ; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_setschedparam.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_setschedparam.c new file mode 100644 index 00000000..3768c73b --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_setschedparam.c @@ -0,0 +1,95 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_setschedparam PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the scheduling parameters attribute for the */ +/* pthread attributes object. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* sched_param Address of structure containing the */ +/* scheduling parameters to set */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param *param) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + if (param->sched_priority == 0) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + if(param->sched_priority >= PX_LOWEST_PRIORITY && param->sched_priority <= PX_HIGHEST_PRIORITY ) + { + + attr->sched_attr.sched_priority = param->sched_priority; + } + return(OK); +} + diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_setschedpolicyl.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_setschedpolicyl.c new file mode 100644 index 00000000..308c11fb --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_setschedpolicyl.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_setschedpolicy PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the scheduling policy from the pthread */ +/* attributes object. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* policy variable holding the scheduling */ +/* policy to set */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_setschedpolicy(pthread_attr_t *attr, INT policy) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + attr->sched_policy = policy; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_setstack.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_setstack.c new file mode 100644 index 00000000..16f84ee0 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_setstack.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_setstack PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the thread creation stack attributes stackaddr */ +/* and stacksize in the attr object. */ +/* The stack attributes specify the area of storage to be used for the*/ +/* created thread’s stack. The base (lowest addressable byte) of */ +/* the storage shall be stackaddr , and the size of the storage shall */ +/* be stacksize bytes. */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* stackaddr Address of stack */ +/* stacksize Holds the stack size */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_setstack( pthread_attr_t *attr,void *stackaddr, + size_t stacksize) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + attr->stack_address = stackaddr; /* This has got no effect */ + attr->stack_size = stacksize; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_setstackaddr.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_setstackaddr.c new file mode 100644 index 00000000..62ffca97 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_setstackaddr.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_setstackaddr PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the stack address associated with a pthread */ +/* attributes */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* stackaddr Address of variable to contain the */ +/* stack address to set */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_setstackaddr(pthread_attr_t *attr,void *stackaddr) +{ + + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + attr->stack_address = stackaddr; + return(OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_attr_setstacksize.c b/utility/rtos_compatibility_layers/posix/px_pth_attr_setstacksize.c new file mode 100644 index 00000000..34ba0230 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_attr_setstacksize.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_attr_setstacksize PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the stack size associated with a pthread attr */ +/* The stacksize is the minimum stack size (in bytes) allocated for */ +/* the created threads stack. */ +/* */ +/* INPUT */ +/* */ +/* attr Address of the thread attributes */ +/* stacksize stack size */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) +{ + /* First check the attribute object is already destroyed? */ + if (attr->inuse == TX_FALSE) + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + else + { + attr->stack_size = stacksize; + return(OK); + } +} diff --git a/ports/cortex_m33/ac5/src/txe_thread_secure_stack_allocate.c b/utility/rtos_compatibility_layers/posix/px_pth_cancel.c similarity index 59% rename from ports/cortex_m33/ac5/src/txe_thread_secure_stack_allocate.c rename to utility/rtos_compatibility_layers/posix/px_pth_cancel.c index dc99f538..8b04ee42 100644 --- a/ports/cortex_m33/ac5/src/txe_thread_secure_stack_allocate.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_cancel.c @@ -9,56 +9,54 @@ /* */ /**************************************************************************/ - /**************************************************************************/ /**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ /** */ -/** ThreadX Component */ /** */ -/** Thread */ /** */ /**************************************************************************/ /**************************************************************************/ -#define TX_SOURCE_CODE - - /* Include necessary system files. */ -#include "tx_api.h" -#include "tx_initialize.h" -#include "tx_thread.h" +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _txe_thread_secure_stack_allocate Cortex-M33 */ -/* 6.1 */ +/* pthread_cancel PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function checks for errors in the secure stack allocate */ -/* function call. */ +/* The pthread_cancel function shall request that thread be canceled. */ +/* The target thread’s cancelability state and type determines when */ +/* the cancellation takes effect. When the cancellation is acted on, */ +/* the cancelation cleanup handlers for thread shall be called. When */ +/* the last cancelation cleanup handler returns, the thread-specific */ +/* data destructor functions shall be called for thread. When the last */ +/* destructor function returns, thread shall be terminated. */ /* */ /* INPUT */ /* */ -/* thread_ptr Thread control block pointer */ -/* stack_size Size of secure stack to */ -/* allocate */ +/* thread pthread handle to thread to be canceled */ /* */ /* OUTPUT */ /* */ -/* TX_THREAD_ERROR Invalid thread pointer */ -/* TX_CALLER_ERROR Invalid caller of function */ -/* status Actual completion status */ +/* zero If successful */ +/* error number If fails */ /* */ /* CALLS */ /* */ -/* _tx_thread_secure_stack_allocate Actual stack alloc function */ /* */ /* CALLED BY */ /* */ @@ -68,52 +66,55 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ -/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ /**************************************************************************/ -UINT _txe_thread_secure_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size) +INT pthread_cancel(pthread_t thread) { -#if defined(TX_SINGLE_MODE_SECURE) || defined(TX_SINGLE_MODE_NON_SECURE) - return(TX_FEATURE_NOT_ENABLED); -#else -UINT status; + +TX_THREAD *thread_ptr; +POSIX_TCB *pthread_ptr; + - /* Default status to success. */ - status = TX_SUCCESS; - /* Check for an invalid thread pointer. */ - if (thread_ptr == TX_NULL) + + /* Get the thread identifier of the pthread to be canceled */ + thread_ptr = posix_tid2thread(thread); + + if( (thread_ptr->tx_thread_state == TX_COMPLETED) || (thread_ptr->tx_thread_state == TX_TERMINATED) ) { - /* Thread pointer is invalid, return appropriate error code. */ - status = TX_THREAD_ERROR; + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + /* get posix TCB for this pthread */ + pthread_ptr = (POSIX_TCB *)thread_ptr; + + /* Check if target pthread is created with cancel enable */ + if ( pthread_ptr->cancel_state != PTHREAD_CANCEL_ENABLE) + { + posix_errno= EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + if( pthread_ptr->cancel_type==PTHREAD_CANCEL_DEFERRED ) + { + /* set cancel request for cancelation point */ + pthread_ptr->cancel_request=TRUE; + } + else if(pthread_ptr->cancel_type==PTHREAD_CANCEL_ASYNCHRONOUS ) + { + /* Signal the housekeeping ThreadX thread to cancel (delete) the requested pthread now */ + + posix_destroy_pthread(pthread_ptr,(VOID *)0); + } + else /* illegal value in pthread_ptr->cancel_type */ + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); } - /* 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 + /* Indicate success. */ + return(OK); } diff --git a/utility/rtos_compatibility_layers/posix/px_pth_create.c b/utility/rtos_compatibility_layers/posix/px_pth_create.c new file mode 100644 index 00000000..e2d6f4db --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_create.c @@ -0,0 +1,260 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_create PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This creates a new thread with attributes specified by attr within */ +/* a process.If the attr is NULL,then default attributes are used. */ +/* Upon successful completion, pthread_create() stores the ID of the */ +/* created thread in the location referenced by thread. */ +/* The thread is created executing start_routine with arg as its sole */ +/* argument. */ +/* Initially, threads are created from within a process. Once created, */ +/* threads are peers, and may create other threads. Note that an */ +/* "initial thread" exists by default which runs 'main' */ +/* If pthread_create( ) fails,no new thread is created and the contents*/ +/* of the location referenced by thread are undefined. */ +/* */ +/* INPUT */ +/* */ +/* thread place to store newly created thread ID */ +/* Each thread in a process is uniquely */ +/* identified during its lifetime by a */ +/* value of type pthread_t called as */ +/* thread ID. */ +/* */ +/* attr attributes object , NULL = Default attr.*/ +/* start_routine thread start up routine */ +/* arg arguments to start up routine by ref. */ +/* */ +/* OUTPUT */ +/* */ +/* zero If successful */ +/* error number If fails */ +/* pthread_create() function will fail if: */ +/* [EAGAIN] system lacked the necessary */ +/* resources to create a thread, */ +/* or the system-imposed limit on */ +/* the number of pthreads in */ +/* a process PTHREAD_THREADS_MAX */ +/* would be exceeded. */ +/* [EINVAL] value specified by attr is */ +/* invalid. */ +/* [EPERM] The caller does not have */ +/* appropriate permission to set */ +/* the required scheduling */ +/* parameters or scheduling policy*/ +/* */ +/* This call will not return an error code of [EINTR]*/ +/* */ +/* */ +/* CALLS */ +/* */ +/* posix_in_thread_context To check calling context. */ +/* posix_internal_error Internal error */ +/* posix_allocate_pthread_t Allocate control block for pthread */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_create (pthread_t *thread, pthread_attr_t *attr, + void *(*start_routine)(void*),void *arg) +{ + +TX_INTERRUPT_SAVE_AREA + + +TX_THREAD *thread_ptr; +POSIX_TCB *pthread_ptr, *current_thread_ptr; +INT status,retval; + + + + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + } + + /* Disable interrupts. */ + + + /* check for any pthread_t attr suggested */ + if (!attr) + { + /* no attributes passed so assume default attributes */ + attr = &(posix_default_pthread_attr); + } + else + { + /* Check attributes passed , check for validity */ + if ( (attr->inuse) == TX_FALSE) + { + /* attributes passed are not valid, return with an error */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + } + + + /* Get a pthread control block for this new pthread */ + TX_DISABLE + status = posix_allocate_pthread_t(&pthread_ptr); + TX_RESTORE + /* Make sure we got a Thread control block */ + if ((status == ERROR) || (!pthread_ptr)) + { + /* Configuration/resource error. */ + return(EAGAIN); + } + + if(attr->inherit_sched==PTHREAD_INHERIT_SCHED) + { + /* get current thread tcb */ + current_thread_ptr=posix_tid2tcb(pthread_self()); + + /* copy scheduling attributes */ + pthread_ptr->current_priority = current_thread_ptr->current_priority ; + pthread_ptr->detach_state = current_thread_ptr->detach_state ; + pthread_ptr->inherit_sched = current_thread_ptr->inherit_sched ; + pthread_ptr->orig_priority = current_thread_ptr->orig_priority ; + pthread_ptr->sched_attr.sched_priority= current_thread_ptr->sched_attr.sched_priority ; + pthread_ptr->pthread_flags = current_thread_ptr->pthread_flags ; + pthread_ptr->sched_policy = current_thread_ptr->sched_policy; + pthread_ptr->stack_size = current_thread_ptr->stack_size ; + pthread_ptr->stack_address = NULL; /* will allocate our own stack */ + pthread_ptr->threshold = pthread_ptr->current_priority ; /* preemption threshold */ + } + else /* assume PTHREAD_EXPLICIT_SCHED */ + { + + /* copy pthread-attr to TCB */ + posix_copy_pthread_attr(pthread_ptr,attr); + + /* preemption treshold */ + pthread_ptr->threshold = pthread_ptr->current_priority ; + /* scheduling */ + if(pthread_ptr->sched_policy==SCHED_RR) pthread_ptr->time_slice = SCHED_RR_TIME_SLICE; + else pthread_ptr->time_slice = 0; + } + + /* Now set up pthread initial parameters */ + + pthread_ptr->entry_parameter = arg; + pthread_ptr->start_routine = start_routine; + /* Newly created pthread not joined by anybody! */ + pthread_ptr->is_joined_by = TX_FALSE; + pthread_ptr->joined_by_pthreadID =TX_FALSE; + /* Newly created pthread not yet joined to any other pthread */ + pthread_ptr->is_joined_to = TX_FALSE; + pthread_ptr->joined_to_pthreadID = TX_FALSE; + + + /* Allow cancel */ + pthread_ptr->cancel_state = PTHREAD_CANCEL_ENABLE; + pthread_ptr->cancel_type = PTHREAD_CANCEL_DEFERRED; + pthread_ptr->cancel_request = FALSE; + + pthread_ptr->value_ptr = NULL; + + + /* default stack allocation */ + if((attr->stack_address)==NULL) + { + pthread_ptr->stack_size = attr->stack_size ; + status = posix_memory_allocate( pthread_ptr->stack_size, &(pthread_ptr->stack_address)); + + /* problem allocating stack space */ + if ((status == ERROR)) + { + /* Configuration/resource error. */ + return(EAGAIN); + } + + } + + /* Create an event flags group for sigwait. */ + retval = tx_event_flags_create(&(pthread_ptr -> signals.signal_event_flags), "posix sigwait events"); + + /* Get the thread info from the TCB. */ + thread_ptr = posix_tcb2thread(pthread_ptr); + + /* Now actually create and start the thread. */ + /* convert Posix priorities to Threadx priority */ + retval += tx_thread_create( thread_ptr, + "pthr", + posix_thread_wrapper, + (ULONG)pthread_ptr, + pthread_ptr->stack_address, + pthread_ptr->stack_size, + (TX_LOWEST_PRIORITY - pthread_ptr->current_priority + 1), + (TX_LOWEST_PRIORITY - pthread_ptr->threshold + 1), + pthread_ptr->time_slice, + TX_AUTO_START); + + /* See if ThreadX encountered an error */ + if (retval) + { + /* Internal error */ + posix_error_handler(3333); + retval = EACCES; + } + else + { + /* Everything is fine. */ + /* create a pthreadID by type casting POSIX_TCB into pthread_t */ + pthread_ptr->pthreadID = (pthread_t )pthread_ptr; + *thread = pthread_ptr->pthreadID ; + retval = OK; + } + + /* Everything worked fine if we got here */ + return(retval); + +} diff --git a/ports/cortex_m33/ac5/src/txe_thread_secure_stack_free.c b/utility/rtos_compatibility_layers/posix/px_pth_detach.c similarity index 62% rename from ports/cortex_m33/ac5/src/txe_thread_secure_stack_free.c rename to utility/rtos_compatibility_layers/posix/px_pth_detach.c index 9f6ed6b9..b2b7581b 100644 --- a/ports/cortex_m33/ac5/src/txe_thread_secure_stack_free.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_detach.c @@ -12,51 +12,61 @@ /**************************************************************************/ /**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ /** */ -/** ThreadX Component */ /** */ -/** Thread */ /** */ /**************************************************************************/ /**************************************************************************/ -#define TX_SOURCE_CODE - - /* Include necessary system files. */ -#include "tx_api.h" -#include "tx_initialize.h" -#include "tx_thread.h" +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _txe_thread_secure_stack_free Cortex-M33 */ -/* 6.1 */ +/* pthread_detach PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function checks for errors in the secure stack free */ -/* function call. */ +/* */ +/* The pthread_detach() function indicates that system resources for */ +/* the specified thread should be reclaimed when the thread ends. */ +/* If the thread is already ended, resources are reclaimed immediately.*/ +/* This routine does not cause the thread to end. */ +/* After pthread_detach() has been issued, it is not valid to try to */ +/* pthread_join() with the target thread. */ +/* Eventually, you should call pthread_join() or pthread_detach() for */ +/* every thread that is created joinable (with a detachstate of */ +/* PTHREAD_CREATE_JOINABLE)so that the system can reclaim all resources*/ +/* associated with the thread. Failure to join to or detach joinable */ +/* threads will result in memory and other resource leaks until the */ +/* process ends. If thread doesn't represent a valid undetached thread,*/ +/* pthread_detach() will return ESRCH. */ +/* */ /* */ /* INPUT */ /* */ -/* thread_ptr Thread control block pointer */ +/* thread pthread handle to the target thread */ +/* */ /* */ /* OUTPUT */ /* */ -/* TX_THREAD_ERROR Invalid thread pointer */ -/* TX_CALLER_ERROR Invalid caller of function */ -/* status Actual completion status */ +/* zero If successful */ +/* error number If fails */ /* */ /* CALLS */ /* */ -/* _tx_thread_secure_stack_free Actual stack free function */ /* */ /* CALLED BY */ /* */ @@ -66,55 +76,32 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ /* */ /**************************************************************************/ -UINT _txe_thread_secure_stack_free(TX_THREAD *thread_ptr) +INT pthread_detach(pthread_t thread) + { -#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) + +TX_INTERRUPT_SAVE_AREA + +POSIX_TCB *pthread_ptr; + + TX_DISABLE + + pthread_ptr = posix_tid2tcb(thread); + if(pthread_ptr==NULL) { - - /* Thread pointer is invalid, return appropriate error code. */ - status = TX_THREAD_ERROR; + TX_RESTORE + return(ESRCH); } - - /* Now check for invalid thread ID. */ - else if (thread_ptr -> tx_thread_id != TX_THREAD_ID) + if(pthread_ptr->is_detached==TX_TRUE) { - - /* Thread pointer is invalid, return appropriate error code. */ - status = TX_THREAD_ERROR; + TX_RESTORE + return (EINVAL); } + pthread_ptr->is_detached = TX_TRUE; - /* 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 + TX_RESTORE + return(OK); } diff --git a/utility/rtos_compatibility_layers/posix/px_pth_equal.c b/utility/rtos_compatibility_layers/posix/px_pth_equal.c new file mode 100644 index 00000000..e1930601 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_equal.c @@ -0,0 +1,80 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_equal PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* */ +/* This function compares two pthread handles for equality. */ +/* */ +/* */ +/* */ +/* INPUT */ +/* */ +/* thread1 pthread handle to the first thread */ +/* thread2 pthread handle to the second thread */ +/* */ +/* OUTPUT */ +/* */ +/* 0 The pthread handles do not refer to the */ +/* same thread */ +/* 1 The pthread handles refer to the same */ +/* thread */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_equal(pthread_t thread1, pthread_t thread2) +{ + if (thread1 == thread2) + + return(1); + else + return(0); +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_exit.c b/utility/rtos_compatibility_layers/posix/px_pth_exit.c new file mode 100644 index 00000000..26445711 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_exit.c @@ -0,0 +1,94 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_exit PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* */ +/* The pthread_exit() function terminates the calling thread, making */ +/* its exit status available to any waiting threads.Normally,a thread */ +/* terminates by returning from the start routine that was specified */ +/* in the pthread_create() call which started it. */ +/* An implicit call to pthread_exit() occurs when any thread returns */ +/* from its start routine. (With the exception of the initial thread, */ +/* at which time an implicit call to exit() occurs). */ +/* The pthread_exit() function provides an interface similar to exit()*/ +/* but on a per-thread basis. */ +/* */ +/* pthread_exit() does not return. */ +/* */ +/* */ +/* INPUT */ +/* value_ptr exit parameter */ +/* */ +/* OUTPUT */ +/* */ +/* none pthread_exit() does not return. */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID pthread_exit(void *value_ptr) +{ + +TX_THREAD *thread_ptr; +POSIX_TCB *pthread_ptr; + + /* Get the thread identifier of the currently running thread */ + thread_ptr = tx_thread_identify(); + /* get posix TCB for this pthread */ + pthread_ptr = (POSIX_TCB *)thread_ptr; + + /* Signal the housekeeping ThreadX thread to delete the requested pthread */ + posix_destroy_pthread(pthread_ptr,value_ptr); + + /* Indicate success. */ + return; + +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_getcanceltype.c b/utility/rtos_compatibility_layers/posix/px_pth_getcanceltype.c new file mode 100644 index 00000000..c366b6c0 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_getcanceltype.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_getcanceltype PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* The pthread_fetcancelstate()function shall atomically both get the */ +/* calling thread’s cancelability type to the indicated type and */ +/* return the previous cancelability type at the location referenced */ +/* by oldtype. Legal values for type are PTHREAD_CANCEL_DEFERRED and */ +/* PTHREAD_CANCEL_ASYNCHRONOUS. */ +/* */ +/* INPUT */ +/* */ +/* type New cancelability type to be set */ +/* oldtype Pointer to old cancelability type */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_getcanceltype (INT type, INT *oldtype) +{ +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *thread_ptr; +POSIX_TCB *pthread_ptr; + + /* First check for validity of the new cancel type to be set */ + if ( ( type == PTHREAD_CANCEL_DEFERRED ) || ( type == PTHREAD_CANCEL_ASYNCHRONOUS ) ) + { + TX_DISABLE + + /* Get the thread identifier of the currently running thread */ + thread_ptr = tx_thread_identify(); + /* get posix TCB for this pthread */ + pthread_ptr = (POSIX_TCB *)thread_ptr; + *oldtype = pthread_ptr->cancel_type; + pthread_ptr->cancel_type = type; + + TX_RESTORE + + return(OK); + } + else + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_getschedparam.c b/utility/rtos_compatibility_layers/posix/px_pth_getschedparam.c new file mode 100644 index 00000000..38df6cae --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_getschedparam.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_getschedparam PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the scheduling parameters attribute from the */ +/* pthread TCB. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* thread POSIX thread ID */ +/* policy Address of the scheduling policy */ +/* sched_param Address of structure to contain the */ +/* returned scheduling parameters */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_getschedparam(pthread_t thread, INT *policy, struct sched_param *param) +{ + + POSIX_TCB *thread_tcb; + + + thread_tcb=posix_tid2tcb(thread); + + if(thread_tcb==NULL) + { + return(ESRCH); + } + else + { + *policy=thread_tcb->sched_policy; + *param=thread_tcb->sched_attr; + return(OK); + } + +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_init.c b/utility/rtos_compatibility_layers/posix/px_pth_init.c new file mode 100644 index 00000000..ad0b16a0 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_init.c @@ -0,0 +1,959 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ + +/* this define will force declaration of the */ +/* posix objects to happen in this file */ +#define PX_OBJECT_INIT + +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* is_posix_thread PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Verify that the control block belongs to a POSIX thread and not */ +/* a ThreadX thread */ +/* */ +/* INPUT */ +/* */ +/* thread_ptr Pointer to a thread control block */ +/* */ +/* OUTPUT */ +/* */ +/* TX_FALSE if not POSIX thread. TX_TRUE if POSIX thread. */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static INT is_posix_thread(TX_THREAD *thread_ptr) +{ + if (((POSIX_TCB *)thread_ptr < ptcb_pool) || + ((POSIX_TCB *)thread_ptr > &ptcb_pool[PTHREAD_THREADS_MAX - 1])) + { + return TX_FALSE; + } + return TX_TRUE; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_pthread_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets up / configures / initializes all the */ +/* pthread Control Blocks that we define at compile-time in order to */ +/* ensure that there is sufficient memory. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* posix_reset_pthread_t Reset a task control block */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + VOID posix_pthread_init(VOID) +{ + +ULONG index; + + /* Loop through array of TCBs and initialize each one. */ + for (index = 0; index < PTHREAD_THREADS_MAX; index++) + { + posix_reset_pthread_t(&(ptcb_pool[index])); + } +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_reset_pthread_t PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets a pthread w/ default information. */ +/* */ +/* INPUT */ +/* */ +/* ptcb pthread control block pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + VOID posix_reset_pthread_t (POSIX_TCB *ptcb) +{ + /* Indicate this entry is not in use. */ + ptcb->in_use = TX_FALSE; +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_copy_pthread_attr PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function copies pthread attributes from a pthread_attr object */ +/* to a pthread TCB */ +/* */ +/* INPUT */ +/* */ +/* attr pthread attr object pointer */ +/* pthread_ptr target pthread TCB */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + VOID posix_copy_pthread_attr(POSIX_TCB *pthread_ptr,pthread_attr_t *attr) +{ + + pthread_ptr->current_priority = attr->sched_attr.sched_priority ; + pthread_ptr->detach_state = attr->detach_state ; + pthread_ptr->inherit_sched = attr->inherit_sched ; + pthread_ptr->orig_priority = attr->sched_attr.sched_priority ; + pthread_ptr->sched_attr.sched_priority= attr->sched_attr.sched_priority ; + pthread_ptr->pthread_flags = attr->pthread_flags ; + pthread_ptr->sched_policy = attr->sched_policy; + pthread_ptr->stack_size = attr->stack_size ; + pthread_ptr->stack_address = attr->stack_address; + + return; +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_allocate_pthread_t PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to allocate memory for a pthread stack and */ +/* a POSIX pthread Control Block (PTCB). */ +/* */ +/* INPUT */ +/* */ +/* stack_size Requested task stack size */ +/* tcb_ptr Pointer to tcb pointer */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* Nothing */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + INT posix_allocate_pthread_t(POSIX_TCB **ptcb_ptr) +{ + +POSIX_TCB *ptcb; +ULONG index; + + /* Assume the worst. */ + *ptcb_ptr = (POSIX_TCB *)0; + + /* This next search is optimized for simplicity, not speed. */ + for (index = 0, ptcb = ptcb_pool; + index < PTHREAD_THREADS_MAX; + index++, ptcb++) + { + /* Is this guy in use? If not, we can use it. */ + if (ptcb->in_use == TX_FALSE) + { + /* This pTCB is now in use. */ + ptcb->in_use = TX_TRUE; + + /* Stop searching. */ + break; + } + } /* for each POSIX Thread Control Block */ + + /* Did we search all pTCBs and come up empty? */ + if (index == PTHREAD_THREADS_MAX) + { + /* No more pTCBs available - user configuration error. */ + return(ERROR); + } + else + { + + /* Make sure the signal handler information is cleared when the new TCB is allocated. */ + memset(&(ptcb -> signals), 0, sizeof(signal_info)); + + /* Found one. */ + *ptcb_ptr = ptcb; + } + return(OK); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_thread_wrapper PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Every thread that is modeling a ThreadX thread has this routine as */ +/* its entry point.This routine simply calls the pthread entry routine */ +/* with its sole argument passed in pthread-create(). */ +/* */ +/* The main purpose of this function is to mimic the pthread interface */ +/* which allows 1 argument to be passed to the entry point of a thread */ +/* */ +/* INPUT */ +/* */ +/* pthread_ptr pthread control block pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* *(pthread_start_routine) Application pthread entry */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX only (internal) */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + VOID posix_thread_wrapper(ULONG pthr_ptr) +{ + +POSIX_TCB *pthread_ptr; +VOID *value_ptr; + + /* The input argument is really a pointer to the pthread's control block */ + pthread_ptr = (POSIX_TCB *) pthr_ptr; + /* Invoke the pthread start routine with appropriate arguments */ + value_ptr = (pthread_ptr->start_routine)((VOID *)pthread_ptr->entry_parameter); + + /* In ThreadX, when a thread returns from its entry point, it enters the */ + /* "completed" state, which is basically an infinite suspension. */ + /* now use pthread_exit call to end this pthread */ + pthread_exit(value_ptr); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_thread2tcb PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function converts a ThreadX thread identifier into */ +/* a posix pthread control block (TCB) */ +/* */ +/* INPUT */ +/* */ +/* thread_ptr Thread pointer */ +/* */ +/* OUTPUT */ +/* */ +/* pthread pthread Task control block */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Internal error */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + POSIX_TCB *posix_thread2tcb(TX_THREAD *thread_ptr) +{ + +POSIX_TCB *p_tcb; + + /* Make sure we were called from a thread. */ + if (!thread_ptr) + { + /* Not called from a thread - error! */ + posix_internal_error(333); + } + + /* Make sure thread is a POSIX thread else following case is illegal. */ + if (!is_posix_thread(thread_ptr)) { + /* Not called from a POSIX thread - error! */ + return NULL; + } + + /* We can do this because the Thread information is intentionally */ + /* located as the first field in the structure. */ + p_tcb = (POSIX_TCB *)thread_ptr; + + /* All done. */ + return(p_tcb); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_tcb2thread PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function converts a POSIX TCB into ThreadX thread */ +/* */ +/* */ +/* INPUT */ +/* */ +/* pthread_ptr pthread TCB */ +/* */ +/* OUTPUT */ +/* */ +/* thread ThreadX thread */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Internal error */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + TX_THREAD *posix_tcb2thread (POSIX_TCB *pthread_ptr) +{ + +TX_THREAD *thread; + + /* Make sure we don't have a NULL pointer. */ + if (pthread_ptr) + { + /* Simply convert the TCB to a Thread via a cast */ + thread = (&(pthread_ptr->thread_info )); + } + else + { + thread = ((TX_THREAD *)0); + } + + return(thread); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_thread2tid PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function converts a ThreadX thread identifier into */ +/* posix thread ID */ +/* */ +/* INPUT */ +/* */ +/* thread_ptr Thread pointer */ +/* */ +/* OUTPUT */ +/* */ +/* thread_ID thread_ID */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Internal error */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + pthread_t posix_thread2tid(TX_THREAD *thread_ptr) +{ + +pthread_t thread_ID; +POSIX_TCB *p_tcb; + + /* Make sure we were called from a thread. */ + if (!thread_ptr) + { + /* Not called from a thread - error! */ + posix_internal_error(222); + } + + /* Get the TCB for this pthread */ + + p_tcb = posix_thread2tcb(thread_ptr); + thread_ID = p_tcb->pthreadID; + + /* All done. */ + return(thread_ID); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_tid2thread PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function converts a posix thread ID into a thread. */ +/* */ +/* INPUT */ +/* */ +/* tid Thread ID */ +/* */ +/* OUTPUT */ +/* */ +/* thread_ptr Thread pointer */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + TX_THREAD *posix_tid2thread(pthread_t ptid) +{ + +TX_THREAD *thread; +POSIX_TCB *pthread; + + /* Make sure we don't have a NULL TID. */ + if (ptid) + { + /* convert the pthread ID to a pThread TCB */ + pthread = posix_tid2tcb(ptid); + /* convert the pthread TCB to a pThread TCB */ + thread= posix_tcb2thread(pthread); + } + else + { + thread = ((TX_THREAD *)0); + } + return(thread); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_tid2tcb PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function converts a posix thread ID into a posix pthread TCB */ +/* */ +/* INPUT */ +/* */ +/* tid Thread ID */ +/* */ +/* OUTPUT */ +/* */ +/* pthread_ptr pthread pointer */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + POSIX_TCB *posix_tid2tcb(pthread_t ptid) +{ + +POSIX_TCB *pthread; + + /* Make sure we don't have a NULL TID. */ + if (ptid) + /* Simply convert the thread ID to a pthread TCB via a cast */ + pthread = (POSIX_TCB *)ptid; + else + pthread = ((POSIX_TCB *)0); + + return(pthread); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_destroy_pthread PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs internal cleanup and housekeeping */ +/* when a pthread exits. */ +/* */ +/* INPUT */ +/* */ +/* pthread_ptr pointer to TCB of the pthread */ +/* to be deleted */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If fails */ +/* */ +/* CALLS */ +/* */ +/* tx_queue_send Send to system mgr queue */ +/* posix_internal_error Internal error handling */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + VOID posix_destroy_pthread(POSIX_TCB *pthread_ptr, VOID *value_ptr) +{ + +ULONG request[WORK_REQ_SIZE]; +INT status; + + /* Build the request. */ + + request[0] = (ULONG)pthread_ptr; + request[1] = (ULONG)value_ptr; + + /* Send a message to the SysMgr supervisor thread, asking it to delete */ + /* the pthread. Since the SysMgr supervisor thread is the highest */ + /* possible priority, this routine will be preempted when we */ + /* post the message to the SysMgr's work queue. */ + + status = tx_queue_send(&posix_work_queue, request, TX_NO_WAIT); + /* This should always succeed. */ + if (status != TX_SUCCESS) + { + posix_internal_error(1001); + } + + /* Return the pthread's TCB to the pool of available TCB's. */ + posix_reset_pthread_t(pthread_ptr); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_do_pthread_delete PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes the pthread and reclaims the stack memory. */ +/* Also it resumes any pthread joined to this exiting pthread. */ +/* */ +/* INPUT */ +/* */ +/* pthread_ptr pointer to TCB of the pthread */ +/* to be deleted */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If fails */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_terminate Terminate ThreadX thread */ +/* tx_thread_delete Delete the ThreadX thread */ +/* posix_memory_release Release the task's stack */ +/* posix_free_tcb Free pthread control block */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + VOID posix_do_pthread_delete(POSIX_TCB *pthread_ptr, VOID *value_ptr) +{ + +TX_INTERRUPT_SAVE_AREA + +POSIX_TCB *joined_pthread_ptr; +TX_THREAD *thread_ptr,*thread1_ptr; +pthread_t joined_pthread_ID; +ULONG status; + + TX_DISABLE + /* preserve the thread's return value regardless */ + pthread_ptr->value_ptr = value_ptr; + + if ( pthread_ptr->is_joined_by == TX_TRUE) + { + joined_pthread_ID = pthread_ptr->joined_by_pthreadID ; + joined_pthread_ptr = posix_tid2tcb(joined_pthread_ID); + + joined_pthread_ptr->is_joined_to = TX_FALSE; + joined_pthread_ptr->joined_to_pthreadID =TX_FALSE; + + thread_ptr = (TX_THREAD *)joined_pthread_ptr; + + /* Now resume the suspended pthread joined to this pthread */ + tx_thread_resume(thread_ptr); + } + /* Terminate the pthread's ThreadX thread. */ + thread1_ptr = posix_tcb2thread(pthread_ptr); + status = tx_thread_terminate(thread1_ptr); + if (status != TX_SUCCESS) + { + posix_internal_error(2244); + } + + /* Delete the pthread's ThreadX thread. */ + status = tx_thread_delete(&(pthread_ptr->thread_info)); + if (status != TX_SUCCESS) + { + posix_internal_error(2255); + } + /* Free the memory allocated for pthread's stack allocated from the posix heap */ + /* if the memory was not from the posix heap this call has no effect */ + /* it will be the user's responsibility to manage such memory */ + + posix_memory_release(pthread_ptr->stack_address); + + /* Determine if this thread is NOT a signal handler thread. If this is the case, + delete the event flag group. */ + if (pthread_ptr -> signals.signal_handler == FALSE) + { + + /* Delete the event flag group. */ + tx_event_flags_delete(&(pthread_ptr -> signals.signal_event_flags)); + } + + /* Return the pthread's TCB to the pool of available TCB's. */ + pthread_ptr->in_use = TX_FALSE; + + TX_RESTORE + + /* All done. */ + return; +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_set_pthread_errno PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets the pthread error number. */ +/* Each pthread has got its very own erron number. */ +/* */ +/* INPUT */ +/* */ +/* errno_set error number to set */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* OK Always return successful */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify get calling ThreadX thread */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT posix_set_pthread_errno(ULONG errno_set) +{ + +TX_THREAD *thread_ptr; +POSIX_TCB *pthread_ptr; + + /* Get the thread identifier of the currently running thread */ + thread_ptr = tx_thread_identify(); + /* get posix TCB for this pthread */ + pthread_ptr = (POSIX_TCB *)thread_ptr; + /* Set the error number */ + pthread_ptr->perrno = errno_set; + + /* Always return success!*/ + return(OK); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_get_pthread_errno PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the erron number for a pthread. */ +/* Each pthread has got its very own erron number. */ +/* */ +/* INPUT */ +/* */ +/* ptid pthread id */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* error_number error number for the pthread */ +/* ERROR In case of any error */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify get calling ThreadX thread */ +/* */ +/* CALLED BY */ +/* */ +/* posix internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT posix_get_pthread_errno(pthread_t ptid) +{ + +TX_INTERRUPT_SAVE_AREA + +INT error_number; +POSIX_TCB *pthread_ptr; + + TX_DISABLE + + /* Get the POSIX pthread structure pointer for the ptid */ + pthread_ptr = posix_tid2tcb(ptid); + /* Check whether we got NULL pointer */ + if (pthread_ptr) + /* Retrive the stored error number for this pthread */ + error_number = pthread_ptr->perrno; + else + error_number = ERROR; + + TX_RESTORE + return(error_number); +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_join.c b/utility/rtos_compatibility_layers/posix/px_pth_join.c new file mode 100644 index 00000000..791fec6b --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_join.c @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_join PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall suspend execution of the calling thread until */ +/* the target thread terminates, unless the target thread has already */ +/* terminated. On return from a successful pthread_join ( ) call with */ +/* a non-NULL value_ptr argument, the value passed to pthread_exit( ) */ +/* by the terminating thread shall be made available in the location */ +/* referenced by value_ptr. When a pthread_join returns successfully, */ +/* the target thread has been terminated. The results of multiple */ +/* simultaneous calls to pthread_join specifying the same target thread*/ +/* are undefined. If the thread calling pthread_join is canceled, then */ +/* the target thread shall not be detached. */ +/* Eventually, you should call pthread_join() or pthread_detach() for */ +/* every thread that is created joinable (with a detachstate of */ +/* PTHREAD_CREATE_JOINABLE)so that the system can reclaim all resources*/ +/* associated with the thread. Failure to join to or detach joinable */ +/* threads will result in memory and other resource leaks until the */ +/* process ends. If thread doesn't represent a valid undetached thread,*/ +/* pthread_detach() will return ESRCH. */ +/* */ +/* Note: this function must be called from a POSIX context; if it is */ +/* called from ThreadX context an error is returned. */ +/* */ +/* INPUT */ +/* */ +/* thread pthread handle to the target thread */ +/* value_ptr To receive return value of terminating */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* zero If successful */ +/* error number If fails */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_join(pthread_t thread, VOID **value_ptr) + +{ + TX_INTERRUPT_SAVE_AREA + + POSIX_TCB *current_ptr, *target_ptr; + TX_THREAD *target_thread; + + + /* Get the TCB for the currently running pthread */ + current_ptr = posix_thread2tcb(tx_thread_identify()); + + /* Make sure that a TCB was returned. */ + if (!current_ptr) + { + posix_errno = ECANCELED; + posix_set_pthread_errno(ECANCELED); + return(ECANCELED); + } + + /* Check trying to join to self ! */ + if ( current_ptr->pthreadID == thread) + { + posix_errno= EDEADLK; + posix_set_pthread_errno(EDEADLK); + return(EDEADLK); + } + /* Check if calling thread is already joined to other thread */ + + if ( current_ptr->is_joined_to == TX_TRUE) + { + posix_errno= EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + /* Sure, calling pthread can be joined to target pthread */ + + target_thread = posix_tid2thread(thread); + + if (!target_thread) + { + /* Invalid target pthread object */ + posix_errno= ESRCH; + posix_set_pthread_errno(ESRCH); + return(ESRCH); + } + + if ( (target_thread->tx_thread_state == TX_COMPLETED) || (target_thread->tx_thread_state == TX_TERMINATED) ) + { + /* but target pthread is already terminated */ + /* return the return value of the terminated thread */ + target_ptr = posix_tid2tcb(thread); + if(value_ptr)*value_ptr = target_ptr->value_ptr; + return(OK); + } + + /* Now check the target thread, whether it is already joined to any other thread? */ + target_ptr = posix_tid2tcb(thread); + + /* Now check the target thread, whether it is already joined to any other thread? */ + if (target_ptr->is_joined_by == TX_TRUE) + { + /* but target pthread is already terminated */ + posix_errno= EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + /* check joinability of target thread */ + if ( target_ptr->detach_state != PTHREAD_CREATE_JOINABLE) + { + posix_errno= EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + /* Now it is Okay to join */ + + TX_DISABLE + + /* declare that this calling pthread is joined to other pthread */ + current_ptr->is_joined_to = TX_TRUE; + /* register the target pthread */ + current_ptr->joined_to_pthreadID = thread; + /* declare that the target pthread is joined by calling pthread */ + target_ptr->is_joined_by = TX_TRUE; + /* and register the caller pthread with target pthread */ + target_ptr->joined_by_pthreadID = current_ptr->pthreadID ; + + TX_RESTORE + + /* Now calling pthread will suspend itself and wait till target pthread exits */ + tx_thread_suspend ( &(current_ptr->thread_info)); + /* target pthread exited and thus current pthread will resume now */ + /* store return value if value_ptr is valid */ + if(value_ptr)*value_ptr = target_ptr->value_ptr; + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_kill.c b/utility/rtos_compatibility_layers/posix/px_pth_kill.c new file mode 100644 index 00000000..3cf9deb0 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_kill.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_kill PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is used to request that a signal be delivered to */ +/* the specified thread. */ +/* */ +/* INPUT */ +/* */ +/* thread_id Thread ID */ +/* sig Signal */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* posix_in_thread_context Make sure caller is thread */ +/* posix_internal_error Generic error Handler */ +/* tx_event_flags_set */ +/* posix_memory_allocate Create a byte pool for stack */ +/* tx_thread_create */ +/* tx_event_flags_delete */ +/* posix_memory_release */ +/* tx_thread_suspend */ +/* _tx_thread_system_preempt_check */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +int pthread_kill(ULONG thread_id, int sig) +{ + +TX_INTERRUPT_SAVE_AREA + +POSIX_TCB *target_thread; +POSIX_TCB *new_signal_thread; +VOID (*handler)(int); +INT status; +UINT retval; + + + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + return(ERROR); + } + + /* Determine if the desired signal is valid. */ + if ((sig < 0) || (sig > SIGRTMAX)) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(ERROR); + } + + /* Pickup target thread. */ + target_thread = (POSIX_TCB *) thread_id; + + /* Is it non-NULL? */ + if (!target_thread) + { + + /* Invalid target pthread object */ + posix_errno= ESRCH; + posix_set_pthread_errno(ESRCH); + return(ERROR); + } + + /* Pickup signal handler function pointer. */ + handler = target_thread -> signals.signal_func[sig]; + + /* See if there is a signal handler setup for this signal. */ + if (!handler) + { + + /* No handler, just set/clear the event flags to handle the sigwait condition. */ + + /* Set the event flag corresponding the signal. */ + tx_event_flags_set(&(target_thread -> signals.signal_event_flags), (((ULONG) 1) << sig), TX_OR); + + /* Ensure the flag is left in a clear state. */ + tx_event_flags_set(&(target_thread -> signals.signal_event_flags), ~(((ULONG) 1) << sig), TX_AND); + + /* We are done, just return success. */ + return(OK); + } + + /* Now, let's look to see if the same signal is already pending. */ + if (target_thread -> signals.signal_pending.signal_set & (((unsigned long) 1) << sig)) + { + + /* Yes, the same signal is already pending, just return. */ + return(OK); + } + + /* Now determine if the thread's signals are masked by pthread_sigmask. */ + if (target_thread -> signals.signal_mask.signal_set & (((unsigned long) 1) << sig)) + { + + /* Yes, simply set the pending bit so we know that the signal must be activated later when the + signal mask for this signal is cleared. */ + target_thread -> signals.signal_pending.signal_set = target_thread -> signals.signal_pending.signal_set | (((unsigned long) 1) << sig); + return(OK); + } + + /* At this point we know that we need to create a new signal handler thread for processing this signal. */ + + /* Get a pthread control block for this new signal pthread */ + + /* Disable interrupts for protection. */ + TX_DISABLE + + /* Disable preemption temporarily. */ + _tx_thread_preempt_disable++; + + /* Allocate a POSIX thread control block. */ + status = posix_allocate_pthread_t(&new_signal_thread); + + /* Restore interrupts. */ + TX_RESTORE + + /* Make sure we got a new thread control block */ + if ((status == ERROR) || (!new_signal_thread)) + { + + /* Disable interrupts. */ + TX_DISABLE + + /* Enable preemption. */ + _tx_thread_preempt_disable--; + + /* Restore interrupts. */ + TX_RESTORE + + /* Configuration/resource error. */ + posix_set_pthread_errno(EAGAIN); + return(ERROR); + } + + /* Inherit the stack size for the new signal thread. */ + new_signal_thread -> stack_size = target_thread -> stack_size ; + + /* Allocate memory for stack. */ + status = posix_memory_allocate(new_signal_thread -> stack_size, &new_signal_thread -> stack_address); + + /* problem allocating stack space */ + if ((status == ERROR)) + { + + /* Mark the previously allocated control block as available. */ + new_signal_thread -> in_use = FALSE; + + /* Disable interrupts. */ + TX_DISABLE + + /* Enable preemption. */ + _tx_thread_preempt_disable--; + + /* Restore interrupts. */ + TX_RESTORE + + /* Configuration/resource error. */ + posix_set_pthread_errno(EAGAIN); + return(ERROR); + } + + /* Inherit scheduling attributes from base thread. */ + new_signal_thread -> current_priority = target_thread -> current_priority ; + new_signal_thread -> detach_state = target_thread -> detach_state ; + new_signal_thread -> inherit_sched = target_thread -> inherit_sched ; + new_signal_thread -> orig_priority = target_thread -> orig_priority ; + new_signal_thread -> sched_attr.sched_priority= target_thread -> sched_attr.sched_priority ; + new_signal_thread -> pthread_flags = target_thread -> pthread_flags ; + new_signal_thread -> sched_policy = target_thread -> sched_policy; + new_signal_thread -> is_joined_by = TX_FALSE; + new_signal_thread -> joined_by_pthreadID = TX_FALSE; + new_signal_thread -> is_joined_to = TX_FALSE; + new_signal_thread -> joined_to_pthreadID = TX_FALSE; + new_signal_thread -> cancel_state = PTHREAD_CANCEL_ENABLE; + new_signal_thread -> cancel_type = PTHREAD_CANCEL_DEFERRED; + new_signal_thread -> cancel_request = FALSE; + new_signal_thread -> value_ptr = NULL; + + /* Increment the target thread's signal nesting depth. */ + target_thread -> signals.signal_nesting_depth++; + + /* Mark this signal as pending in the signal set. */ + target_thread -> signals.signal_pending.signal_set = target_thread -> signals.signal_pending.signal_set | (((unsigned long) 1) << sig); + + /* Mark the new thread as a signal thread, clear signal info, and setup links. */ + new_signal_thread -> signals.signal_handler = TRUE; + new_signal_thread -> signals.signal_nesting_depth = target_thread -> signals.signal_nesting_depth; + new_signal_thread -> signals.signal_pending.signal_set = target_thread -> signals.signal_pending.signal_set; + new_signal_thread -> signals.saved_thread_state = ((TX_THREAD *) target_thread) -> tx_thread_state; + new_signal_thread -> signals.base_thread_ptr = target_thread; + new_signal_thread -> signals.next_signal_thread = target_thread -> signals.top_signal_thread; + + /* Remember the top signal thread in the base thread. */ + target_thread -> signals.top_signal_thread = new_signal_thread; + + /* Now actually create and start the signal thread. */ + retval = tx_thread_create( (TX_THREAD *) new_signal_thread, + "signal pthr", + internal_signal_dispatch, + (ULONG) sig, + new_signal_thread -> stack_address, + new_signal_thread -> stack_size, + (TX_LOWEST_PRIORITY - new_signal_thread -> current_priority + 1), + (TX_LOWEST_PRIORITY - new_signal_thread -> current_priority + 1), + new_signal_thread -> time_slice, + TX_AUTO_START); + + /* See if ThreadX encountered an error */ + if (retval) + { + + /* Create an event flags group. */ + tx_event_flags_delete(&(new_signal_thread -> signals.signal_event_flags)); + + /* Release the stack memory. */ + posix_memory_release(new_signal_thread -> stack_address); + + /* Mark the previously allocated control block as available. */ + new_signal_thread -> in_use = FALSE; + + /* Disable interrupts. */ + TX_DISABLE + + /* Enable preemption. */ + _tx_thread_preempt_disable--; + + /* Restore interrupts. */ + TX_RESTORE + + /* Internal error */ + posix_error_handler(3333); + posix_set_pthread_errno(EACCES); + return(ERROR); + } + + /* Disable interrupts. */ + TX_DISABLE + + /* Enable preemption. */ + _tx_thread_preempt_disable--; + + /* At this point, we need to suspend the target thread if we are the first signal handler to run. */ + if (new_signal_thread -> signals.signal_nesting_depth == 1) + { + + /* Restore interrupts. */ + TX_RESTORE + + /* Suspend the base thread so that it doesn't run again until all the signals have been processed. */ + tx_thread_suspend((TX_THREAD *) target_thread); + } + else if (new_signal_thread -> signals.next_signal_thread) + { + + /* Restore interrupts. */ + TX_RESTORE + + /* Make sure the current top level signal handler thread is suspended. */ + tx_thread_suspend((TX_THREAD *) new_signal_thread -> signals.next_signal_thread); + } + + /* At this point, the new signal has been set and the signal handler is ready for execution. */ + + /* Check for a preemption condition. */ + _tx_thread_system_preempt_check(); + + /* Return success! */ + return(OK); +} diff --git a/ports/cortex_m23/ac5/src/txe_thread_secure_stack_allocate.c b/utility/rtos_compatibility_layers/posix/px_pth_once.c similarity index 56% rename from ports/cortex_m23/ac5/src/txe_thread_secure_stack_allocate.c rename to utility/rtos_compatibility_layers/posix/px_pth_once.c index 35482b6c..5b24e96b 100644 --- a/ports/cortex_m23/ac5/src/txe_thread_secure_stack_allocate.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_once.c @@ -12,53 +12,55 @@ /**************************************************************************/ /**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ /** */ -/** ThreadX Component */ /** */ -/** Thread */ /** */ /**************************************************************************/ /**************************************************************************/ -#define TX_SOURCE_CODE - - /* Include necessary system files. */ -#include "tx_api.h" -#include "tx_initialize.h" -#include "tx_thread.h" +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _txe_thread_secure_stack_allocate Cortex-M23 */ -/* 6.1 */ +/* pthread_once PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function checks for errors in the secure stack allocate */ -/* function call. */ +/* The pthread_once function shall call the init_routine with no */ +/* arguments. Subsequent calls of pthread_once() with the same */ +/* once_control shall not call the init_routine. On return from */ +/* pthread_once(), init_routine shall have completed. The */ +/* once_control parameter shall determine whether the associated */ +/* initialization routine has been called. */ /* */ /* INPUT */ -/* */ -/* thread_ptr Thread control block pointer */ -/* stack_size Size of secure stack to */ -/* allocate */ +/* once_control */ +/* init_routine */ /* */ /* OUTPUT */ +/* zero If successful */ +/* error number If fails */ /* */ -/* TX_THREAD_ERROR Invalid thread pointer */ -/* TX_CALLER_ERROR Invalid caller of function */ -/* status Actual completion status */ /* */ /* CALLS */ +/* tx_thread_preemption_change */ +/* tx_event_flags_create */ +/* tx_event_flags_set */ +/* tx_event_flags_get */ /* */ -/* _tx_thread_secure_stack_allocate Actual stack alloc function */ /* */ /* CALLED BY */ /* */ @@ -68,52 +70,52 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ /* */ /**************************************************************************/ -UINT _txe_thread_secure_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size) +INT pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID)) { -#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) + INT result; + UINT old_treshold, temp; + + if (once_control == NULL || init_routine == NULL) { - /* Thread pointer is invalid, return appropriate error code. */ - status = TX_THREAD_ERROR; + result = EINVAL; } - - /* Check for interrupt call. */ - if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0)) + else { - /* Is call from an interrupt and not initialization? */ - if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS) + if ( once_control->state==PTH_ONCE_DONE) { - /* Invalid caller of this function, return appropriate error code. */ - status = TX_CALLER_ERROR; + result = 0; + } + + /* suspend preemption */ + tx_thread_preemption_change( tx_thread_identify(), 0, &old_treshold); + + if (once_control->state==PTH_ONCE_INIT) + { + once_control->state=PTH_ONCE_STARTED; + tx_event_flags_create(&(once_control->event),"once flags"); + + /* enable preemption */ + tx_thread_preemption_change( tx_thread_identify(),old_treshold, &temp); + (*init_routine)(); + + tx_event_flags_set(&(once_control->event), PTH_ONCE_INIT, TX_AND); + + once_control->state=PTH_ONCE_DONE; + } + + /* enable preemption */ + tx_thread_preemption_change( tx_thread_identify(),old_treshold, &temp); + + if (once_control->state==PTH_ONCE_STARTED) + { + tx_event_flags_get(&(once_control->event), PTH_ONCE_INIT, TX_AND, &(once_control->flags) ,TX_WAIT_FOREVER); } } - - /* 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 + /* note: this routine will not handle the case where the init routine is a cancellation point */ + return (result); } diff --git a/utility/rtos_compatibility_layers/posix/px_pth_self.c b/utility/rtos_compatibility_layers/posix/px_pth_self.c new file mode 100644 index 00000000..41cff887 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_self.c @@ -0,0 +1,94 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_self PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* */ +/* This function returns thread ID of the calling pthread . */ +/* */ +/* */ +/* */ +/* */ +/* INPUT */ +/* */ +/* Nothing */ +/* */ +/* OUTPUT */ +/* */ +/* thread_ID pthread handle of the calling thread */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +pthread_t pthread_self(VOID) +{ + +TX_THREAD *thread_ptr; +pthread_t thread_ID; + + /* Get the thread identifier of the currently running thread */ + thread_ptr = tx_thread_identify(); + + /* Convert thread identifier to posix thread ID */ + + thread_ID = posix_thread2tid(thread_ptr); + + /* Determine if this thread is actually the signal thread helper. */ + if (((POSIX_TCB *) thread_ptr) -> signals.signal_handler) + { + + /* Yes, override the thread_ID with the non-signal thread ID. */ + thread_ID = (pthread_t) ((POSIX_TCB *) thread_ptr) -> signals.base_thread_ptr; + } + + + /* All done. */ + return(thread_ID); +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_set_default_pthread_attr.c b/utility/rtos_compatibility_layers/posix/px_pth_set_default_pthread_attr.c new file mode 100644 index 00000000..0e49bd64 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_set_default_pthread_attr.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* set_default_pthread_attr PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets default pthread attr w/ default information. */ +/* */ +/* INPUT */ +/* */ +/* attr pthread attr object pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID set_default_pthread_attr(pthread_attr_t *attr) +{ + attr->detach_state =PTHREAD_CREATE_JOINABLE; + attr->inherit_sched =0; + attr->inuse =TX_TRUE; + attr->pthread_flags =0; + attr->sched_attr.sched_priority =31; + attr->sched_policy =0; + attr->stack_address =0; + attr->stack_size = TX_DEFAULT_THREAD_STACK_SIZE; +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_setcancelstate.c b/utility/rtos_compatibility_layers/posix/px_pth_setcancelstate.c new file mode 100644 index 00000000..6e7e1798 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_setcancelstate.c @@ -0,0 +1,103 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_setcancelstate PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* The pthread_setcancelstate()function shall atomically both set the */ +/* calling thread’s cancelability state to the indicated state and */ +/* return the previous cancelability state at the location referenced */ +/* by oldstate.Legal values for state are PTHREAD_CANCEL_ENABLE and */ +/* PTHREAD_CANCEL_DISABLE. */ +/* */ +/* INPUT */ +/* */ +/* state New cancelability state to be set */ +/* oldstate Pointer to old cancelability state */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_setcancelstate (INT state, INT *oldstate) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *thread_ptr; +POSIX_TCB *pthread_ptr; + + /* First check for validity of the new cancel state to be set */ + if ( (state == PTHREAD_CANCEL_ENABLE) || (state == PTHREAD_CANCEL_DISABLE) ) + { + TX_DISABLE + + /* Get the thread identifier of the currently running thread */ + thread_ptr = tx_thread_identify(); + /* get posix TCB for this pthread */ + pthread_ptr = (POSIX_TCB *)thread_ptr; + *oldstate = pthread_ptr->cancel_state; + pthread_ptr->cancel_state = state; + + TX_RESTORE + + return(OK); + } + else + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return (EINVAL); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_setcanceltype.c b/utility/rtos_compatibility_layers/posix/px_pth_setcanceltype.c new file mode 100644 index 00000000..91f7ac2d --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_setcanceltype.c @@ -0,0 +1,102 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_setcanceltype PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* The pthread_setcancelstate()function shall atomically both get the */ +/* calling thread's cancelability type to the indicated type and */ +/* return the previous cancelability type at the location referenced */ +/* by oldtype. Legal values for type are PTHREAD_CANCEL_DEFERRED and */ +/* PTHREAD_CANCEL_ASYNCHRONOUS. */ +/* */ +/* INPUT */ +/* */ +/* type New cancelability type to be set */ +/* oldtype Pointer to old cancelability type */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_setcanceltype (INT type, INT *oldtype) +{ +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *thread_ptr; +POSIX_TCB *pthread_ptr; + + /* First check for validity of the new cancel type to be set */ + if ( ( type == PTHREAD_CANCEL_DEFERRED ) || ( type == PTHREAD_CANCEL_ASYNCHRONOUS ) ) + { + TX_DISABLE + + /* Get the thread identifier of the currently running thread */ + thread_ptr = tx_thread_identify(); + /* get posix TCB for this pthread */ + pthread_ptr = (POSIX_TCB *)thread_ptr; + *oldtype = pthread_ptr->cancel_type; + pthread_ptr->cancel_type = type; + + TX_RESTORE + + return(OK); + } + else + { + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_setschedparam.c b/utility/rtos_compatibility_layers/posix/px_pth_setschedparam.c new file mode 100644 index 00000000..3d6def00 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_setschedparam.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_setschedparam PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function changes the scheduling parameters of a pthread. */ +/* */ +/* */ +/* INPUT */ +/* */ +/* thread POSIX thread ID */ +/* policy Address of the thread attributes */ +/* sched_param Address of structure to contain the */ +/* returned scheduling parameters */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* 0 if successful */ +/* Value in case of any error */ +/* */ +/* CALLS */ +/* */ +/* posix_tid2tcb */ +/* posix_tcb2thread */ +/* tx_thread_priority_change */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT pthread_setschedparam(pthread_t thread, INT policy, const struct sched_param *param) +{ + TX_INTERRUPT_SAVE_AREA + POSIX_TCB *thread_tcb; + TX_THREAD *TheThread; + UINT Tmp; + ULONG UTmp; + + + + thread_tcb=posix_tid2tcb(thread); + + if(thread_tcb==NULL) + { + return(ESRCH); + } + if (!(( policy == SCHED_FIFO )||(policy== SCHED_RR))) + { + return(ENOTSUP); + } + + + TX_DISABLE + thread_tcb->sched_policy=policy; + thread_tcb->sched_attr.sched_priority=param->sched_priority; + thread_tcb->current_priority= param->sched_priority; + + TheThread=posix_tcb2thread(thread_tcb); + + tx_thread_priority_change(TheThread, (TX_LOWEST_PRIORITY - thread_tcb->current_priority + 1),&Tmp); + thread_tcb->orig_priority=(ULONG) Tmp; + + if(policy==SCHED_RR) thread_tcb->time_slice=SCHED_RR_TIME_SLICE; + else thread_tcb->time_slice=0; + tx_thread_time_slice_change(TheThread, thread_tcb->time_slice, &UTmp); + + TX_RESTORE + + return(NO_ERROR); +} + + + + + diff --git a/utility/rtos_compatibility_layers/posix/px_pth_sigmask.c b/utility/rtos_compatibility_layers/posix/px_pth_sigmask.c new file mode 100644 index 00000000..38885c4a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_sigmask.c @@ -0,0 +1,228 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_sigmask PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall examine or change (or both) the calling */ +/* thread's signal mask. */ +/* */ +/* INPUT */ +/* */ +/* how how the set will be changed */ +/* newmask pointer to new set of signals */ +/* oldmask pointer to store previous signals */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* EINVAL If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_set_pthread_errno */ +/* tx_thread_identify */ +/* pthread_kill */ +/* _tx_thread_system_preempt_check */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask) +{ + +TX_INTERRUPT_SAVE_AREA + +ULONG blocked_signals; +ULONG released_signals; +ULONG signal_number; +ULONG previous_mask; +POSIX_TCB *base_thread; +ULONG reissue_flag; + + + /* Check for a valid how parameter. */ + if ((how != SIG_BLOCK) && (how != SIG_SETMASK) & (how != SIG_UNBLOCK)) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + /* Check for valid signal masks. */ + if ((newmask == NULL) || (oldmask == NULL)) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + /* Pickup base thread, since the base thread and all signal threads will pend off the same + event flag group. */ + base_thread = (POSIX_TCB *) tx_thread_identify(); + + /* Is it non-NULL? */ + if (!base_thread) + { + + /* System error! */ + posix_set_pthread_errno(ESRCH); + return(EINVAL); + } + + /* Determine if the current thread is a signal handler thread. */ + if (base_thread -> signals.signal_handler) + { + + /* Pickup target thread. */ + base_thread = base_thread -> signals.base_thread_ptr; + } + + /* Save the current signal mask for return. */ + previous_mask = base_thread -> signals.signal_mask.signal_set; + + /* Now process based on how the mask is to be changed. */ + if (how == SIG_BLOCK) + { + + /* Simply set the mask to block the signal(s). */ + base_thread -> signals.signal_mask.signal_set = base_thread -> signals.signal_mask.signal_set | newmask -> signal_set; + } + else + { + + /* Now calculate the set of currently pending signals there are waiting based on the current mask. */ + blocked_signals = base_thread -> signals.signal_mask.signal_set & base_thread -> signals.signal_pending.signal_set; + + /* Now modify the singal mask correspondingly. */ + if (how == SIG_UNBLOCK) + { + + /* Clear only the signals specified in the new signal mask. */ + base_thread -> signals.signal_mask.signal_set = base_thread -> signals.signal_mask.signal_set & ~(newmask -> signal_set); + } + else + { + + /* Simply set the signal mask to the new signal mask value. */ + base_thread -> signals.signal_mask.signal_set = newmask -> signal_set; + } + + /* Now determine if there are any signals that need to be activated. */ + released_signals = blocked_signals & ~(base_thread -> signals.signal_mask.signal_set); + + /* Are there any signals that need to be activated? */ + if (released_signals) + { + + /* Temporarily disable interrupts. */ + TX_DISABLE + + /* Temporarily disable preemption. */ + _tx_thread_preempt_disable++; + + /* Restore interrupts. */ + TX_RESTORE + + /* Set the reissue flag to false. */ + reissue_flag = TX_FALSE; + + /* Loop to process all the blocked signals. */ + signal_number = 0; + while ((released_signals) && (signal_number < 32)) + { + + /* Determine if this signal was released. */ + if (released_signals & 1) + { + + /* Yes, this signal was released. We need to make it active again. */ + + /* Clear the pending bit so the pthread_kill call will not discard the signal (signals are not queued in this implementation). */ + base_thread -> signals.signal_pending.signal_set = base_thread -> signals.signal_pending.signal_set & ~(((unsigned long) 1) << signal_number); + + /* Call pthread_kill to reissue the signal. */ + pthread_kill((ULONG) base_thread, signal_number); + + /* Set the reissue flag. */ + reissue_flag = TX_TRUE; + } + + /* Look for next signal. */ + released_signals = released_signals >> 1; + signal_number++; + } + + /* Temporarily disable interrupts. */ + TX_DISABLE + + /* Release preemption. */ + _tx_thread_preempt_disable--; + + /* Restore interrupts. */ + TX_RESTORE + + /* Check for a preemption condition. */ + _tx_thread_system_preempt_check(); + + /* Determine if the reissue flag is set. */ + if (reissue_flag == TX_TRUE) + { + + /* Relinquish to allow signal thread at same priority to run before we return. */ + _tx_thread_relinquish(); + } + } + } + + /* Setup return mask. */ + oldmask -> signal_set = previous_mask; + + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_pth_testcancel.c b/utility/rtos_compatibility_layers/posix/px_pth_testcancel.c new file mode 100644 index 00000000..7bd89449 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_testcancel.c @@ -0,0 +1,92 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_testcancel PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* The pthread_testcancel function shall request that thread be */ +/* canceled if the cancel state is enabled and cancel type is */ +/* deferred, and a cancellation request has happened in the past. */ +/* The target thread's cancelability state and type determines when */ +/* the cancellation takes effect. When the cancellation is acted on, */ +/* the cancelation cleanup handlers for thread shall be called. When */ +/* the last cancelation cleanup handler returns, the thread-specific */ +/* data destructor functions shall be called for thread. When the last */ +/* destructor function returns, thread shall be terminated. */ +/* */ +/* INPUT */ +/* */ +/* thread pthread handle to thread to be canceled */ +/* */ +/* OUTPUT */ +/* */ +/* */ +/* */ +/* CALLS */ +/* posix_destroy_thread */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID pthread_testcancel(VOID) +{ + +POSIX_TCB *pthread_ptr; + + + /* Get the thread identifier of the calling pthread */ + pthread_ptr = posix_tid2tcb(pthread_self()); + + /* Check if thread was created with cancel enable */ + if ( (pthread_ptr->cancel_state == PTHREAD_CANCEL_ENABLE) && + (pthread_ptr->cancel_type==PTHREAD_CANCEL_DEFERRED) && + (pthread_ptr->cancel_request==TRUE) ) + { + + /* Signal the housekeeping ThreadX thread to cancel (delete) this pthread */ + posix_destroy_pthread(pthread_ptr,(VOID *)0); + } +} + diff --git a/utility/rtos_compatibility_layers/posix/px_pth_yield.c b/utility/rtos_compatibility_layers/posix/px_pth_yield.c new file mode 100644 index 00000000..f1e953e0 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_pth_yield.c @@ -0,0 +1,82 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* pthread_yield PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This subroutine forces the calling thread to relinquish use of its */ +/* processor,and to wait in the run queue before it is scheduled again.*/ +/* If the run queue is empty when this subroutine is called, the */ +/* calling thread is immediately rescheduled. */ +/* */ +/* INPUT */ +/* */ +/* Nothing */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error posix internal error function */ +/* tx_thread_relinquish ThreadX function */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID pthread_yield(VOID) +{ + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + } + + /* This relinquishes the CPU. */ + tx_thread_relinquish(); +} diff --git a/utility/rtos_compatibility_layers/posix/px_px_initialize.c b/utility/rtos_compatibility_layers/posix/px_px_initialize.c new file mode 100644 index 00000000..19b68aa5 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_px_initialize.c @@ -0,0 +1,276 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_memory_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to create a ThreadX byte pool that will */ +/* act as a "heap" for the POSIX's dynamic, "behind-the-scenes" */ +/* memory needs. */ +/* */ +/* INPUT */ +/* */ +/* reqion0_ptr Pointer to region0 memory */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* tx_byte_pool_create Create region0 byte pool */ +/* posix_internal_error Generic posix error */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static VOID posix_memory_init(VOID * posix_heap_ptr) +{ + +INT retval; + + /* Create a ThreadX byte pool that will provide memory + needed by the POSIX. */ + retval = tx_byte_pool_create((TX_BYTE_POOL *)&posix_heap_byte_pool, + "POSIX HEAP", + posix_heap_ptr, + POSIX_HEAP_SIZE_IN_BYTES); + + /* Make sure the byte pool was created successfully. */ + if (retval) + { + /* Error creating byte pool. */ + posix_internal_error(9999); + } +} + + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_semaphore_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the POSIX's internal semaphore pool. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +static VOID posix_semaphore_init(VOID) +{ + +ULONG i; +sem_t *sem_ptr; + + /* Start at the front of the pool. */ + sem_ptr = &(posix_sem_pool[0]); + + for (i = 0; i < SEM_NSEMS_MAX; i++, sem_ptr++) + { + /* This semaphore is not currently in use. */ + sem_ptr->in_use = TX_FALSE; + sem_ptr->count = 0; + sem_ptr->sem_name = ""; + sem_ptr->refCnt = 0; + sem_ptr->psemId = 0; + sem_ptr->unlink_flag = TX_FALSE; + } +} + + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_initialize PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets up / configures / initializes all the */ +/* "behind-the-scenes" data structures, tables, memory regions, etc. */ +/* used by the POSIX at run-time. */ +/* */ +/* INPUT */ +/* */ +/* posix_memory POSIX memory pointer */ +/* */ +/* OUTPUT */ +/* */ +/* pointer Next free POSIX memory */ +/* */ +/* CALLS */ +/* */ +/* posix_memory_init Initialize posix memory */ +/* tx_thread_create Create System Manager Thread */ +/* tx_queue_create Create system manager queue */ +/* posix_queue_init Initialize posix queues */ +/* posix_qattr_init Initialize mqattr structure */ +/* posix_semaphore_init Initialize posix semaphores */ +/* set_default_mutexattr Set up default mutexattr obj */ +/* posix_pthread_init Initialize a static pool of */ +/* pthreads Control blocks */ +/* set_default_pthread_attr Set defualt pthread_attr obj */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID *posix_initialize(VOID * posix_memory) +{ + +UCHAR *pointer; + + /* Setup temporary memory pointer, so we can start allocating + space for the posix data structures. The important thing to + remember here is that the system thread's stack, the region0 + memory, and the queue are allocated sequentially from the + address specified by posix_memory. */ + + pointer = (UCHAR *)posix_memory; + + /* Start up the System Manager thread. */ + tx_thread_create(&posix_system_manager, "POSIX System Manager", posix_system_manager_entry, + 0, pointer, POSIX_SYSTEM_STACK_SIZE, + SYSMGR_PRIORITY, SYSMGR_THRESHOLD, + TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + POSIX_SYSTEM_STACK_SIZE; + + /* Set up a memory "heap" used internally by the POSIX. */ + posix_memory_init(pointer); + + pointer = pointer + POSIX_HEAP_SIZE_IN_BYTES; + + /* Create the work item message queue. */ + tx_queue_create(&posix_work_queue, "POSIX work queue", WORK_REQ_SIZE, + pointer, WORK_QUEUE_DEPTH*WORK_REQ_SIZE); + + pointer = pointer + (WORK_QUEUE_DEPTH * WORK_REQ_SIZE); + + /* Initialize static pool of pthreads Control blocks. */ + posix_pthread_init(); + + /* Create a default pthread_attr */ + set_default_pthread_attr(&posix_default_pthread_attr); + +#if POSIX_MAX_QUEUES != 0 + /* Set up a pool of message queues used internally by the POSIX. */ + posix_queue_init(); + + /* Set up a pool of q_attr used internally by the POSIX. */ + posix_qattr_init(); +#endif + +#if SEM_NSEMS_MAX != 0 + /* Set up a pool of semaphores used internally by the POSIX. */ + posix_semaphore_init(); +#endif + + /* Create a default mutex_attr */ + set_default_mutexattr(&posix_default_mutex_attr); + + pointer = (VOID *) pointer; + + /* All done. */ + return(pointer); +} diff --git a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c b/utility/rtos_compatibility_layers/posix/px_sched_get_prio.c similarity index 52% rename from ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c rename to utility/rtos_compatibility_layers/posix/px_sched_get_prio.c index a4ebdf5d..024545dc 100644 --- a/ports_module/cortex-m7/ac5/module_manager/src/txm_module_manager_alignment_adjust.c +++ b/utility/rtos_compatibility_layers/posix/px_sched_get_prio.c @@ -12,174 +12,114 @@ /**************************************************************************/ /**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ /** */ -/** ThreadX Component */ /** */ -/** Module Manager */ /** */ /**************************************************************************/ /**************************************************************************/ -#define TX_SOURCE_CODE +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ -#include "tx_api.h" -#include "txm_module.h" /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _txm_power_of_two_block_size Cortex-M7/MPU/AC5 */ -/* 6.1 */ +/* sched_get_priority_max PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function calculates a power of two size at or immediately above*/ -/* the input size and returns it to the caller. */ +/* This routine returns the higest priority available in the system */ +/* Note that in POSIX higher number indicates a higher priority */ /* */ /* INPUT */ /* */ -/* size Block size */ +/* policy */ /* */ /* OUTPUT */ /* */ -/* calculated size Rounded up to power of two */ +/* Maximum Priority If successful */ +/* ERROR If policy not implemented */ /* */ /* CALLS */ /* */ -/* None */ /* */ /* CALLED BY */ /* */ -/* _txm_module_manager_alignment_adjust Adjust alignment for Cortex-M */ +/* Application Code */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ /* */ /**************************************************************************/ -ULONG _txm_power_of_two_block_size(ULONG size) + + +INT sched_get_priority_max(INT policy) { - /* Check for 0 size. */ - if(size == 0) - return 0; - - /* Minimum MPU block size is 32. */ - if(size <= 32) - return 32; - - /* Bit twiddling trick to round to next high power of 2 - (if original size is power of 2, it will return original size. Perfect!) */ - size--; - size |= size >> 1; - size |= size >> 2; - size |= size >> 4; - size |= size >> 8; - size |= size >> 16; - size++; - - /* Return a power of 2 size at or above the input size. */ - return(size); + if (policy==SCHED_FIFO || policy==SCHED_RR ) + return SCHED_PRIO_MAX; + else + return ERROR; } + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _txm_module_manager_alignment_adjust Cortex-M7/MPU/AC5 */ -/* 6.1 */ +/* sched_get_priority_min PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function adjusts the alignment and size of the code and data */ -/* section for a given module implementation. */ +/* This routine returns the lowest priority available in the system */ +/* Note that in POSIX higher number indicates a higher priority */ /* */ /* INPUT */ /* */ -/* module_preamble Pointer to module preamble */ -/* code_size Size of the code area (updated) */ -/* code_alignment Code area alignment (updated) */ -/* data_size Size of data area (updated) */ -/* data_alignment Data area alignment (updated) */ +/* policy */ /* */ /* OUTPUT */ /* */ -/* None */ +/* Minimum Priority If successful */ +/* ERROR If policy not implemented */ /* */ /* CALLS */ /* */ -/* _txm_power_of_two_block_size Calculate power of two size */ /* */ /* CALLED BY */ /* */ -/* Initial thread stack frame */ +/* Application Code */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ /* */ /**************************************************************************/ -VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, - ULONG *code_size, - ULONG *code_alignment, - ULONG *data_size, - ULONG *data_alignment) +INT sched_get_priority_min(INT policy) { - -ULONG local_code_size; -ULONG local_code_alignment; -ULONG local_data_size; -ULONG local_data_alignment; -ULONG code_size_accum; -ULONG data_size_accum; - - /* Copy the input parameters into local variables for ease of use. */ - local_code_size = *code_size; - local_code_alignment = *code_alignment; - local_data_size = *data_size; - local_data_alignment = *data_alignment; - - /* Determine code block sizes. Minimize the alignment requirement. - There are 4 MPU code entries available. The following is how the code size - will be distributed: - 1. 1/4 of the largest power of two that is greater than or equal to code size. - 2. 1/4 of the largest power of two that is greater than or equal to code size. - 3. Largest power of 2 that fits in the remaining space. - 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ - local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2; - code_size_accum = local_code_alignment + local_code_alignment; - code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1); - code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum); - local_code_size = code_size_accum; - - /* Determine data block sizes. Minimize the alignment requirement. - There are 4 MPU data entries available. The following is how the data size - will be distributed: - 1. 1/4 of the largest power of two that is greater than or equal to data size. - 2. 1/4 of the largest power of two that is greater than or equal to data size. - 3. Largest power of 2 that fits in the remaining space. - 4. Smallest power of 2 that exceeds the remaining space, minimum 32. */ - local_data_alignment = _txm_power_of_two_block_size(local_data_size) >> 2; - data_size_accum = local_data_alignment + local_data_alignment; - data_size_accum = data_size_accum + (_txm_power_of_two_block_size(local_data_size - data_size_accum) >> 1); - data_size_accum = data_size_accum + _txm_power_of_two_block_size(local_data_size - data_size_accum); - local_data_size = data_size_accum; - - /* Return all the information to the caller. */ - *code_size = local_code_size; - *code_alignment = local_code_alignment; - *data_size = local_data_size; - *data_alignment = local_data_alignment; + if (policy==SCHED_FIFO || policy==SCHED_RR ) + return SCHED_PRIO_MIN; + else + return ERROR; } diff --git a/utility/rtos_compatibility_layers/posix/px_sched_yield.c b/utility/rtos_compatibility_layers/posix/px_sched_yield.c new file mode 100644 index 00000000..a058d26a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sched_yield.c @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "tx_posix.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sched_yield PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine forces the running thread to relinquish the CPU */ +/* */ +/* INPUT */ +/* */ +/* void . */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR IF fails */ +/* */ +/* CALLS */ +/* */ +/* posix_in_thread_context Checks thread is called from its context.*/ +/* tx_thread_relinquish Relinquishes processor control */ +/* posix_internal_error Returns generic error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sched_yield(VOID) +{ + + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + + /* return error. */ + return (ERROR); + } + + /* This relinquishes the CPU. */ + tx_thread_relinquish(); + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_close.c b/utility/rtos_compatibility_layers/posix/px_sem_close.c new file mode 100644 index 00000000..58c0bd4e --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_close.c @@ -0,0 +1,116 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_close PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine is called to indicate that the calling thread is */ +/* finished with the specified named semaphore, sem. */ +/* */ +/* INPUT */ +/* */ +/* sem type of semaphore */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_internal_error Generic error handler */ +/* posix_sem_reset Resets the semaphore structure */ +/* tx_thread_identify Returns currently running thread */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sem_close(sem_t * sem) +{ + +TX_SEMAPHORE * TheSem; +TX_THREAD * Thethread; + + /* Make sure we're calling this routine from a thread context. */ + Thethread = tx_thread_identify(); + + if (!Thethread) + { + /* Return appropriate error. */ + posix_internal_error(240); + + /* there is no error defined for this in POSIX, hence give default. */ + return(ERROR); + } + + /* Get ThreadX semaphore. */ + TheSem = (TX_SEMAPHORE * )sem; + + /* Check for an invalid semaphore pointer. */ + if ((!TheSem) || (TheSem -> tx_semaphore_id != TX_SEMAPHORE_ID)) + { + + /* Return appropriate error. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + + /* return error. */ + return(ERROR); + } + if(sem) + sem->count -= 1; + + if(! (sem->count) ) + { + + if(sem->unlink_flag == TX_TRUE) + { + posix_sem_reset(sem ); + sem = NULL; + } + } + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_destroy.c b/utility/rtos_compatibility_layers/posix/px_sem_destroy.c new file mode 100644 index 00000000..d6f85a2f --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_destroy.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_destroy PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function destroys a nameless semphore */ +/* Waiting threads will be rescheduled */ +/* No memory will be released */ +/* */ +/* INPUT */ +/* */ +/* sem Semaphore pointer */ +/* */ +/* OUTPUT */ +/* */ +/* EINVAL if error occurs */ +/* EBUSY if threads were waiting */ +/* NO_ERROR successful */ +/* */ +/* CALLS */ +/* */ +/* tx_semaphore_delete deletes actual THreadx semaphore */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sem_destroy(sem_t *sem) + { + INT result; + + if((sem==NULL)|| ( sem->in_use == TX_FALSE)) + { + result = EINVAL; /* general error */ + + } + else + { + if(sem->sem.tx_semaphore_suspended_count > 0 ) result = EBUSY; + else result = NO_ERROR; + tx_semaphore_delete(&(sem->sem)); + sem->in_use = TX_FALSE; + } + + + return result; +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_find_sem.c b/utility/rtos_compatibility_layers/posix/px_sem_find_sem.c new file mode 100644 index 00000000..64061575 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_find_sem.c @@ -0,0 +1,118 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_find_sem PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine returns sem descriptor indicating that name of */ +/* in the semaphore exists. */ +/* */ +/* INPUT */ +/* */ +/* const char * name Name of the semaphore. */ +/* */ +/* OUTPUT */ +/* */ +/* sem If successful */ +/* ERROR IF fails */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +sem_t* posix_find_sem(const CHAR * name) +{ + +sem_t *sem; +ULONG index; +ULONG match; +CHAR *dummy_name; +CHAR *dummy_sem_name; +ULONG namelength; + + /* For checking the name. */ + for(index = 0,sem = posix_sem_pool;index < SEM_NSEMS_MAX;index ++,sem ++) + { + /* Assume the worst case. */ + match = TX_FALSE; + + dummy_sem_name = sem->sem_name; + + for(namelength = 0 ,dummy_name = (CHAR *)name ; namelength < 10 ; + namelength ++, dummy_name++,dummy_sem_name ++) + { + /* Copy name. */ + if(* dummy_name == * dummy_sem_name) + { + /* End of the string. */ + if(* dummy_name == '\0'); + { + match = TX_TRUE; + break; + } + }/* Copy name. */ + else + break; + } + + /* Stop searching. */ + if ( match == TX_TRUE) + { + break; + } + }/* For each semaphore. */ + if(match == TX_TRUE) + { + return(sem); + } + + /* return NULL. */ + sem = NULL; + return(sem); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_get_new_sem.c b/utility/rtos_compatibility_layers/posix/px_sem_get_new_sem.c new file mode 100644 index 00000000..8ee48ce4 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_get_new_sem.c @@ -0,0 +1,99 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_get_new_sem PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function attempts to acquire a ThreadX semaphore from */ +/* the POSIX semaphore pool. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* tx_sem ThreadX semaphore pointer */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +TX_SEMAPHORE * posix_get_new_sem(VOID) +{ + +ULONG i; +TX_SEMAPHORE *tx_sem; +sem_t *sem_ptr; + + /* Loop through the list of semaphores - */ + /* try to find one that is not "in use" */ + /* Start out pessimistic - assume we won't find a match. */ + tx_sem = (TX_SEMAPHORE *)0; + + /* Search the semaphore pool for an available semaphore. */ + for (i = 0, sem_ptr = &(posix_sem_pool[0]); + i < SEM_NSEMS_MAX; + i++, sem_ptr++) + { + /* Make sure the semaphore is not already "in use". */ + if (sem_ptr->in_use == TX_FALSE) + { + + /* Found one! */ + tx_sem = MAKE_TX_SEM(sem_ptr); + + /* This semaphore is now in use. */ + sem_ptr->in_use = TX_TRUE; + + break; + } + } + return(tx_sem); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_getvalue.c b/utility/rtos_compatibility_layers/posix/px_sem_getvalue.c new file mode 100644 index 00000000..7e548c10 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_getvalue.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_getvalue PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine updates the location referenced by the sval argument */ +/* to have the value of the semaphore referenced by sem without */ +/* affecting the state of the semaphore */ +/* */ +/* INPUT */ +/* */ +/* *sem pointer to Semaphore. */ +/* *sval Buffer by which the value is returned. */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR IF fails */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sem_getvalue(sem_t * sem,ULONG * sval) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_SEMAPHORE *TheSem; + + /* get ThreadX semaphore. */ + TheSem = (TX_SEMAPHORE *)sem; + + /* First, check for an invalid semaphore pointer. */ + if ((!TheSem) || (TheSem -> tx_semaphore_id != TX_SEMAPHORE_ID)) + { + /* Return appropriate error. */ + posix_errno=EINVAL; + posix_set_pthread_errno(EINVAL); + /* Return Error. */ + return(EINVAL); + } + + /* Disable interrupts. */ + TX_DISABLE + + * sval = TheSem ->tx_semaphore_count; + + /* Restore Interrupts. */ + TX_RESTORE + + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_init.c b/utility/rtos_compatibility_layers/posix/px_sem_init.c new file mode 100644 index 00000000..6a090198 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_init.c @@ -0,0 +1,98 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "tx_posix.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_init PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes a nameless sempaphore. */ +/* */ +/* INPUT */ +/* */ +/* sem Semaphore pointer */ +/* pshared Shared semphore (TRUE/FALSE) */ +/* value Initial value */ +/* */ +/* OUTPUT */ +/* */ +/* EINVAL if error occurs */ +/* NO_ERROR successful */ +/* */ +/* CALLS */ +/* */ +/* tx_semaphore_create creates actual THreadx semaphore */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sem_init(sem_t *sem , INT pshared, UINT value) +{ + INT result; + + if((sem==NULL)||(value > SEM_VALUE_MAX)||(sem->in_use==TX_TRUE)) + { + result = EINVAL; /* general error */ + + } + else + { + if(tx_semaphore_create(&(sem->sem),"",value)) result = EINVAL; + else + { /* initialize semaphore fields */ + sem->count = 0; + sem->in_use = TX_TRUE; + sem->psemId = 0; + sem->refCnt = value; + sem->sem_name = ""; + sem->unlink_flag =TX_FALSE; + + result = NO_ERROR; + } + } + + + return result; +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_open.c b/utility/rtos_compatibility_layers/posix/px_sem_open.c new file mode 100644 index 00000000..4f0291f0 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_open.c @@ -0,0 +1,256 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_open PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates/initialize a semaphore. */ +/* */ +/* INPUT */ +/* */ +/* name Semaphore name */ +/* oflags Flags */ +/* mode Optional parameter */ +/* value Optional parameter */ +/* */ +/* OUTPUT */ +/* */ +/* sem Semaphore descriptor */ +/* */ +/* CALLS */ +/* */ +/* posix_in_thread_context Make sure caller is thread */ +/* posix_find_sem Finds the required semaphore */ +/* posix_get_new_sem Get new semaphore block */ +/* posix_internal_error Internal posix error */ +/* tx_semaphore_create ThreadX semaphore create */ +/* posix_set_sem_name Sets name for semaphore */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +sem_t * sem_open(const CHAR * name, ULONG oflag, ...) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_SEMAPHORE *TheSem; +sem_t *semid; +ULONG retval; +ULONG len; +sem_t *posix_sem; +va_list vl; +UINT value; +mode_t mode; + + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + + /* return error. */ + return (( sem_t * )SEM_FAILED); + } + + /* Find length of the name. The actual length is not known yet. */ + len = strlen(name); + + if(len > SEM_NAME_MAX) + { + /* Set appropriate errno. */ + posix_errno = ENAMETOOLONG; + posix_set_pthread_errno(ENAMETOOLONG); + + /* Return ERROR. */ + return (( sem_t * ) SEM_FAILED); + } + + /* Check if semaphore exists. */ + if(semid= posix_find_sem( name)) + { + if(semid->unlink_flag ==TX_TRUE ) + { + /* Return error. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return(( sem_t * )SEM_FAILED); + } + } + + /* Semaphore not found. */ + if(!(semid)) + { + /* Check if flag set is O_EXCL. */ + if( oflag == O_EXCL ) + { + + /* Set error for sem does not exist and O_CREAT not set. */ + posix_errno = ENOENT; + posix_set_pthread_errno(ENOENT); + + /* Return the SEM_FAILED error. */ + return(( sem_t * )SEM_FAILED); + } + if( (oflag == O_CREAT) || ( (oflag & (O_CREAT|O_EXCL )) == (O_CREAT|O_EXCL) ) ) + { + + /* Get the variable arguments pointers. */ + + va_start( vl, oflag ); + + mode = va_arg( vl, mode_t); + mode = mode; /* just to keep compiler happy */ + + value = va_arg( vl, ULONG); + + if(value > SEM_VALUE_MAX) + { + /* Semaphore value large. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + + /* Return ERROR */ + return (( sem_t * )SEM_FAILED); + + } + + /* Disable interrupts. */ + TX_DISABLE + + /* Get a new semaphore from the POSIX semaphore pool. */ + TheSem = posix_get_new_sem(); + + /* Make sure we actually got a semaphore. */ + if (!TheSem) + { + /* Semaphore cannot be initialized due to resource constraint. */ + posix_errno = ENOSPC; + posix_set_pthread_errno(ENOSPC); + + /* Restore interrupts. */ + TX_RESTORE + + /* return appropriate error code. */ + return(( sem_t * )SEM_FAILED); + } + + /* Set the semaphore name. */ + posix_set_sem_name((sem_t *)TheSem, ( CHAR * ) name); + + /* Now actually create the ThreadX semaphore. */ + posix_sem = (struct POSIX_SEMAPHORE_STRUCT *)TheSem; + retval = tx_semaphore_create(TheSem, ( CHAR * ) posix_sem->sem_name , value); + + /* Make sure it worked. */ + if (retval) + { + /* Return generic error. */ + posix_internal_error(100); + + /* Restore interrupts. */ + TX_RESTORE + + /* Return appropriate error code. */ + return(( sem_t * )SEM_FAILED); + } + + /* Add the calling thread to the thread list. */ + posix_sem -> count += 1; + + /* Set initial count */ + posix_sem->refCnt = value; + + /* Give the caller the semaphore ID. */ + semid = (sem_t * )TheSem; + + /* Restore interrupts. */ + TX_RESTORE + + /* All done. */ + return(semid); + } + + } + /* Semaphore found. */ + if(semid) + { + + /* Check if flags are O_CREAT|O_EXCL. */ + if( (oflag == O_EXCL) || (oflag & (O_CREAT|O_EXCL )) == (O_CREAT|O_EXCL) ) + { + /* Set appropriate errno. */ + posix_errno = EEXIST; + posix_set_pthread_errno(EEXIST); + + /* Return ERROR. */ + return (( sem_t * ) SEM_FAILED); + } + + /* Check if flag is only O_CREAT. */ + if( (oflag == O_CREAT) || (oflag==0)) + { + /* Disable interrupts. */ + TX_DISABLE + + /* Add the calling thread to the thread list. */ + semid -> count++; + + /* Restore interrupts. */ + TX_RESTORE + + /* Return semaphore. */ + return (( sem_t * ) semid); + } + } + + /* Semaphore value large. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + + /* Return ERROR. */ + return (( sem_t * ) SEM_FAILED); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_post.c b/utility/rtos_compatibility_layers/posix/px_sem_post.c new file mode 100644 index 00000000..a97ab945 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_post.c @@ -0,0 +1,103 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_post PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function releases/puts back a semaphore token. */ +/* */ +/* INPUT */ +/* */ +/* sem semaphore descriptor */ +/* */ +/* OUTPUT */ +/* */ +/* temp1 If successful */ +/* ERROR If fails */ +/* */ +/* CALLS */ +/* */ +/* tx_semaphore_put ThreadX Semaphore put */ +/* posix_internal_error Internal posix error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sem_post(sem_t * sem) +{ + +TX_SEMAPHORE *TheSem; +UINT temp1; + + /* Assign a temporary variable for clarity. */ + TheSem = (TX_SEMAPHORE *)sem; + + if( !TheSem || TheSem->tx_semaphore_id != TX_SEMAPHORE_ID) + { + /* Set appropriate errno. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + /* Return ERROR. */ + return (EINVAL); + } + + /* Place an instance of the semaphore. */ + temp1 = tx_semaphore_put(TheSem); + + /* Make sure the semaphore was incremented. */ + if (temp1 != TX_SUCCESS) + { + + /* return generic error. */ + posix_internal_error(159); + + /* Return ERROR. */ + return (ERROR); + } + + /* All done. */ + return(temp1); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_reset.c b/utility/rtos_compatibility_layers/posix/px_sem_reset.c new file mode 100644 index 00000000..12a897b4 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_reset.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_sem_reset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the POSIX's internal semaphore pool. */ +/* */ +/* INPUT */ +/* */ +/* sem Semaphore pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_sem_reset(sem_t *sem ) +{ + + sem->count = 0; + sem->in_use = TX_FALSE; + sem->psemId = 0; + sem->refCnt = 0; + sem->sem_name = ""; + sem->unlink_flag =TX_FALSE; + return; +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_set_sem_name.c b/utility/rtos_compatibility_layers/posix/px_sem_set_sem_name.c new file mode 100644 index 00000000..4470d53c --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_set_sem_name.c @@ -0,0 +1,75 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_set_sem_name PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gives name to thread */ +/* */ +/* INPUT */ +/* */ +/* sem semaphore descriptor */ +/* name Name to semaphore */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* POSIX internal code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_set_sem_name(sem_t * sem, CHAR *name) +{ + if(sem) + { + sem->sem_name = name; + } + return; +} diff --git a/ports/cortex_m23/ac5/src/txe_thread_secure_stack_free.c b/utility/rtos_compatibility_layers/posix/px_sem_trywait.c similarity index 60% rename from ports/cortex_m23/ac5/src/txe_thread_secure_stack_free.c rename to utility/rtos_compatibility_layers/posix/px_sem_trywait.c index 950e8ec0..d15a2082 100644 --- a/ports/cortex_m23/ac5/src/txe_thread_secure_stack_free.c +++ b/utility/rtos_compatibility_layers/posix/px_sem_trywait.c @@ -12,51 +12,50 @@ /**************************************************************************/ /**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ /** */ -/** ThreadX Component */ /** */ -/** Thread */ /** */ /**************************************************************************/ /**************************************************************************/ -#define TX_SOURCE_CODE - - /* Include necessary system files. */ -#include "tx_api.h" -#include "tx_initialize.h" -#include "tx_thread.h" +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ -/* _txe_thread_secure_stack_free Cortex-M23 */ -/* 6.1 */ +/* sem_trywait PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function checks for errors in the secure stack free */ -/* function call. */ +/* This routine locks(takes) a semaphore if the semaphore is not */ +/* currently locked. */ /* */ /* INPUT */ /* */ -/* thread_ptr Thread control block pointer */ +/* *sem Pointer to Semaphore */ /* */ /* OUTPUT */ /* */ -/* TX_THREAD_ERROR Invalid thread pointer */ -/* TX_CALLER_ERROR Invalid caller of function */ -/* status Actual completion status */ +/* OK If successful */ +/* ERROR If error occurs */ /* */ /* CALLS */ /* */ -/* _tx_thread_secure_stack_free Actual stack free function */ +/* posix_internal_error Returns generic error */ +/* tx_semaphore_get ThreadX Semaphore get */ +/* tx_thread_identify Returns currently running thread */ /* */ /* CALLED BY */ /* */ @@ -66,55 +65,66 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ /* */ /**************************************************************************/ -UINT _txe_thread_secure_stack_free(TX_THREAD *thread_ptr) +INT sem_trywait(sem_t * sem) { -#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; +TX_SEMAPHORE * TheSem; +INT retval; +INT pxerror; + + /* Make sure we're calling this routine from a thread context. */ + if (!tx_thread_identify() ) + { + /* No error in POSIX. */ + posix_internal_error(242); + + /* Return error. */ + return (ERROR); } - /* Now check for invalid thread ID. */ - else if (thread_ptr -> tx_thread_id != TX_THREAD_ID) + /* Get ThreadX semaphore. */ + TheSem = (TX_SEMAPHORE *)sem; + + /* Check for an invalid semaphore pointer. */ + if ((!TheSem) || (TheSem -> tx_semaphore_id != TX_SEMAPHORE_ID)) + { + /* error in POSIX. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + return (EINVAL); + } + else + retval = tx_semaphore_get(TheSem,TX_NO_WAIT); + + switch(retval) { - /* 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) - { + case TX_SUCCESS : - /* Call actual secure stack allocate function. */ - status = _tx_thread_secure_stack_free(thread_ptr); - } + sem->refCnt -= 1; + pxerror = OK; + break; - /* Return completion status. */ - return(status); -#endif + case TX_NO_INSTANCE: + + posix_errno = EAGAIN; + posix_set_pthread_errno(EAGAIN); + pxerror = ERROR; + break; + + case TX_DELETED : + case TX_WAIT_ABORTED : + case TX_SEMAPHORE_ERROR : + case TX_WAIT_ERROR : + + /* No error in POSIX, give default. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + pxerror = ERROR; + break; + } + return(pxerror); } diff --git a/utility/rtos_compatibility_layers/posix/px_sem_unlink.c b/utility/rtos_compatibility_layers/posix/px_sem_unlink.c new file mode 100644 index 00000000..f331b997 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_unlink.c @@ -0,0 +1,112 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_unlink PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This routine removes the string from the semaphore name table ,and */ +/* marks the corresponding semaphore for destruction. */ +/* */ +/* INPUT */ +/* */ +/* name Semaphore name. */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR IF fails */ +/* */ +/* CALLS */ +/* */ +/* posix_find_sem checks the name of semaphore with the names */ +/* of the already created semaphore. */ +/* posix_sem_reset Resets the semaphore structure */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sem_unlink(const CHAR * name) +{ + + +struct POSIX_SEMAPHORE_STRUCT * sem; +ULONG len; + + + /* Checking for the invalid length. */ + len = strlen(name); + + if(len > SEM_NAME_MAX) + { + /* Return appropriate error. */ + posix_errno=ENAMETOOLONG; + posix_set_pthread_errno(ENAMETOOLONG); + /* Return error. */ + return(ERROR); + } + + if(!(sem=posix_find_sem(name))) + { + /* Set error in global variable. */ + posix_errno = ENOENT; + posix_set_pthread_errno(ENOENT); + + /* Return Error. */ + return(ERROR); + } + if(sem) + + sem->unlink_flag =TX_TRUE; + + /* Check for the count. */ + if ((sem->count == 0) ) + { + posix_sem_reset(sem ); + sem = NULL; + } + + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sem_wait.c b/utility/rtos_compatibility_layers/posix/px_sem_wait.c new file mode 100644 index 00000000..b38e2298 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sem_wait.c @@ -0,0 +1,113 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sem_wait PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function locks (takes) a semaphore. */ +/* */ +/* INPUT */ +/* */ +/* *sem Pointer to Semaphore */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify To check whether calling from a thread */ +/* tx_semaphore_get ThreadX Semaphore get */ +/* posix_internal_error Returns a generic error */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +INT sem_wait( sem_t * sem ) +{ + +TX_SEMAPHORE * TheSem; + + + /* Make sure we're calling this routine from a thread context. */ + if (! tx_thread_identify()) + { + /* No wait when called from ISR. */ + posix_internal_error(242); + + /* Return Error. */ + return (ERROR); + } + + /* get ThreadX semaphore. */ + TheSem = (TX_SEMAPHORE *)sem; + + /* Check for an invalid semaphore pointer. */ + if ((!TheSem) || (TheSem -> tx_semaphore_id != TX_SEMAPHORE_ID)) + { + /* error in POSIX. */ + posix_errno = EINVAL; + posix_set_pthread_errno(EINVAL); + + /* Return error. */ + return (EINVAL); + } + else + { + /* Takes the semaphore. */ + if(tx_semaphore_get(TheSem,TX_WAIT_FOREVER)) + { + /* Return general error. */ + posix_internal_error(246); + + /* Return error. */ + return(ERROR); + } + + return (OK); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_sig_addset.c b/utility/rtos_compatibility_layers/posix/px_sig_addset.c new file mode 100644 index 00000000..86982e7d --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sig_addset.c @@ -0,0 +1,87 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sigaddset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function adds the individual signal specified by the signo to */ +/* the signal set pointed to by set. */ +/* */ +/* INPUT */ +/* */ +/* set Pointer to set of signals */ +/* signo Signal */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_set_pthread_errno */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +int sigaddset(sigset_t *set, int signo) +{ + + /* Determine if the desired signal is valid. */ + if ((signo < 0) || (signo > SIGRTMAX)) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(ERROR); + } + + /* All is okay, set the appropriate signal bit. */ + set -> signal_set = set -> signal_set | (((ULONG) 1) << signo); + + /* Return success! */ + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sig_delset.c b/utility/rtos_compatibility_layers/posix/px_sig_delset.c new file mode 100644 index 00000000..de3b55bb --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sig_delset.c @@ -0,0 +1,87 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sigdelset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes the individual signal specified by the signo */ +/* from the signal set pointed to by set. */ +/* */ +/* INPUT */ +/* */ +/* set Pointer to set of signals */ +/* signo Signal */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_set_pthread_errno */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +int sigdelset(sigset_t *set, int signo) +{ + + /* Determine if the desired signal is valid. */ + if ((signo < 0) || (signo > SIGRTMAX)) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(EINVAL); + } + + /* All is okay, clear the appropriate signal bit. */ + set -> signal_set = set -> signal_set & ~(((unsigned long) 1) << signo); + + /* Return success! */ + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sig_emptyset.c b/utility/rtos_compatibility_layers/posix/px_sig_emptyset.c new file mode 100644 index 00000000..0184fd43 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sig_emptyset.c @@ -0,0 +1,85 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sigemptyset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the signal set pointed to by 'set' to 0. */ +/* */ +/* INPUT */ +/* */ +/* set Pointer to set of signals */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_set_pthread_errno */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +int sigemptyset(sigset_t *set) +{ + + /* Is there a pointer. */ + if (!set) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(ERROR); + } + + /* Set the signal set to 0, which is the empty set. */ + set -> signal_set = 0; + + /* Return successful status. */ + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sig_fillset.c b/utility/rtos_compatibility_layers/posix/px_sig_fillset.c new file mode 100644 index 00000000..6af4cd52 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sig_fillset.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sigfillset PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the signal set pointed to by 'set' to */ +/* include all signals. */ +/* */ +/* INPUT */ +/* */ +/* set Pointer to set of signals */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_set_pthread_errno */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +int sigfillset(sigset_t *set) +{ + + /* Is there a pointer. */ + if (!set) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(ERROR); + } + + /* Set all the signals. */ + set -> signal_set = 0xFFFFFFFF; + + /* Return successful status. */ + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sig_signal.c b/utility/rtos_compatibility_layers/posix/px_sig_signal.c new file mode 100644 index 00000000..7e550148 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sig_signal.c @@ -0,0 +1,103 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* signal PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function assigns a function ("signal handler") pointed to by */ +/* func to be invoked when signal signo occurs. */ +/* */ +/* INPUT */ +/* */ +/* set Pointer to set of signals */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* ERROR If error occurs */ +/* */ +/* CALLS */ +/* */ +/* posix_in_thread_context */ +/* posix_internal_error */ +/* posix_set_pthread_errno */ +/* tx_thread_identify */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +int signal(int signo, void (*func)(int)) +{ + +POSIX_TCB *current_thread; + + + /* Make sure we're calling this routine from a thread context. */ + if (!posix_in_thread_context()) + { + /* return POSIX error. */ + posix_internal_error(444); + return(444); + } + + /* Determine if the desired signal is valid. */ + if ((signo < 0) || (signo > SIGRTMAX)) + { + + /* Return an error. */ + posix_set_pthread_errno(EINVAL); + return(ERROR); + } + + /* Now pickup the current thread pointer. */ + current_thread = (POSIX_TCB *) tx_thread_identify(); + + /* Now index into the array of signal handlers and insert this one. */ + current_thread -> signals.signal_func[signo] = func; + + /* Return success! */ + return(OK); +} diff --git a/utility/rtos_compatibility_layers/posix/px_sig_wait.c b/utility/rtos_compatibility_layers/posix/px_sig_wait.c new file mode 100644 index 00000000..0857dab2 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sig_wait.c @@ -0,0 +1,194 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include "tx_thread.h" /* Internal ThreadX thread management. */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sigwait PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function selects a pending signal from set, atomically */ +/* clears it from the system's set of pending signals, and returns the */ +/* signal number in the location referenced by sig. */ +/* */ +/* INPUT */ +/* */ +/* set Pointer to set of signals */ +/* sig Pointer to returned signal number */ +/* */ +/* OUTPUT */ +/* */ +/* OK If successful */ +/* EINVAL If error occurs */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_identify */ +/* posix_internal_error */ +/* pthread_sigmask */ +/* tx_event_flags_get */ +/* TX_LOWEST_SET_BIT_CALCULATE */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +int sigwait(const sigset_t *set, int *sig) +{ + +UINT status; +ULONG signal_bit_map; +ULONG signal_number; +ULONG saved_mask; +ULONG changed_mask; +ULONG pending_signals; +sigset_t original_set; +POSIX_TCB *base_thread; + + + /* Pickup base thread, since the base thread and all signal threads will pend off the same + event flag group. */ + base_thread = (POSIX_TCB *) tx_thread_identify(); + + /* Is it non-NULL? */ + if (!base_thread) + { + + /* System error! */ + posix_internal_error(444); + return(EINVAL); + } + + /* Determine if the current thread is a signal handler thread. */ + if (base_thread -> signals.signal_handler) + { + + /* Pickup target thread. */ + base_thread = base_thread -> signals.base_thread_ptr; + } + + /* Initialize the saved and changed mask values to zero. */ + saved_mask = 0; + changed_mask = 0; + + /* Determine if there are any pending signals that are pertinent to this request. */ + pending_signals = base_thread -> signals.signal_mask.signal_set & base_thread -> signals.signal_pending.signal_set & set -> signal_set; + + /* Are there any. */ + if (pending_signals) + { + + /* Yes, there are signals being masked currently that would satisfy this request. */ + + /* Save the current mask. */ + saved_mask = base_thread -> signals.signal_mask.signal_set; + + /* Calculate the changed mask. */ + changed_mask = saved_mask & ~(set -> signal_set); + + /* Call pthread_sigmask to temporarily unblock these signals which will release them as well. */ + pthread_sigmask(SIG_UNBLOCK, set, &original_set); + + /* Now determine if the changed mask is still in effect, i.e., there wasn't a pthread_sigmask call from any subsequent signal handlers. */ + if (base_thread -> signals.signal_mask.signal_set == changed_mask) + { + + /* Yes, restore the previous signal mask. */ + base_thread -> signals.signal_mask.signal_set = saved_mask; + } + + /* Derived the signal number from the bit map. */ + TX_LOWEST_SET_BIT_CALCULATE(pending_signals, signal_number); + + /* Return the signal number. */ + *sig = (int) signal_number; + + /* Return success! */ + return(OK); + } + + /* Determine if there are any signals that have to be temporarily cleared. */ + if (base_thread -> signals.signal_mask.signal_set & set -> signal_set) + { + + /* Yes, there are signals being masked needed to satisfy this request. */ + + /* Save the current mask. */ + saved_mask = base_thread -> signals.signal_mask.signal_set; + + /* Calculate the changed mask. */ + changed_mask = saved_mask & ~(set -> signal_set); + + /* Apply the changed signal mask. */ + base_thread -> signals.signal_mask.signal_set = changed_mask; + } + + /* Suspend on the signal specified by the input. */ + status = tx_event_flags_get(&(base_thread -> signals.signal_event_flags), (ULONG) set -> signal_set, TX_OR_CLEAR, &signal_bit_map, TX_WAIT_FOREVER); + + /* Determine if we need to restore the signal mask. */ + if ((saved_mask) && (changed_mask == base_thread -> signals.signal_mask.signal_set)) + { + + /* Yes, the signal mask should be restored. */ + base_thread -> signals.signal_mask.signal_set = saved_mask; + } + + /* Check for successful status. */ + if (status == TX_SUCCESS) + { + + /* Derived the signal number from the bit map. */ + TX_LOWEST_SET_BIT_CALCULATE(signal_bit_map, signal_number); + + /* Return the signal number. */ + *sig = (int) signal_number; + + /* Return success! */ + return(OK); + } + else + { + + /* Return error! */ + return(EINVAL); + } +} diff --git a/utility/rtos_compatibility_layers/posix/px_sleep.c b/utility/rtos_compatibility_layers/posix/px_sleep.c new file mode 100644 index 00000000..a307456c --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_sleep.c @@ -0,0 +1,97 @@ +/**************************************************************************/ +/* */ +/* 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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* sleep PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function shall cause the calling thread to be suspended from */ +/* execution until either the number of realtime seconds specified by */ +/* the argument seconds has elapsed */ +/* */ +/* INPUT */ +/* */ +/* seconds Is the number of real-time (as opposed */ +/* to CPU-time) seconds to suspend the */ +/* calling thread. */ +/* */ +/* OUTPUT */ +/* */ +/* number of seconds remaining to sleep */ +/* A nonzero value indicates sleep was */ +/* interrupted. Zero is successful */ +/* completion */ +/* */ +/* */ +/* CALLS */ +/* */ +/* tx_thread_sleep ThreadX thread sleep service */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT sleep(ULONG seconds) +{ + +UINT temp1, temp2, diff, result; + + temp1 = tx_time_get(); + tx_thread_sleep(seconds * CPU_TICKS_PER_SECOND); + temp2 = tx_time_get(); + diff = temp2 - temp1; + + if (diff > (seconds * CPU_TICKS_PER_SECOND)) + { + result = (diff - (seconds * CPU_TICKS_PER_SECOND)); + } + else + { + result = ((seconds * CPU_TICKS_PER_SECOND) - diff); + } + + return (result/CPU_TICKS_PER_SECOND); + +} + diff --git a/utility/rtos_compatibility_layers/posix/px_system_manager.c b/utility/rtos_compatibility_layers/posix/px_system_manager.c new file mode 100644 index 00000000..e359709e --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/px_system_manager.c @@ -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. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** POSIX wrapper for THREADX */ +/** */ +/** */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* posix_system_manager_entry PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This is the System Manager thread for the POSIX> The system */ +/* manager thread cleans up terminated threads and releases */ +/* the stack memory associated with the thread */ +/* */ +/* INPUT */ +/* */ +/* input Not used */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* tx_queue_receive Receive system request */ +/* posix_do_pthread_delete Delete a pthread */ +/* */ +/* CALLED BY */ +/* */ +/* Start-up code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ +VOID posix_system_manager_entry(ULONG input) +{ + +UINT status; +ULONG request[WORK_REQ_SIZE]; + + + /* Avoid compiler warning. */ + if (input) { } + + /* Loop forever, waiting for work requests. */ + while(1) + { + /* Wait forever for the next work request. */ + status = tx_queue_receive(&posix_work_queue, &request, TX_WAIT_FOREVER); + /* Make sure we didn't encounter any trouble. */ + if (status != TX_SUCCESS) + { + /* Hmmmm... should not happen. */ + /* Anywayjust go back and get the next message. */ + continue; + } + /* Go delete the pthread */ + posix_do_pthread_delete((POSIX_TCB *)request[0], (VOID *)request[1] ); + + } /* System Manager forever loop */ +} + diff --git a/utility/rtos_compatibility_layers/posix/readme_release_history.txt b/utility/rtos_compatibility_layers/posix/readme_release_history.txt new file mode 100644 index 00000000..2eb4eaa0 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/readme_release_history.txt @@ -0,0 +1,46 @@ + + px_abs_time_to_rel_ticks.c Casted size_t to ULONG. + + px_clock_gettime.c Casted size_t to ULONG. + + px_clock_settime.c Casted size_t to ULONG. + + px_int.h Removed posix_initialize prototype (moved to tx_posix.h). + + px_nanosleep.c Casted size_t to ULONG. + + tx_posix.h Reduced default object pool sizes, added posix_initialize prototype. + Improved default stack size symbol name + + px_memory_release.c When thread completes and posix_do_pthread_delete() is called, + posix_memory_release() returns with error if stack was not + allocated from the posix pool but rather stack is a static array. + + px_mq_open.c Fixed bug to handle a NULL attribute in mq_open(). + + px_pth_create.c Call to pthread_create() with pthread_attr_t set to NULL or with the + default values as set by pthread_attr_init() has unexpected behavior. + Fixed by adding code to use defaults. + + px_pth_init.c Fixed memory leak when threads are released or killed by + calling posix_reset_pthread after posix_destroy_pthread() + which was not returning memory to the TCB pool + + Fixed bug when trying to join threads from ThreadX context when + there is an illegal pointer convertion + + px_pth_join.c Fixed bug when calling join from ThreadX context to check if called from + a ThreadX context and if so, return error. + + px_sem_init.c Fixed a bug causing Unnamed semaphore init to return error when ThreadX + the semaphore is created correctly. + + + px_sem_open.c Modified error return values as per the Linux man pages. + + px_pth_sigmask.c Modified error return values as per the Linux man pages. + + px_sig_wait.c Modified error return value type from an INT to a UINT and modified the logic + to return the number of seconds remaining in the sleep interval. A return value of + zero is successful completion. + diff --git a/utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt b/utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt new file mode 100644 index 00000000..82977a8c --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt @@ -0,0 +1,362 @@ + POSIX Compliancy Wrapper for Azure RTOS ThreadX + + + +1.0 POSIX Compliancy Wrapper Overview + +The POSIX Compliancy Wrapper supports many of the basic POSIX calls, with +some limitations, and utilizes ThreadX® primitives underneath. This POSIX +compatibility layer should have good performance since it utilizes internal +ThreadX primitives and bypasses basic ThreadX error checking. + + +1.1 POSIX Compliancy Wrapper Source + +The Wrapper source code is designed for simplicity and is comprised of separate source +files for most functions. Including the supplied pthread.h file will import +all the necessary POSIX constants and subroutine prototypes. + + +1.2 POSIX Compliancy Wrapper Documentation + +This document itself serves as a POSIX Compliancy Wrapper User Guide by +providing an overview of the porting process, including various caveats and +pitfalls to watch out for. In addition, each covered POSIX call is documented, +including information about supported/unsupported options, limitations, deviations, +and suggestions on how to work-around any limitations. + + +2.0 Installation + +The POSIX Compliancy Wrapper is easily installed by adding the +the posix library to your current application build. Make sure your application build +references the same header files as the ones the posix library has been built with. +The file pthread.h must be included in your application source where POSIX +calls are required. +Since the POSIX compliancy wrapper does not cover the complete standard, not all prototypes +are provided. Most notably is the header file tx_px_time.h. + +2.1 Initialization + +The POSIX Compliancy Wrapper requires that a special initialization function is called +prior to accessing any POSIX calls. The function to call and its prototype is: + +VOID *posix_initialize(VOID * posix_memory); + +This function is usually called from the application specific ThreadX +initialization routine, tx_application_define(). The memory pointer supplied +to posix_initialize must be a contiguouis reserved section of memory +that has at least the following number of bytes: + + + POSIX_SYSTEM_STACK_SIZE + + TX_REGION0_SIZE_IN_BYTES + /* Region0 size */ + (WORK_QUEUE_DEPTH * WORK_REQ_SIZE) + /* system queue size */ + POSIX_HEAP_SIZE_IN_BYTES + + +These equates are defined in tx_posix.h. The following additional equates +define the number of POSIX objects supported by the POSIX Wrapper (default +value is shown): + + SEM_NSEMS_MAX 100 /* simultaneous POSIX semaphores */ + + SEM_NAME_MAX 10 /* maximum length of name of semaphore */ + + SEM_VALUE_MAX 100 /* max value of semaphore while initialization */ + + POSIX_MAX_QUEUES 32 /* maximum number of simultaneous POSIX + message queues supported */ + + PATH_MAX 10 /* maximum length of name of a message queue */ + + PTHREAD_THREADS_MAX 256 /* define the maximum number of simultaneous + POSIX Pthreads supported. */ + + POSIX_MAX_MUTEX 32 /* define the maximum number of simultaneous + POSIX mutexes sported. */ + + +The function posix_initialize will return a pointer to the next free +available memory location for the application. + + +3.0 POSIX Calls + +Once posix_initialize returns, POSIX calls can be made. +The Threadx POSIX Compliancy Wrapper supports the following POSIX +calls: + +/***********************************************************************/ +/* CALLS RELATED TO POSIX MESSAGE QUEUE */ +/***********************************************************************/ + +INT mq_send(mqd_t mqdes, const char * msg_ptr, + ssize_t msg_len,ULONG msg_prio ); +ssize_t mq_receive(mqd_t mqdes, VOID *pMsg, ssize_t msgLen, + ULONG *pMsgPrio ); +INT mq_unlink(const char * mqName); +INT mq_close(mqd_t mqdes); +mqd_t mq_open(const CHAR * mqName, ULONG oflags,...); + + +/***********************************************************************/ +/* CALLS RELATED TO POSIX SEMAPHORE */ +/***********************************************************************/ + +INT sem_close(sem_t * sem); +INT sem_getvalue(sem_t * sem,ULONG * sval); +sem_t *sem_open(const char * name, ULONG oflag, ...); +INT sem_post(sem_t * sem); +INT sem_trywait(sem_t * sem); +INT sem_unlink(const char * name); +INT sem_wait( sem_t * sem ); +INT sem_init(sem_t *sem , INT pshared, UINT value); +INT sem_destroy(sem_t *sem); + +/***********************************************************************/ +/* CALLS RELATED TO POSIX pthreads */ +/***********************************************************************/ + +INT sched_yield(VOID); +INT pthread_create (pthread_t *thread, + pthread_attr_t *attr, + VOID *(*start_routine)(VOID*),VOID *arg); +INT pthread_detach(pthread_t thread); +INT pthread_join(pthread_t thread, VOID **value_ptr); +INT pthread_equal(pthread_t thread1, pthread_t thread2); +VOID pthread_exit(VOID *value_ptr); +pthread_t pthread_self(VOID); +INT pthread_attr_destroy(pthread_attr_t *attr); +INT pthread_attr_getdetachstate( pthread_attr_t *attr,INT *detachstate); +INT pthread_attr_setdetachstate(pthread_attr_t *attr,INT detachstate); +INT pthread_attr_getinheritsched(pthread_attr_t *attr, INT *inheritsched); +INT pthread_attr_setinheritsched(pthread_attr_t *attr, INT inheritsched); +INT pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param); +INT pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param *param); +INT pthread_attr_getschedpolicy(pthread_attr_t *attr, INT *policy); +INT pthread_attr_setschedpolicy(pthread_attr_t *attr, INT policy); +INT pthread_attr_init(pthread_attr_t *attr); +INT phread_attr_getstackaddr( pthread_attr_t *attr,VOID **stackaddr); +INT phread_attr_setstackaddr(pthread_attr_t *attr,VOID **stackaddr); +INT pthread_attr_getstacksize( pthread_attr_t *attr, ssize_t *stacksize); +INT pthread_attr_setstacksize(pthread_attr_t *attr, ssize_t stacksize); +INT phread_attr_getstack( pthread_attr_t *attr,VOID **stackaddr, + ssize_t *stacksize); +INT phread_attr_setstack( pthread_attr_t *attr,VOID *stackaddr, + ssize_t stacksize); + +INT pthread_mutexattr_gettype(pthread_mutexattr_t *attr, INT *type); +INT pthread_mutexattr_settype(pthread_mutexattr_t *attr, INT type); +INT pthread_mutexattr_destroy(pthread_mutexattr_t *attr); +INT pthread_mutexattr_init(pthread_mutexattr_t *attr); +INT pthread_mutex_destroy(pthread_mutex_t *mutex); +INT pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); +INT pthread_mutex_lock(pthread_mutex_t *mutex ); +INT pthread_mutex_unlock(pthread_mutex_t *mutex ); +INT pthread_mutex_trylock(pthread_mutex_t *mutex); +INT pthread_mutexattr_getprotocol( pthread_mutexattr_t *attr, INT *protocol); +INT pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, INT protocol); +INT pthread_mutexattr_getpshared (pthread_mutexattr_t *attr, INT *pshared); +INT pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, INT pshared); +INT pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout); +INT pthread_setcancelstate (INT state, INT *oldstate); +INT pthread_setcanceltype (INT type, INT *oldtype); +INT pthread_cancel(pthread_t thread); +VOID pthread_yield(VOID); +VOID pthread_testcancel(VOID); +INT pthread_getschedparam(pthread_t thread, INT *policy, struct sched_param *param); +INT pthread_setschedparam(pthread_t thread, INT policy, const struct sched_param *param); + +INT sched_get_priority_max(INT policy) +INT sched_get_priority_min(INT policy) + +INT pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID)) + +INT pthread_kill(ULONG thread_id, int sig) +INT pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask) + + +/***********************************************************************/ +/* CALLS RELATED TO POSIX CONDITION VARIABLE */ +/***********************************************************************/ + +INT pthread_cond_destroy(pthread_cond_t *cond); +INT pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr); +INT pthread_cond_broadcast(pthread_cond_t *cond); +INT pthread_cond_signal(pthread_cond_t *cond); +INT pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, + struct timespec *abstime); +INT pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); + + +/***********************************************************************/ +/* CALLS RELATED TO Timer */ +/***********************************************************************/ + +INT nanosleep(struct timespec *req, struct timespec *rem) +INT sleep(ULONG seconds) +INT clock_gettime(clockid_t t, struct timespec * tspec) +INT clock_settime(clockid_t t, const struct timespec * tspec) +INT clock_getres(clockid_t t, struct timespec * tspec) + +/***********************************************************************/ +/* CALLS RELATED TO Signal */ +/***********************************************************************/ + +INT sigwait(const sigset_t *set, int *sig) +INT sigaddset(sigset_t *set, int signo) +INT sigdelset(sigset_t *set, int signo) +INT sigemptyset(sigset_t *set) +INT signal(int signo, void (*func)(int)) +INT sigfillset(sigset_t *set) + + +4.0 POSIX Compliancy Wrapper Error Handling + +There are two "error handling" functions defined in tx_posix.c and used +throughout the Wrapper, as follows: + + posix_error_handler + posix_internal_error + +In general these routines are called when basic usage errors occur. These +routines may also be used as a place to catch errors that are not detected if the +application source is not checking the return status. The default processing for each of +these is a simple spin loop. + +Most functions can provide an error number. The means by which each function +provides its error numbers is specified in its description. Some functions +provide the error number in a variable accessed through the symbol posix_errno. +While other functions return an error number directly as the function value. Functions +return a value of zero to indicate success. If more than one error occurs in +processing a function call, any one of the possible errors may be returned, as the order +of detection is undefined. + +Some functions may return [ENOSYS] suggesting that an attempt was made to +use a function that is not available in this implementation. + +Each pthread has its own error number, which can be obtained through a +function call: + +INT posix_get_pthread_errno(pthread_t ptid) + +This call will return the last generated error code for the pthread having +ptid as an ID. + + +5.1 POSIX Compliancy Wrapper Limitations + +Due to performance and architecture issues, this POSIX Compliancy Wrapper +does not support all the POSIX calls. A summary of the POSIX Compliancy +Wrapper limitations is as follows: + +· Configuration +· Initialization +· Driver and I/O model might require porting of current drivers. +· Multi-processor extensions are not supported +· Unsupported calls (please see below) +. Calls supported with certain limitations (please see list below) + +The POSIX Compliancy Wrapper supports a subset of POSIX calls. In addition, +there are also certain limitations with respect to some services. Below is the list of +such limitations: + + +LIMITATIONS + +Following calls are implemented with some limitations: + +1.) mq_open() + + LIMITATIONS : + a.) The value of mode (mode_t) has no effect in this implementation. + b.) If pAttr is NULL, the message queue is created with + implementation-defined default message queue attributes. + The default message queue attributes selected are : + + #define MQ_MAXMSG 125 [MQ_MAXMSG 1024 (POSIX value)] + #define MQ_MSGSIZE 500 [MQ_MSGSIZE 4096 (POSIX value)] + #define MQ_FLAGS 0 + + This is due to limitation of size of posix_region0_byte_pool (64KB ). + +2.) mq_send() + + LIMITATIONS : + a.) In POSIX : If more than one mq_send() is blocked on a queue and + space becomes available in that queue, the message with the highest + priority will be unblocked. THIS FEATURE IS NOT IMPLEMENTED. + + b.) If a message is sent (or received) to a queue with out opening the named + queue, in such a case mqdes (message queue descriptor) pointer is + invalid and may result in erratic behavior. + +3.) mq_receive() + + LIMITATIONS : + a.) If a receive (or send) message from queue with out it being opened, erratic + behavior may ensue. + +4.) ULONG sem_close() + + LIMITATIONS : + a.) This routine does not deallocate any system resources. + +5.) POSIX SEMAPHORE + + LIMITATIONS : + a.) If any operation (eg. sem_post, sem_wait, sem_trywait, sem_getvalue ) is done on a + semaphore before creating or opening (sem_open()) the named semaphore, erratic + behavior may result. + +6.) ULONG sem_trywait(sem_t * sem) + + LIMITATIONS : + + a.) EDEADLKA :->[ This is a return value when deadlock condition is detected; i.e., two separate + processes are waiting for an available resource to be released via a + semaphore "held" by the other process.] This is not implemented. + + b.) EINTR :->[ This is a return value when sem_wait() was interrupted by a signal.] + This is not implemented. +7.) Thread Cancelation + +pthread cancelation cleanup handlers are not supported which means +pthread_cleanup_push( ) and pthread_cleanup_pop( ) functions are not +implemented. + +When the pthread_cancel( ) function is called the target thread is canceled +with immediate effect. (provided cancelability is enabled for the target +pthread) + +The cancelation processing in the target thread shall run asynchronously +with respect to the ailing thread returning from pthread_cancel( ). + +8.) Attributes for Condition Variable + No attributes are supported for condition variable in this implementation. + +9.) pthreads suspended by nanosleep() and sleep() calls can not be awakened +by signals, once in the suspension both these calls will complete the +suspension period. + +10.) pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID)) +There is no provision if the init_routine contains a cancellation point. + + +6.0 Demonstration System + +The file posix_demo.c contains a demonstration system that utilizes POSIX +calls. This Demo application will demonstrate some of the basic POSIX +calls. This demo application should be used as an example of how to integrate the POSIX +Compliancy Wrapper into your application. + + +7.0 Future POSIX Compliancy Wrapper Phases + +Please get in touch with us for next phases of this POSIX Compliancy +Wrapper. + + + + diff --git a/ports/cortex_m23/ac5/inc/tx_secure_interface.h b/utility/rtos_compatibility_layers/posix/sched.h similarity index 67% rename from ports/cortex_m23/ac5/inc/tx_secure_interface.h rename to utility/rtos_compatibility_layers/posix/sched.h index 976f32be..732e313b 100644 --- a/ports/cortex_m23/ac5/inc/tx_secure_interface.h +++ b/utility/rtos_compatibility_layers/posix/sched.h @@ -9,52 +9,57 @@ /* */ /**************************************************************************/ - /**************************************************************************/ /**************************************************************************/ /** */ -/** ThreadX Component */ +/** ThreadX Component */ /** */ -/** Thread */ +/** POSIX Compliancy Wrapper (POSIX) */ /** */ /**************************************************************************/ /**************************************************************************/ - /**************************************************************************/ /* */ -/* COMPONENT DEFINITION RELEASE */ +/* EKP DEFINITIONS RELEASE */ /* */ -/* tx_secure_interface.h Cortex-M23 */ -/* 6.1 */ +/* sched.h PORTABLE C */ +/* 6.x */ /* AUTHOR */ /* */ -/* Scott Larson, Microsoft Corporation */ +/* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This file defines the ThreadX secure thread stack components, */ -/* including data types and external references. */ -/* It is assumed that tx_api.h and tx_port.h have already been */ -/* included. */ +/* This file defines the constants, structures, etc.needed to */ +/* implement the Evacuation Kit for POSIX Users (POSIX) */ +/* */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ /* */ /**************************************************************************/ -#ifndef TX_SECURE_INTERFACE_H -#define TX_SECURE_INTERFACE_H +#ifndef _SCHED_H +#define _SCHED_H -/* Define internal secure thread stack function prototypes. */ -extern void _tx_thread_secure_stack_initialize(void); -extern UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size); -extern UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr); -extern void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr); -extern void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr); +struct sched_param +{ + INT sched_priority; +}; + + +#define SCHED_FIFO 0 +#define SCHED_RR 1 +#define SCHED_OTHER SCHED_RR + +INT sched_get_priority_max(INT policy); +INT sched_get_priority_min(INT policy); + +INT sched_yield(void); #endif diff --git a/utility/rtos_compatibility_layers/posix/signal.h b/utility/rtos_compatibility_layers/posix/signal.h new file mode 100644 index 00000000..8d48ff9d --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/signal.h @@ -0,0 +1,117 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** POSIX Compliancy Wrapper (POSIX) */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKP DEFINITIONS RELEASE */ +/* */ +/* signal.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc.needed to */ +/* implement signals functionality for POSIX Users (POSIX) */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef _SIGNAL_H +#define _SIGNAL_H + + +/* The POSIX wrapper for ThreadX supports a maximum of 32 signals, from 0 + through 31, inclusive. In this implemenation, signals are NOT queued. */ + + +/* Define constants for the signal implementation. */ + +#define MAX_SIGNALS 32 +#define SIGRTMIN 0 +#define SIGRTMAX 31 +#define SIG_DFL (void *) 0 +#define SIG_IGN (void *) 0 +#define SIG_BLOCK 1 +#define SIG_SETMASK 2 +#define SIG_UNBLOCK 3 + + +/* Define the typdefs for this signal handling implementation. */ + + +/* Define the type that holds the desired signals. */ + +typedef struct sigset_t_struct +{ + unsigned long signal_set; +} sigset_t; + + +/* Define the type that keeps track of information in the POSIX thread control block. POSIX threads are used to simulate the behavior + of POSIX signals in this implemenation. */ + +struct pthread_control_block; +struct pthread_t_variable; + +typedef struct signal_info_struct +{ + + UINT signal_handler; /* This is a flag. If TRUE, this thread is being used as a signal handler. If FALSE, it is a regular thread. */ + UINT signal_nesting_depth; /* A positive value indicates the level of nested signal handling the POSIX thread is currently processing. */ + sigset_t signal_pending; /* Bit map of signals pending. */ + sigset_t signal_mask; /* Signal mask, bit blocks the signal until cleared. */ + UINT saved_thread_state; /* Saved ThreadX state of the POSIX thread, at the time of the first signal. */ + struct pthread_control_block *base_thread_ptr; /* Pointer to the thread associated with the signal. */ + struct pthread_control_block *top_signal_thread; /* Pointer to the top (most recent) signal thread. */ + struct pthread_control_block *next_signal_thread; /* Pointer to the next most recent signal thread. */ + void (*signal_func[MAX_SIGNALS])(int); /* Array of signal handlers for this thread. */ + TX_EVENT_FLAGS_GROUP signal_event_flags; /* ThreadX event flag group used for sigwait */ + +} signal_info; + + +/* Define public POSIX routines. */ + +int signal(int signo, void (*func)(int)); +int pthread_kill(ULONG thread, int sig); +int sigwait(const sigset_t *set, int *sig); +int sigemptyset(sigset_t *set); +int sigaddset(sigset_t *set, int signo); +int sigfillset(sigset_t *set); +int sigdelset(sigset_t *set, int signo); +int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask); + + +/* Define internal POSIX routines. */ + +void internal_signal_dispatch(ULONG id); + + +#endif diff --git a/utility/rtos_compatibility_layers/posix/time.h b/utility/rtos_compatibility_layers/posix/time.h new file mode 100644 index 00000000..e67e6a41 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/time.h @@ -0,0 +1,83 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** POSIX Compliancy Wrapper (POSIX) */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKP DEFINITIONS RELEASE */ +/* */ +/* tx_px_time.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc. needed to */ +/* implement time related functionality for the Evacuation Kit */ +/* for POSIX Users (POSIX) */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef _TX_PX_TIME_H +#define _TX_PX_TIME_H + +#ifndef _TIME_T +#define _TIME_T +typedef ULONG time_t; +#endif + +typedef INT clockid_t; + +struct timespec +{ + time_t tv_sec; /* time in terms of seconds */ + ULONG tv_nsec; /* remaining time in terms of nano seconds*/ +} ; + +struct itimerspec +{ + struct timespec it_interval ; /* Timer period. */ + struct timespec it_value; /* Timer expiration. */ +}; + +#define CLOCK_REALTIME 1 +#define TIMER_ABSTIME 1 +#define CLOCK_MONOTONIC 2 + +INT clock_settime(clockid_t, const struct timespec *); +INT clock_gettime(clockid_t, struct timespec *); +INT clock_getres(clockid_t, struct timespec *); + + +INT nanosleep(struct timespec *req, struct timespec *rem); +UINT sleep(ULONG seconds); + +#endif + + diff --git a/utility/rtos_compatibility_layers/posix/tx_posix.h b/utility/rtos_compatibility_layers/posix/tx_posix.h new file mode 100644 index 00000000..e0208807 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/tx_posix.h @@ -0,0 +1,564 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** POSIX Compliancy Wrapper (POSIX) */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKP DEFINITIONS RELEASE */ +/* */ +/* tx_posix.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc.needed to */ +/* implement the Evacuation Kit for POSIX Users (POSIX) */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef TX_POSIX +#define TX_POSIX + +#include +#include +#include + +/************************************************************************/ +/* Macros to convert between semaphore, queue, scheduler */ +/************************************************************************/ +#define MAKE_TX_SEM(sem) ((TX_SEMAPHORE *)sem) +#define MAKE_POSIX_QUEUE(queue) ((POSIX_MSG_QUEUE *)queue) +#define MAKE_POSIX_SEM(sem) ((sem_t *)sem) + +/************************************************************************/ +/* Define max values for message queue services */ +/************************************************************************/ +#define MQ_MAXMSG 125 /* MQ_MAXMSG 1024 (POSIX value). */ +#define MQ_MSGSIZE 500 /* MQ_MSGSIZE 4096 (POSIX value) */ +#define MQ_FLAGS 0 +#define MQ_PRIO_MAX 32 /* Maximum priority of message. */ + +/************************************************************************/ +/* Global Variables */ +/************************************************************************/ + +/* to errno.h +#ifndef TX_POSIX_SOURCE +#define errno posix_errno +#endif +*/ + +/* Define the system configuration constants for the Evacuation Kit for + POSIX Users.This is where the number of system objects + (pthreads, message queues, semaphores etc.)are defined. */ + +/************************************************************************/ +/* SYSTEM CONFIGURATION PARAMETERS */ +/************************************************************************/ + +/* Define the maximum number of simultaneous POSIX semaphores + supported. */ +#define SEM_NSEMS_MAX 16 + +/* Define the maximum length of name of semaphore . */ +#define SEM_NAME_MAX 10 + +/* Max value of semaphore while initialization. */ +#define SEM_VALUE_MAX 100 + +/* Define the maximum number of simultaneous POSIX message queues supported. */ + +#define POSIX_MAX_QUEUES 16 + +/* Define the maximum number of simultaneous POSIX pthreads supported. */ +#define PTHREAD_THREADS_MAX 16 + +/* Define the maximum number of simultaneous POSIX mutexes supported. */ + +#define POSIX_MAX_MUTEX 16 + +/* Define the maximum length of name of message queue. */ +#define PATH_MAX 10 + + +/* Define size of the posix heap memory segment. */ +/* NOTE: This region should be large enough to supply the memory */ +/* for all pthread stacks, pthread control blocks in the system */ + +#define TX_DEFAULT_THREAD_STACK_SIZE 2048 +#define TX_REGION0_CONSTANT 14 +#define TX_REGION0_SIZE ( (TX_DEFAULT_THREAD_STACK_SIZE+16) * TX_REGION0_CONSTANT) + +#define POSIX_HEAP_SIZE_IN_BYTES (TX_REGION0_SIZE * 4) + + + + +/* Define number of CPU ticks per second */ +#define CPU_TICKS_PER_SECOND 100 /* assuming 10 mSec tick */ +#define NANOSECONDS_IN_CPU_TICK 10000000 /* assuming 10 mSec tick */ + +/* Define queue control specific data definitions. */ + +#define TX_SEMAPHORE_ID 0x53454D41UL +#define TX_QUEUE_ID 0x51554555UL +#define PX_QUEUE_ID 0x51554555UL +#define TX_MUTEX_ID 0x4D555445UL + +/************************************************************************/ +/* Misc. POSIX-related definitions . */ +/************************************************************************/ +#define POSIX_STACK_PADDING 1024 +#define POSIX_SYSTEM_STACK_SIZE 1024 +#define POSIX_PTHREAD_STACK_SIZE 1024 + +/************************************************************************/ +/* ARCHITECTURE DEFINITIONS */ +/************************************************************************/ +/* Define all supported architectures here. */ + +#define POSIX_POWERPC 1 +#define POSIX_68K 2 +#define POSIX_ARM 3 +#define POSIX_MIPS 4 + +/* Define POSIX_ARCH as one of the above list. */ + +#define POSIX_ARCH POSIX_POWERPC + +/* Make sure POSIX_ARCH is defined. */ + +#ifndef POSIX_ARCH +#error Must define symbol POSIX_ARCH to *something*! +#endif + +/* Define the minimum stack size for each supported architecture here. */ + +#define MIN_STACKSIZE_POWERPC 2048 + +/************************************************************************/ +/* MISCELLANEOUS CONSTANTS */ +/************************************************************************/ +/* Requests/commands to SysMgr task. */ + +#define SYSMGR_DELETE_TASK 0 + +/* pthread name length */ +#define PTHREAD_NAME_LEN 4 + +#define PTHREAD_CREATE_DETACHED 1 +#define PTHREAD_CREATE_JOINABLE 0 + +/* scheduler related constants */ + +#define SCHED_PRIO_MAX 31 +#define SCHED_PRIO_MIN 1 + +/* time slice value in ticks for round robin scheduler */ +#define SCHED_RR_TIME_SLICE 20 + +#define PTHREAD_MUTEX_NORMAL 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_ERRORCHECK 3 +#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_RECURSIVE + +#define PTHREAD_PRIO_INHERIT 1 + +#define PTHREAD_PROCESS_PRIVATE 1 +#define PTHREAD_PROCESS_SHARED 2 + +#define PTHREAD_CANCEL_ENABLE 0 /* default */ + +#define PTHREAD_CANCEL_DISABLE 1 + +#define PTHREAD_CANCEL_DEFERRED 0 /* default */ + +#define PTHREAD_CANCEL_ASYNCHRONOUS 1 + +#define PTHREAD_INHERIT_SCHED 1 + +#define PTHREAD_EXPLICIT_SCHED 0 + +#define PTHREAD_ONCE_INIT {0, 0, {0,NULL,0,0,NULL,0,NULL,NULL}} + +enum pth_once_state { + PTH_ONCE_INIT = 0x0, + PTH_ONCE_DONE = 0x1, + PTH_ONCE_STARTED = 0x2, + PTH_ONCE_CANCELLED = 0x3 +}; + +/************************************************************************/ +/* ERROR CODES (those defined outside of POSIX) */ +/************************************************************************/ + +#ifdef ERROR +#undef ERROR +#define ERROR -1 +#else +#define ERROR -1 +#endif + +#define NO_ERROR 0 + +/* From semaphore.h, when px_sem_open fails: */ +#define SEM_FAILED ((sem_t *) 0) + +#ifndef _WIN32 +typedef ULONG BOOL; +#endif + + +#ifndef OK +#define OK 0 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* these constants control internal working of the systemmanager thread */ + +#define WORK_REQ_SIZE TX_2_ULONG +#define WORK_QUEUE_DEPTH 10 + +#define SYSMGR_PRIORITY 0 +#define SYSMGR_THRESHOLD 0 + + +/* STRUCTURES RELATED TO pthreads */ + + + +typedef struct pthread_attr_obj +{ + ULONG pthread_flags; + INT detach_state; + INT inherit_sched; + INT sched_policy; + struct sched_param sched_attr; + VOID *stack_address; + ULONG stack_size; + INT inuse; +} pthread_attr_t; + + +typedef INT ssize_t ; /* this should be pulled in from sys\types.h */ +typedef ULONG pthread_t; +typedef ULONG mode_t; + + + +/* Define POSIX Pthread control block tructure. */ + +typedef struct pthread_control_block +{ + /* This pthread's ThreadX TCB. */ + TX_THREAD thread_info; + /* This pthread's unique identifier */ + pthread_t pthreadID; + /* To check if posix Pthread is in use. */ + UINT in_use; + /* All pthread attributes contained in the a pthread_attr_t object */ + ULONG pthread_flags; + INT detach_state; + INT inherit_sched; + INT sched_policy; + struct sched_param sched_attr; + VOID *stack_address; + ULONG stack_size; + INT cancel_state; + INT cancel_type; + /* Identifier of the target thread to which this pthread is joined */ + pthread_t joined_to_pthreadID; + /* Identifier of the caller thread which has joined to this thread*/ + pthread_t joined_by_pthreadID; + /* To check if posix pthread is joined to any other pthread */ + UINT is_joined_to; + /* To check if posix Pthread is joined by any other pthread */ + UINT is_joined_by; + /* To check if posix Pthread is in detached state or not */ + UINT is_detached; + /* Value returned by the terminating thread which is joined to this thread */ + VOID *value_ptr; + /* Define the original pthread priority. */ + ULONG orig_priority; + /* Define the current pthread priority. */ + ULONG current_priority; + /* Define the pthread's pre-emption threshold. */ + ULONG threshold; + /* Define the pthread's timeslice. */ + ULONG time_slice; + /* specify pthread start routine */ + VOID *(*start_routine)(VOID *); + /* specify argument for start up routine */ + ULONG *entry_parameter; + /* to hold error code for this pthread */ + ULONG perrno; + /* to hold pthread cancel request */ + UINT cancel_request; + + /* Signal information follows. */ + signal_info signals; + +}POSIX_TCB; + +typedef struct pthread_mutex_attr_obj +{ + INT type; + INT protocol; + INT pshared; + INT in_use; + +} pthread_mutexattr_t; + +/* Define POSIX mutex structure. */ + +typedef struct pthread_mutex_control_block +{ + /* This mutex's ThreadX Control block */ + TX_MUTEX mutex_info; + /* This mutex's attributes */ + INT type; + /* Is this Mutex object is in use? */ + INT in_use; + +} pthread_mutex_t; + + +/* STRUCTURES RELATED TO POSIX MESSAGE QUEUE */ + + +struct mq_attr +{ + /* No. of maximum messages. */ + ULONG mq_maxmsg; + /* Size of the message. */ + ULONG mq_msgsize; + /* Flags are ignored as these are passed separately in open(). */ + ULONG mq_flags; +}; + +/* Define POSIX message queue structure. */ +typedef struct msg_que +{ + /* Define ThreadX queue. */ + TX_QUEUE queue; + /* To check if posix queue is in use. */ + UINT in_use; + /* To check if queue is unlinked. */ + UINT unlink_flag; + /* Name of queue. */ + CHAR * name; + /* Attribute of queue. */ + struct mq_attr q_attr; + /* To check no. of times queue is opened. */ + UINT open_count; + /* Address for variable length message. */ + VOID * storage; + /* Byte pool for variable length message. */ + TX_BYTE_POOL vq_message_area; + /* POSIX queue ID. */ + ULONG px_queue_id; + +}POSIX_MSG_QUEUE; + +/* Define Queue Descriptor. */ +typedef struct mq_des +{ + /* Queue FLAGS. */ + ULONG f_flag; + /* message Queue structure. */ + POSIX_MSG_QUEUE * f_data; + +} *mqd_t; + + +/* STRUCTURES RELATED TO POSIX SEMAPHORES */ + +typedef struct POSIX_SEMAPHORE_STRUCT +{ + /* ThreadX semaphore. */ + TX_SEMAPHORE sem; + /* To check if semaphore is in use. */ + UINT in_use; + /* semaphore identifier */ + ULONG psemId; + /* number of attachments */ + ULONG refCnt; /* previously it was int */ + /* name of semaphore */ + char * sem_name; + /* Open Count. */ + ULONG count; + /* For unlink flag. */ + ULONG unlink_flag; + +} sem_t; + +typedef sem_t *SEM_ID; + +typedef struct pthread_cond_obj +{ + /* This pthread condition variable's internal counting Semaphore */ + TX_SEMAPHORE cond_semaphore; + + INT type; + INT in_use; + +} pthread_cond_t; + +typedef struct pthread_condattr_obj +{ +/* INT type; */ + INT in_use; + +} pthread_condattr_t; + + + +typedef struct pthread_once_obj +{ + UINT state; + ULONG flags; + TX_EVENT_FLAGS_GROUP event; +}pthread_once_t; + + +/* Define extern for errno variable. */ + +extern unsigned int posix_errno; + + + +/* Define POSIX initialize prototype. */ + +VOID *posix_initialize(VOID * posix_memory); + +/* Define POSIX API function prototypes. */ + +INT mq_send(mqd_t mqdes, const char * msg_ptr, + size_t msg_len,ULONG msg_prio ); +ssize_t mq_receive(mqd_t mqdes, VOID *pMsg, size_t msgLen, + ULONG *pMsgPrio ); +INT mq_unlink(const char * mqName); +INT mq_close(mqd_t mqdes); +mqd_t mq_open(const CHAR * mqName, ULONG oflags,...); +INT sem_close(sem_t * sem); +INT sem_getvalue(sem_t * sem,ULONG * sval); +sem_t *sem_open(const char * name, ULONG oflag, ...); +INT sem_post(sem_t * sem); +INT sem_trywait(sem_t * sem); +INT sem_unlink(const char * name); +INT sem_wait( sem_t * sem ); +INT sem_init(sem_t *sem , INT pshared, UINT value); +INT sem_destroy(sem_t *sem); + +INT pthread_create (pthread_t *thread, pthread_attr_t *attr, + VOID *(*start_routine)(VOID*),VOID *arg); +INT pthread_detach(pthread_t thread); +INT pthread_join(pthread_t thread, VOID **value_ptr); +INT pthread_equal(pthread_t thread1, pthread_t thread2); +VOID pthread_exit(VOID *value_ptr); +pthread_t pthread_self(VOID); +INT pthread_attr_destroy(pthread_attr_t *attr); +INT pthread_attr_getdetachstate( pthread_attr_t *attr,INT *detachstate); +INT pthread_attr_setdetachstate(pthread_attr_t *attr,INT detachstate); +INT pthread_attr_getinheritsched(pthread_attr_t *attr, INT *inheritsched); +INT pthread_attr_setinheritsched(pthread_attr_t *attr, INT inheritsched); +INT pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param); +INT pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param *param); +INT pthread_attr_getschedpolicy(pthread_attr_t *attr, INT *policy); +INT pthread_attr_setschedpolicy(pthread_attr_t *attr, INT policy); +INT pthread_attr_init(pthread_attr_t *attr); +INT pthread_attr_getstackaddr( pthread_attr_t *attr,VOID **stackaddr); +INT pthread_attr_setstackaddr(pthread_attr_t *attr,VOID *stackaddr); +INT pthread_attr_getstacksize( pthread_attr_t *attr, size_t *stacksize); +INT pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +INT pthread_attr_getstack( pthread_attr_t *attr,VOID **stackaddr, + size_t *stacksize); +INT pthread_attr_setstack( pthread_attr_t *attr,VOID *stackaddr, + size_t stacksize); +INT pthread_mutexattr_gettype(pthread_mutexattr_t *attr, INT *type); +INT pthread_mutexattr_settype(pthread_mutexattr_t *attr, INT type); +INT pthread_mutexattr_destroy(pthread_mutexattr_t *attr); +INT pthread_mutexattr_init(pthread_mutexattr_t *attr); +INT pthread_mutex_destroy(pthread_mutex_t *mutex); +INT pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); +INT pthread_mutex_lock(pthread_mutex_t *mutex ); +INT pthread_mutex_unlock(pthread_mutex_t *mutex ); +INT pthread_mutex_trylock(pthread_mutex_t *mutex); +INT pthread_mutexattr_getprotocol( pthread_mutexattr_t *attr, INT *protocol); +INT pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, INT protocol); +INT pthread_mutexattr_getpshared (pthread_mutexattr_t *attr, INT *pshared); +INT pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, INT pshared); +INT pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout); +INT pthread_setcancelstate (INT state, INT *oldstate); +INT pthread_setcanceltype (INT type, INT *oldtype); +INT pthread_cancel(pthread_t thread); +VOID pthread_yield(VOID); +INT pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID)); +VOID pthread_testcancel(VOID); +INT pthread_setschedparam(pthread_t thread, INT policy, const struct sched_param *param); +INT pthread_getschedparam(pthread_t thread, INT *policy, struct sched_param *param); + +INT pthread_cond_destroy(pthread_cond_t *cond); +INT pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr); +INT pthread_cond_broadcast(pthread_cond_t *cond); +INT pthread_cond_signal(pthread_cond_t *cond); +INT pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, + struct timespec *abstime); +INT pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); + + + + + + +/* static mutex initializer */ + +#define PTHREAD_MUTEX_INITIALIZER {{TX_MUTEX_ID, "PMTX", 0, NULL, 0, 0, 0, NULL, 0 , NULL, NULL}, PTHREAD_MUTEX_RECURSIVE , TX_TRUE} + +/* static conditional variable initializer */ +#define PTHREAD_COND_INITIALIZER {{TX_SEMAPHORE_ID, "CSEM", 0, NULL, 0, NULL, NULL}, TX_TRUE} + + + + + + +#endif /* TX_POSIX */ diff --git a/utility/rtos_compatibility_layers/posix/tx_px_time.h b/utility/rtos_compatibility_layers/posix/tx_px_time.h new file mode 100644 index 00000000..f2a26c65 --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/tx_px_time.h @@ -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 */ +/** */ +/** POSIX Compliancy Wrapper (POSIX) */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* EKP DEFINITIONS RELEASE */ +/* */ +/* tx_px_time.h PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the constants, structures, etc. needed to */ +/* implement time related functionality for the Evacuation Kit */ +/* for POSIX Users (POSIX) */ +/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx William E. Lamie Initial Version 6.x */ +/* */ +/**************************************************************************/ + +#ifndef _TX_PX_TIME_H +#define _TX_PX_TIME_H + +#ifndef _TIME_T +#define _TIME_T +typedef ULONG time_t; +#endif + + +struct timespec +{ + ULONG timeout_value; /* time in terms of CPU ticks */ + time_t tv_sec; /* time in terms of Seconds */ + ULONG tv_nsec; /* time in terms of nano seconds*/ +}; + +# define CLOCK_REALTIME 1 + + +INT clock_settime(clockid_t, const struct timespec *); +INT clock_gettime(clockid_t, struct timespec *); +INT clock_getres(clockid_t, struct timespec *); + + +INT nanosleep(struct timespec *req, struct timespec *rem); +UINT sleep(ULONG seconds); + +#endif + +