summaryrefslogtreecommitdiff
path: root/ports_module
diff options
context:
space:
mode:
Diffstat (limited to 'ports_module')
-rw-r--r--ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s18
-rw-r--r--ports_module/cortex_m3/ac5/inc/tx_port.h546
-rw-r--r--ports_module/cortex_m3/ac5/inc/txm_module_port.h9
-rw-r--r--ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s25
-rw-r--r--ports_module/cortex_m3/ac6/inc/tx_port.h527
-rw-r--r--ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m3/gnu/inc/tx_port.h523
-rw-r--r--ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m3/iar/inc/tx_port.h519
-rw-r--r--ports_module/cortex_m3/iar/module_manager/src/tx_misra.s561
-rw-r--r--ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s18
-rw-r--r--ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s18
-rw-r--r--ports_module/cortex_m4/ac5/inc/tx_port.h546
-rw-r--r--ports_module/cortex_m4/ac5/inc/txm_module_port.h9
-rw-r--r--ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s25
-rw-r--r--ports_module/cortex_m4/ac6/inc/tx_port.h527
-rw-r--r--ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S127
-rw-r--r--ports_module/cortex_m4/gnu/inc/tx_port.h523
-rw-r--r--ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m4/iar/inc/tx_port.h519
-rw-r--r--ports_module/cortex_m4/iar/module_manager/src/tx_misra.s561
-rw-r--r--ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s18
-rw-r--r--ports_module/cortex_m7/ac5/inc/tx_port.h546
-rw-r--r--ports_module/cortex_m7/ac5/inc/txm_module_port.h9
-rw-r--r--ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s25
-rw-r--r--ports_module/cortex_m7/ac6/inc/tx_port.h527
-rw-r--r--ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m7/gnu/inc/tx_port.h523
-rw-r--r--ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S18
-rw-r--r--ports_module/cortex_m7/iar/inc/tx_port.h519
-rw-r--r--ports_module/cortex_m7/iar/module_manager/src/tx_misra.s561
-rw-r--r--ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s18
40 files changed, 5280 insertions, 3301 deletions
diff --git a/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S
index 0e0c8f67..84ba8ae6 100644
--- a/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/AC6 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -68,6 +68,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -278,11 +280,25 @@ __tx_ts_wait:
LDR r1, [r2] // Pickup the next thread to execute pointer
CMP r1, #0
BNE __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}
+#endif
+
#ifdef TX_ENABLE_WFI
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}
+#endif
+
CPSIE i // Enable interrupts
B __tx_ts_wait // Loop to continue waiting
diff --git a/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S
index 7e613c25..78493121 100644
--- a/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/GNU */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -68,6 +68,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -278,11 +280,25 @@ __tx_ts_wait:
LDR r1, [r2] // Pickup the next thread to execute pointer
CMP r1, #0
BNE __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}
+#endif
+
#ifdef TX_ENABLE_WFI
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}
+#endif
+
CPSIE i // Enable interrupts
B __tx_ts_wait // Loop to continue waiting
diff --git a/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S
index af30dffa..1149757a 100644
--- a/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/IAR */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -75,6 +75,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -263,11 +265,25 @@ __tx_ts_wait:
LDR r1, [r2] // Pickup the next thread to execute pointer
CMP r1, #0
BNE __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}
+#endif
+
#ifdef TX_ENABLE_WFI
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}
+#endif
+
CPSIE i // Enable interrupts
B __tx_ts_wait // Loop to continue waiting
diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S
index 69e8a192..2610edb5 100644
--- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/AC6 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -68,6 +68,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -306,11 +308,25 @@ __tx_ts_wait:
CPSID i // Disable interrupts
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
diff --git a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S
index 439a96c0..1a92839a 100644
--- a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S
@@ -26,7 +26,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/GNU */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -64,6 +64,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -302,11 +304,25 @@ __tx_ts_wait:
CPSID i // Disable interrupts
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
diff --git a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s
index 00f1189a..c21fa411 100644
--- a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/IAR */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -80,6 +80,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -303,11 +305,25 @@ __tx_ts_wait:
CPSID i // Disable interrupts
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
diff --git a/ports_module/cortex_m3/ac5/inc/tx_port.h b/ports_module/cortex_m3/ac5/inc/tx_port.h
index 0374d55e..79177b2b 100644
--- a/ports_module/cortex_m3/ac5/inc/tx_port.h
+++ b/ports_module/cortex_m3/ac5/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M3/AC5 */
-/* 6.1.11 */
+/* tx_port.h Cortex-M3 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,14 +278,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);
-#ifndef TX_MISRA_ENABLE
-register unsigned int _ipsr __asm("ipsr");
+#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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -231,37 +308,72 @@ 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); \
- }
-
-#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
@@ -270,78 +382,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 = *((volatile 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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -366,16 +476,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
@@ -387,70 +519,197 @@ ULONG _tx_misra_ipsr_get(VOID);
#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 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) );
+#else
+#error "Compiler not supported."
#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. */
-UINT _tx_thread_interrupt_disable(VOID);
-VOID _tx_thread_interrupt_restore(UINT previous_posture);
+#if defined(__GNUC__) || defined(__ICCARM__)
-#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+/*** GCC/AC6 and IAR ***/
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
+{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
+}
-#define TX_INTERRUPT_SAVE_AREA UINT was_masked;
-#define TX_DISABLE was_masked = __disable_irq();
-#define TX_RESTORE if (was_masked == 0) __enable_irq();
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
+{
+UINT int_posture;
-#define _tx_thread_system_return _tx_thread_system_return_inline
+ 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);
+}
-static void _tx_thread_system_return_inline(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+{
+UINT interrupt_save;
+
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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 UINT 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 was_masked;
+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. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_ipsr == 0)
{
- was_masked = __disable_irq();
+#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 (was_masked != 0)
+ if (interrupt_save != 0)
__disable_irq();
+#endif
}
}
-#endif
-/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing
+#define TX_INTERRUPT_SAVE_AREA UINT 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);
+
+#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);
@@ -460,8 +719,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-M3/AC5 Version 6.1.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -470,5 +729,4 @@ extern CHAR _tx_version_id[];
#endif
#endif
-
#endif
diff --git a/ports_module/cortex_m3/ac5/inc/txm_module_port.h b/ports_module/cortex_m3/ac5/inc/txm_module_port.h
index 523c787a..ba34ddc8 100644
--- a/ports_module/cortex_m3/ac5/inc/txm_module_port.h
+++ b/ports_module/cortex_m3/ac5/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M3/AC5 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -44,6 +44,8 @@
/* 07-29-2022 Scott Larson Enabled user-defined and */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Configure heap size, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -94,6 +96,11 @@ The following extensions must also be defined in tx_port.h:
VOID (*tx_timer_module_expiration_function)(ULONG id);
*/
+/* Users can define the module heap size. */
+#ifndef TXM_MODULE_HEAP_SIZE
+#define TXM_MODULE_HEAP_SIZE 512
+#endif
+
/* Define the kernel stack size for a module thread. */
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
#define TXM_MODULE_KERNEL_STACK_SIZE 768
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
index 11838470..b4772c4f 100644
--- 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
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/AC5 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -80,6 +80,9 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* fixed label syntax, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -324,11 +327,25 @@ __tx_ts_wait
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
@@ -411,11 +428,11 @@ __tx_ts_restore
#ifdef TXM_MODULE_MPU_DEFAULT
B config_mpu // configure MPU for module
-default_mpu:
+default_mpu
LDR r0, =txm_module_default_mpu_registers // default MPU configuration
#endif
-config_mpu:
+config_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
@@ -572,7 +589,7 @@ _tx_thread_user_return
BIC r3, #1 // Clear LSPACT
LDR r1, =0xE000EF34 // Address of FPCCR
STR r3, [r1] // Save updated FPCCR
-_tx_no_lazy_clear:
+_tx_no_lazy_clear
#endif
LDR r0, [r2, #0xB0] // Load the module thread stack pointer
diff --git a/ports_module/cortex_m3/ac6/inc/tx_port.h b/ports_module/cortex_m3/ac6/inc/tx_port.h
index cd4ce994..79177b2b 100644
--- a/ports_module/cortex_m3/ac6/inc/tx_port.h
+++ b/ports_module/cortex_m3/ac6/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M3/AC6 */
-/* 6.1.11 */
+/* tx_port.h Cortex-M3 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,11 +278,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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -228,26 +308,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_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 ) ) static inline void __set_control(ULONG control_value)
+__attribute__( ( always_inline ) ) ULONG __get_control_value(void)
{
+ULONG control_value;
- __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" );
+ __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
+#endif /* TX_MISRA_ENABLE */
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
@@ -255,23 +358,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
@@ -280,77 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_control(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -375,133 +476,240 @@ __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) );
-
+#else
+#error "Compiler not supported."
#endif
-#ifndef TX_DISABLE_INLINE
-/* 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. */
+/* 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 __disable_interrupts(void)
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-unsigned int primask_value;
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- __asm__ volatile (" CPSID i" : : : "memory" );
- return(primask_value);
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
}
-__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value)
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
{
+UINT int_posture;
+
+ int_posture = __get_interrupt_posture();
- __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" );
+#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 unsigned int __get_primask_value(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
{
+UINT interrupt_save;
-unsigned int primask_value;
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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);
+ }
+}
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- return(primask_value);
+#define TX_INTERRUPT_SAVE_AREA UINT 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);
}
-__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+#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;
- __asm__ volatile (" CPSIE i": : : "memory" );
+ 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
+}
-__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+static void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_ipsr_value() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_primask_value();
- __enable_interrupts();
- __restore_interrupts(interrupt_save);
- }
+#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_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 /* TX_DISABLE_INLINE is defined */
-#else
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
-#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
-#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
-#endif
+#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-M3. 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);
@@ -511,11 +719,14 @@ 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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *";
+#else
+#ifdef TX_MISRA_ENABLE
+extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
-
+#endif
#endif
diff --git a/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S
index 00ab9053..c4ebdb82 100644
--- a/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/AC6 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -82,6 +82,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -337,11 +339,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m3/gnu/inc/tx_port.h b/ports_module/cortex_m3/gnu/inc/tx_port.h
index b4197c96..79177b2b 100644
--- a/ports_module/cortex_m3/gnu/inc/tx_port.h
+++ b/ports_module/cortex_m3/gnu/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M3/GNU */
-/* 6.1.11 */
+/* tx_port.h Cortex-M3 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,11 +278,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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -228,26 +308,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_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 ) ) static inline void __set_control(ULONG control_value)
+__attribute__( ( always_inline ) ) ULONG __get_control_value(void)
{
+ULONG control_value;
- __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" );
+ __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
+#endif /* TX_MISRA_ENABLE */
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
@@ -255,23 +358,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
@@ -280,77 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_control(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -375,127 +476,240 @@ __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) );
-
+#else
+#error "Compiler not supported."
#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 __disable_interrupts(void)
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-unsigned int primask_value;
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- __asm__ volatile (" CPSID i" : : : "memory" );
- return(primask_value);
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
}
-__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value)
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
{
+UINT int_posture;
- __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" );
+ 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 unsigned int __get_primask_value(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
{
+UINT interrupt_save;
+
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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 UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-unsigned int primask_value;
+/*** 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);
+}
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- return(primask_value);
+#ifdef TX_PORT_USE_BASEPRI
+static __inline void __set_basepri_value(unsigned int basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI, #basepri_value");
}
+#endif
-__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+static __inline unsigned int __disable_interrupts(void)
{
+unsigned int int_posture;
+
+ int_posture = __get_interrupt_posture();
- __asm__ volatile (" CPSIE i": : : "memory" );
+#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
+}
-__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+static void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_ipsr_value() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_primask_value();
- __enable_interrupts();
- __restore_interrupts(interrupt_save);
- }
+#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_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 /* TX_DISABLE_INLINE is defined */
-#else
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
-#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
-#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
-#endif
+#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-M3. 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);
@@ -505,11 +719,14 @@ 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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *";
+#else
+#ifdef TX_MISRA_ENABLE
+extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
-
+#endif
#endif
diff --git a/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S
index a8b3894f..627cc10f 100644
--- a/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/GNU */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -82,6 +82,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -337,11 +339,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m3/iar/inc/tx_port.h b/ports_module/cortex_m3/iar/inc/tx_port.h
index 6ed2c186..79177b2b 100644
--- a/ports_module/cortex_m3/iar/inc/tx_port.h
+++ b/ports_module/cortex_m3/iar/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M3/IAR */
-/* 6.1.11 */
+/* tx_port.h Cortex-M3 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,27 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
-#include <intrinsics.h>
-#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -166,7 +191,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,7 +205,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
/* Define the TX_THREAD control block extensions for this port. The main reason
- for the multiple macros is so that backward compatibility can be maintained with
+ for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
@@ -216,7 +241,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID *tx_thread_module_reserved;
#endif
#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
-#define TX_THREAD_EXTENSION_3
+#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;
@@ -241,11 +266,11 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -255,27 +280,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_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_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_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
-
-#ifdef __ARMVFP__
+#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -284,28 +308,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.
@@ -315,76 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_CONTROL(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -409,16 +476,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
@@ -427,92 +516,211 @@ 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) );
+#else
+#error "Compiler not supported."
+#endif
+
+
+
+/* Define the interrupt disable/restore macros for each compiler. */
+
+#if defined(__GNUC__) || defined(__ICCARM__)
+
+/*** GCC/AC6 and IAR ***/
+
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
+{
+UINT 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(UINT 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(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
#endif
+}
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
+{
+UINT int_posture;
-/* 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. */
+ int_posture = __get_interrupt_posture();
-#ifdef TX_DISABLE_INLINE
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(TX_PORT_BASEPRI);
+#else
+ __asm__ volatile ("CPSID i" : : : "memory");
+#endif
+ return(int_posture);
+}
-UINT _tx_thread_interrupt_disable(VOID);
-VOID _tx_thread_interrupt_restore(UINT previous_posture);
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+{
+UINT interrupt_save;
-#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-#define TX_RESTORE _tx_thread_interrupt_restore(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
-#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);};
+static __inline unsigned int __disable_interrupts(void)
+{
+unsigned int int_posture;
-#define _tx_thread_system_return _tx_thread_system_return_inline
+ 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)
{
-__istate_t interrupt_save;
+unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_IPSR() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_interrupt_state();
- __enable_interrupt();
- __set_interrupt_state(interrupt_save);
+#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
}
}
-#endif
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing
- thread. These are no longer needed, but are preserved for backward compatibility only. */
+/*** End AC5 ***/
-void tx_thread_fpu_enable(void);
-void tx_thread_fpu_disable(void);
+#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
-/* Define the interrupt lockout macros for each ThreadX object. */
+#else /* TX_DISABLE_INLINE is defined */
-#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
+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);
+#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/IAR Version 6.1.10 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -521,5 +729,4 @@ extern CHAR _tx_version_id[];
#endif
#endif
-
#endif
diff --git a/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s b/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s
index 53c60fbc..ab3fef69 100644
--- a/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s
+++ b/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s
@@ -102,12 +102,22 @@
PUBLIC _tx_misra_fpccr_get
PUBLIC _tx_misra_vfp_touch
#endif
- PUBLIC _tx_version_id
+ PUBLIC _tx_misra_event_flags_group_not_used
+ PUBLIC _tx_misra_event_flags_set_notify_not_used
+ PUBLIC _tx_misra_queue_not_used
+ PUBLIC _tx_misra_queue_send_notify_not_used
+ PUBLIC _tx_misra_semaphore_not_used
+ PUBLIC _tx_misra_semaphore_put_notify_not_used
+ PUBLIC _tx_misra_thread_entry_exit_notify_not_used
+ PUBLIC _tx_misra_thread_not_used
+
+#ifdef TX_MISRA_ENABLE
+ PUBLIC _tx_version_id
SECTION `.data`:DATA:REORDER:NOROOT(2)
DATA
-// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *";
+// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *";
_tx_version_id:
DC8 43H, 6FH, 70H, 79H, 72H, 69H, 67H, 68H
DC8 74H, 20H, 28H, 63H, 29H, 20H, 31H, 39H
@@ -115,11 +125,12 @@ _tx_version_id:
DC8 45H, 78H, 70H, 72H, 65H, 73H, 73H, 20H
DC8 4CH, 6FH, 67H, 69H, 63H, 20H, 49H, 6EH
DC8 63H, 2EH, 20H, 2AH, 20H, 54H, 68H, 72H
- DC8 65H, 61H, 64H, 58H, 20H, 35H, 2EH, 38H
+ DC8 65H, 61H, 64H, 58H, 20H, 36H, 2EH, 31H
DC8 20H, 4DH, 49H, 53H, 52H, 41H, 20H, 43H
DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H
DC8 6EH, 74H, 20H, 2AH, 0
DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+#endif //TX_MISRA_ENABLE
/**************************************************************************/
/**************************************************************************/
@@ -139,7 +150,7 @@ _tx_misra_memset:
MOVS R1,R0
MOVS R0,R4
BL __aeabi_memset
- POP {R4,PC} ;; return
+ POP {R4,PC} // return
/**************************************************************************/
/**************************************************************************/
@@ -153,7 +164,7 @@ _tx_misra_memset:
THUMB
_tx_misra_uchar_pointer_add:
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -169,7 +180,7 @@ _tx_misra_uchar_pointer_add:
_tx_misra_uchar_pointer_sub:
RSBS R1,R1,#+0
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -184,21 +195,97 @@ _tx_misra_uchar_pointer_sub:
THUMB
_tx_misra_uchar_pointer_dif:
SUBS R0,R0,R1
- BX LR ;; return
-
+ BX LR // return
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
+/************************************************************************************************************************************/
+/************************************************************************************************************************************/
+/** */
+/** This single function serves all of the below prototypes. */
+/** */
+/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */
+/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */
+/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */
+/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */
+/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */
+/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */
+/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */
+/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */
+/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */
+/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */
+/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */
+/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */
+/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */
+/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */
+/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */
+/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */
+/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */
+/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */
+/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */
+/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */
+/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */
+/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */
+/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */
+/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */
+/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */
+/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */
+/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */
+/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */
+/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */
+/** VOID _tx_misra_event_flags_group_not_used(TX_EVENT_FLAGS_GROUP *group_ptr); */
+/** VOID _tx_misra_event_flags_set_notify_not_used(VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); */
+/** VOID _tx_misra_queue_not_used(TX_QUEUE *queue_ptr); */
+/** VOID _tx_misra_queue_send_notify_not_used(VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); */
+/** VOID _tx_misra_semaphore_not_used(TX_SEMAPHORE *semaphore_ptr); */
+/** VOID _tx_misra_semaphore_put_notify_not_used(VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); */
+/** VOID _tx_misra_thread_not_used(TX_THREAD *thread_ptr); */
+/** VOID _tx_misra_thread_entry_exit_notify_not_used(VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT id)); */
+/** */
+/************************************************************************************************************************************/
+/************************************************************************************************************************************/
SECTION `.text`:CODE:NOROOT(1)
THUMB
_tx_misra_pointer_to_ulong_convert:
- BX LR ;; return
+_tx_misra_ulong_to_pointer_convert:
+_tx_misra_indirect_void_to_uchar_pointer_convert:
+_tx_misra_uchar_to_indirect_uchar_pointer_convert:
+_tx_misra_block_pool_to_uchar_pointer_convert:
+_tx_misra_void_to_block_pool_pointer_convert:
+_tx_misra_void_to_uchar_pointer_convert:
+_tx_misra_uchar_to_block_pool_pointer_convert:
+_tx_misra_void_to_indirect_uchar_pointer_convert:
+_tx_misra_void_to_byte_pool_pointer_convert:
+_tx_misra_byte_pool_to_uchar_pointer_convert:
+_tx_misra_uchar_to_align_type_pointer_convert:
+_tx_misra_uchar_to_indirect_byte_pool_pointer_convert:
+_tx_misra_void_to_event_flags_pointer_convert:
+_tx_misra_void_to_ulong_pointer_convert:
+_tx_misra_void_to_mutex_pointer_convert:
+_tx_misra_void_to_queue_pointer_convert:
+_tx_misra_void_to_semaphore_pointer_convert:
+_tx_misra_uchar_to_void_pointer_convert:
+_tx_misra_ulong_to_thread_pointer_convert:
+_tx_misra_timer_indirect_to_void_pointer_convert:
+_tx_misra_const_char_to_char_pointer_convert:
+_tx_misra_void_to_thread_pointer_convert:
+#ifdef TX_ENABLE_EVENT_TRACE
+_tx_misra_object_to_uchar_pointer_convert:
+_tx_misra_uchar_to_object_pointer_convert:
+_tx_misra_uchar_to_header_pointer_convert:
+_tx_misra_uchar_to_entry_pointer_convert:
+_tx_misra_entry_to_uchar_pointer_convert:
+#endif
+_tx_misra_char_to_uchar_pointer_convert:
+_tx_misra_event_flags_group_not_used:
+_tx_misra_event_flags_set_notify_not_used:
+_tx_misra_queue_not_used:
+_tx_misra_queue_send_notify_not_used:
+_tx_misra_semaphore_not_used:
+_tx_misra_semaphore_put_notify_not_used:
+_tx_misra_thread_entry_exit_notify_not_used:
+_tx_misra_thread_not_used:
+
+ BX LR // return
/**************************************************************************/
@@ -213,7 +300,7 @@ _tx_misra_pointer_to_ulong_convert:
THUMB
_tx_misra_ulong_pointer_add:
ADD R0,R0,R1, LSL #+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -230,7 +317,7 @@ _tx_misra_ulong_pointer_sub:
MVNS R2,#+3
MULS R1,R2,R1
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -246,21 +333,7 @@ _tx_misra_ulong_pointer_sub:
_tx_misra_ulong_pointer_dif:
SUBS R0,R0,R1
ASRS R0,R0,#+2
- BX LR ;; return
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_ulong_to_pointer_convert:
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -299,7 +372,7 @@ _tx_misra_message_copy:
STR R3,[R0, #+0]
STR R4,[R1, #+0]
POP {R4,R5}
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -316,7 +389,7 @@ _tx_misra_message_copy:
_tx_misra_timer_pointer_dif:
SUBS R0,R0,R1
ASRS R0,R0,#+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -332,7 +405,7 @@ _tx_misra_timer_pointer_dif:
THUMB
_tx_misra_timer_pointer_add:
ADD R0,R0,R1, LSL #+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -347,12 +420,9 @@ _tx_misra_timer_pointer_add:
SECTION `.text`:CODE:NOROOT(1)
THUMB
_tx_misra_user_timer_pointer_get:
- ADDS R2,R0,#+8
- SUBS R2,R2,R0
- RSBS R2,R2,#+0
- ADD R0,R0,R2
- STR R0,[R1, #+0]
- BX LR ;; return
+ SUBS R0,#8
+ STR R0,[R1, #+0]
+ BX LR // return
/**************************************************************************/
@@ -374,7 +444,7 @@ _tx_misra_thread_stack_check:
CMP R4,#+0
BEQ.N ??_tx_misra_thread_stack_check_0
LDR R1,[R4, #+0]
- LDR.N R2,??DataTable2 ;; 0x54485244
+ LDR.N R2,??DataTable2 // 0x54485244
CMP R1,R2
BNE.N ??_tx_misra_thread_stack_check_0
LDR R1,[R4, #+8]
@@ -412,7 +482,7 @@ _tx_misra_thread_stack_check:
BL _tx_thread_interrupt_disable
??_tx_misra_thread_stack_check_0:
BL _tx_thread_interrupt_restore
- POP {R0,R4,R5,PC} ;; return
+ POP {R0,R4,R5,PC} // return
#ifdef TX_ENABLE_EVENT_TRACE
@@ -500,7 +570,7 @@ _tx_misra_trace_event_insert:
LDR R0,[R0, #+0]
STR R4,[R0, #+32]
??_tx_misra_trace_event_insert_0:
- POP {R0,R4-R7,PC} ;; return
+ POP {R0,R4-R7,PC} // return
SECTION `.text`:CODE:NOROOT(2)
@@ -552,7 +622,7 @@ _tx_misra_trace_event_insert:
THUMB
_tx_misra_time_stamp_get:
MOVS R0,#+0
- BX LR ;; return
+ BX LR // return
#endif
@@ -587,203 +657,7 @@ _tx_misra_time_stamp_get:
THUMB
_tx_misra_always_true:
MOVS R0,#+1
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_indirect_void_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_indirect_uchar_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************/
-/***********************************************************************************/
-/** */
-/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */
-/** */
-/***********************************************************************************/
-/***********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_block_pool_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_block_pool_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************/
-/*****************************************************************************/
-/** */
-/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************/
-/*****************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/************************************************************************************/
-/************************************************************************************/
-/** */
-/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */
-/** */
-/************************************************************************************/
-/************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_block_pool_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************************/
-/**************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */
-/** */
-/**************************************************************************************/
-/**************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_indirect_uchar_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************************/
-/*****************************************************************************************/
-/** */
-/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************************/
-/*****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_byte_pool_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_byte_pool_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************************/
-/*****************************************************************************************/
-/** */
-/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */
-/** */
-/*****************************************************************************************/
-/*****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_align_type_pointer_convert:
- BX LR ;; return
-
-
-/****************************************************************************************************/
-/****************************************************************************************************/
-/** */
-/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */
-/** */
-/****************************************************************************************************/
-/****************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_indirect_byte_pool_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************************************/
-/**************************************************************************************************/
-/** */
-/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */
-/** */
-/**************************************************************************************************/
-/**************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_event_flags_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************/
-/*****************************************************************************/
-/** */
-/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************/
-/*****************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_ulong_pointer_convert:
- BX LR ;; return
-
-
-/********************************************************************************/
-/********************************************************************************/
-/** */
-/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */
-/** */
-/********************************************************************************/
-/********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_mutex_pointer_convert:
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -798,192 +672,7 @@ _tx_misra_void_to_mutex_pointer_convert:
THUMB
_tx_misra_status_get:
MOVS R0,#+0
- BX LR ;; return
-
-
-/********************************************************************************/
-/********************************************************************************/
-/** */
-/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */
-/** */
-/********************************************************************************/
-/********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_queue_pointer_convert:
- BX LR ;; return
-
-
-/****************************************************************************************/
-/****************************************************************************************/
-/** */
-/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */
-/** */
-/****************************************************************************************/
-/****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_semaphore_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_void_pointer_convert:
- BX LR ;; return
-
-
-/*********************************************************************************/
-/*********************************************************************************/
-/** */
-/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */
-/** */
-/*********************************************************************************/
-/*********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_ulong_to_thread_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************************/
-/***************************************************************************************************/
-/** */
-/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */
-/** */
-/***************************************************************************************************/
-/***************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_timer_indirect_to_void_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_const_char_to_char_pointer_convert:
- BX LR ;; return
-
-
-/**********************************************************************************/
-/**********************************************************************************/
-/** */
-/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */
-/** */
-/**********************************************************************************/
-/**********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_thread_pointer_convert:
- BX LR ;; return
-
-
-#ifdef TX_ENABLE_EVENT_TRACE
-
-/************************************************************************************************/
-/************************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */
-/** */
-/************************************************************************************************/
-/************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_object_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/************************************************************************************************/
-/************************************************************************************************/
-/** */
-/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */
-/** */
-/************************************************************************************************/
-/************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_object_pointer_convert:
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_header_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_entry_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_entry_to_uchar_pointer_convert:
- BX LR ;; return
-#endif
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_char_to_uchar_pointer_convert:
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -998,7 +687,7 @@ _tx_misra_char_to_uchar_pointer_convert:
THUMB
_tx_misra_ipsr_get:
MRS R0, IPSR
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -1013,7 +702,7 @@ _tx_misra_ipsr_get:
THUMB
_tx_misra_control_get:
MRS R0, CONTROL
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -1028,7 +717,7 @@ _tx_misra_control_get:
THUMB
_tx_misra_control_set:
MSR CONTROL, R0
- BX LR ;; return
+ BX LR // return
#ifdef __ARMVFP__
@@ -1044,9 +733,9 @@ _tx_misra_control_set:
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
+ LDR r0, =0xE000EF34 // Build FPCCR address
+ LDR r0, [r0] // Load FPCCR value
+ BX LR // return
/***********************************************************************************************/
@@ -1061,7 +750,7 @@ _tx_misra_fpccr_get:
THUMB
_tx_misra_vfp_touch:
vmov.f32 s0, s0
- BX LR ;; return
+ BX LR // return
#endif
diff --git a/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s
index b83ec527..1ff11a25 100644
--- a/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/IAR */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -77,6 +77,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -325,11 +327,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S
index 417d1404..e305ca17 100644
--- a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/AC6 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -75,6 +75,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -344,11 +346,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S
index af8be2ba..f8fb777b 100644
--- a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S
@@ -29,7 +29,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/GNU */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -76,6 +76,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -345,11 +347,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s
index 3242fac2..5cf5ae16 100644
--- a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/IAR */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -87,6 +87,8 @@
/* 07-29-2022 Scott Larson Removed the code path to skip */
/* MPU reloading, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -341,11 +343,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m4/ac5/inc/tx_port.h b/ports_module/cortex_m4/ac5/inc/tx_port.h
index 3aba89f0..73cb0069 100644
--- a/ports_module/cortex_m4/ac5/inc/tx_port.h
+++ b/ports_module/cortex_m4/ac5/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M4/AC5 */
-/* 6.1.11 */
+/* tx_port.h Cortex-M4 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* Define various constants for the ThreadX Cortex-M4 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,14 +278,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);
-#ifndef TX_MISRA_ENABLE
-register unsigned int _ipsr __asm("ipsr");
+#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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -231,37 +308,72 @@ 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); \
- }
-
-#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
@@ -270,78 +382,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 = *((volatile 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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -366,16 +476,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
@@ -387,70 +519,197 @@ ULONG _tx_misra_ipsr_get(VOID);
#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 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) );
+#else
+#error "Compiler not supported."
#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. */
-UINT _tx_thread_interrupt_disable(VOID);
-VOID _tx_thread_interrupt_restore(UINT previous_posture);
+#if defined(__GNUC__) || defined(__ICCARM__)
-#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+/*** GCC/AC6 and IAR ***/
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
+{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
+}
-#define TX_INTERRUPT_SAVE_AREA UINT was_masked;
-#define TX_DISABLE was_masked = __disable_irq();
-#define TX_RESTORE if (was_masked == 0) __enable_irq();
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
+{
+UINT int_posture;
-#define _tx_thread_system_return _tx_thread_system_return_inline
+ 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);
+}
-static void _tx_thread_system_return_inline(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+{
+UINT interrupt_save;
+
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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 UINT 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 was_masked;
+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. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_ipsr == 0)
{
- was_masked = __disable_irq();
+#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 (was_masked != 0)
+ if (interrupt_save != 0)
__disable_irq();
+#endif
}
}
-#endif
-/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing
+#define TX_INTERRUPT_SAVE_AREA UINT 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);
+
+#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);
@@ -460,8 +719,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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -470,5 +729,4 @@ extern CHAR _tx_version_id[];
#endif
#endif
-
#endif
diff --git a/ports_module/cortex_m4/ac5/inc/txm_module_port.h b/ports_module/cortex_m4/ac5/inc/txm_module_port.h
index f375107e..bddabbe3 100644
--- a/ports_module/cortex_m4/ac5/inc/txm_module_port.h
+++ b/ports_module/cortex_m4/ac5/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M4/AC5 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -44,6 +44,8 @@
/* 07-29-2022 Scott Larson Enabled user-defined and */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Configure heap size, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -94,6 +96,11 @@ The following extensions must also be defined in tx_port.h:
VOID (*tx_timer_module_expiration_function)(ULONG id);
*/
+/* Users can define the module heap size. */
+#ifndef TXM_MODULE_HEAP_SIZE
+#define TXM_MODULE_HEAP_SIZE 512
+#endif
+
/* Define the kernel stack size for a module thread. */
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
#define TXM_MODULE_KERNEL_STACK_SIZE 768
diff --git a/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s
index 6067dd44..3f59ee6c 100644
--- a/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/AC5 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -80,6 +80,9 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* fixed label syntax, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -324,11 +327,25 @@ __tx_ts_wait
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
@@ -411,11 +428,11 @@ __tx_ts_restore
#ifdef TXM_MODULE_MPU_DEFAULT
B config_mpu // configure MPU for module
-default_mpu:
+default_mpu
LDR r0, =txm_module_default_mpu_registers // default MPU configuration
#endif
-config_mpu:
+config_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
@@ -572,7 +589,7 @@ _tx_thread_user_return
BIC r3, #1 // Clear LSPACT
LDR r1, =0xE000EF34 // Address of FPCCR
STR r3, [r1] // Save updated FPCCR
-_tx_no_lazy_clear:
+_tx_no_lazy_clear
#endif
LDR r0, [r2, #0xB0] // Load the module thread stack pointer
diff --git a/ports_module/cortex_m4/ac6/inc/tx_port.h b/ports_module/cortex_m4/ac6/inc/tx_port.h
index 5e0f6a91..73cb0069 100644
--- a/ports_module/cortex_m4/ac6/inc/tx_port.h
+++ b/ports_module/cortex_m4/ac6/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M4/AC6 */
-/* 6.1.11 */
+/* tx_port.h Cortex-M4 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* Define various constants for the ThreadX Cortex-M4 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,11 +278,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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -228,26 +308,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_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 ) ) static inline void __set_control(ULONG control_value)
+__attribute__( ( always_inline ) ) ULONG __get_control_value(void)
{
+ULONG control_value;
- __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" );
+ __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
+#endif /* TX_MISRA_ENABLE */
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
@@ -255,23 +358,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
@@ -280,77 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_control(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -375,133 +476,240 @@ __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) );
-
+#else
+#error "Compiler not supported."
#endif
-#ifndef TX_DISABLE_INLINE
-/* 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. */
+/* 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 __disable_interrupts(void)
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-unsigned int primask_value;
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- __asm__ volatile (" CPSID i" : : : "memory" );
- return(primask_value);
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
}
-__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value)
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
{
+UINT int_posture;
+
+ int_posture = __get_interrupt_posture();
- __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" );
+#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 unsigned int __get_primask_value(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
{
+UINT interrupt_save;
-unsigned int primask_value;
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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);
+ }
+}
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- return(primask_value);
+#define TX_INTERRUPT_SAVE_AREA UINT 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);
}
-__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+#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;
- __asm__ volatile (" CPSIE i": : : "memory" );
+ 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
+}
-__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+static void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_ipsr_value() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_primask_value();
- __enable_interrupts();
- __restore_interrupts(interrupt_save);
- }
+#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_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 /* TX_DISABLE_INLINE is defined */
-#else
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
-#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
-#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
-#endif
+#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
+/* 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);
@@ -511,11 +719,14 @@ 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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *";
+#else
+#ifdef TX_MISRA_ENABLE
+extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
-
+#endif
#endif
diff --git a/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S
index cb50426c..9dfaee37 100644
--- a/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/AC6 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -82,6 +82,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -337,11 +339,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S b/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S
deleted file mode 100644
index d4cb1636..00000000
--- a/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S
+++ /dev/null
@@ -1,127 +0,0 @@
- .global _start
- .extern main
-
-
- .section .init, "ax"
- .code 16
- .align 2
- .thumb_func
-
-
-_start:
- CPSID i
- ldr r1, =__stack_end__
- mov sp, r1
-
-
- /* Copy initialised sections into RAM if required. */
- ldr r0, =__data_load_start__
- ldr r1, =__data_start__
- ldr r2, =__data_end__
- bl crt0_memory_copy
- ldr r0, =__text_load_start__
- ldr r1, =__text_start__
- ldr r2, =__text_end__
- bl crt0_memory_copy
- ldr r0, =__fast_load_start__
- ldr r1, =__fast_start__
- ldr r2, =__fast_end__
- bl crt0_memory_copy
- ldr r0, =__ctors_load_start__
- ldr r1, =__ctors_start__
- ldr r2, =__ctors_end__
- bl crt0_memory_copy
- ldr r0, =__dtors_load_start__
- ldr r1, =__dtors_start__
- ldr r2, =__dtors_end__
- bl crt0_memory_copy
- ldr r0, =__rodata_load_start__
- ldr r1, =__rodata_start__
- ldr r2, =__rodata_end__
- bl crt0_memory_copy
-
-
- /* Zero bss. */
- ldr r0, =__bss_start__
- ldr r1, =__bss_end__
- mov r2, #0
- bl crt0_memory_set
-
-
- /* Setup heap - not recommended for Threadx but here for compatibility reasons */
- ldr r0, = __heap_start__
- ldr r1, = __heap_end__
- sub r1, r1, r0
- mov r2, #0
- str r2, [r0]
- add r0, r0, #4
- str r1, [r0]
-
-
- /* constructors in case of using C++ */
- ldr r0, =__ctors_start__
- ldr r1, =__ctors_end__
-crt0_ctor_loop:
- cmp r0, r1
- beq crt0_ctor_end
- ldr r2, [r0]
- add r0, #4
- push {r0-r1}
- blx r2
- pop {r0-r1}
- b crt0_ctor_loop
-crt0_ctor_end:
-
-
- /* Setup call frame for main() */
- mov r0, #0
- mov lr, r0
- mov r12, sp
-
-
-start:
- /* Jump to main() */
- mov r0, #0
- mov r1, #0
- ldr r2, =main
- blx r2
- /* when main returns, loop forever. */
-crt0_exit_loop:
- b crt0_exit_loop
-
-
-
- /* Startup helper functions. */
-
-
-crt0_memory_copy:
- cmp r0, r1
- beq memory_copy_done
- sub r2, r2, r1
- beq memory_copy_done
-memory_copy_loop:
- ldrb r3, [r0]
- add r0, r0, #1
- strb r3, [r1]
- add r1, r1, #1
- sub r2, r2, #1
- bne memory_copy_loop
-memory_copy_done:
- bx lr
-
-
-crt0_memory_set:
- cmp r0, r1
- beq memory_set_done
- strb r2, [r0]
- add r0, r0, #1
- b crt0_memory_set
-memory_set_done:
- bx lr
-
-
- /* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
- .section .stack, "wa", %nobits
- .section .stack_process, "wa", %nobits
- .section .heap, "wa", %nobits
- \ No newline at end of file
diff --git a/ports_module/cortex_m4/gnu/inc/tx_port.h b/ports_module/cortex_m4/gnu/inc/tx_port.h
index ed3f0984..73cb0069 100644
--- a/ports_module/cortex_m4/gnu/inc/tx_port.h
+++ b/ports_module/cortex_m4/gnu/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M4/GNU */
-/* 6.1.11 */
+/* tx_port.h Cortex-M4 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* Define various constants for the ThreadX Cortex-M4 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,11 +278,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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -228,26 +308,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_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 ) ) static inline void __set_control(ULONG control_value)
+__attribute__( ( always_inline ) ) ULONG __get_control_value(void)
{
+ULONG control_value;
- __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" );
+ __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
+#endif /* TX_MISRA_ENABLE */
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
@@ -255,23 +358,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
@@ -280,77 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_control(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -375,127 +476,240 @@ __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) );
-
+#else
+#error "Compiler not supported."
#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 __disable_interrupts(void)
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-unsigned int primask_value;
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- __asm__ volatile (" CPSID i" : : : "memory" );
- return(primask_value);
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
}
-__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value)
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
{
+UINT int_posture;
- __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" );
+ 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 unsigned int __get_primask_value(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
{
+UINT interrupt_save;
+
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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 UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-unsigned int primask_value;
+/*** 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);
+}
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- return(primask_value);
+#ifdef TX_PORT_USE_BASEPRI
+static __inline void __set_basepri_value(unsigned int basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI, #basepri_value");
}
+#endif
-__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+static __inline unsigned int __disable_interrupts(void)
{
+unsigned int int_posture;
+
+ int_posture = __get_interrupt_posture();
- __asm__ volatile (" CPSIE i": : : "memory" );
+#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
+}
-__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+static void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_ipsr_value() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_primask_value();
- __enable_interrupts();
- __restore_interrupts(interrupt_save);
- }
+#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_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 /* TX_DISABLE_INLINE is defined */
-#else
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
-#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
-#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
-#endif
+#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
+/* 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);
@@ -505,11 +719,14 @@ 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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *";
+#else
+#ifdef TX_MISRA_ENABLE
+extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
-
+#endif
#endif
diff --git a/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S
index 4d5e9947..43cd3725 100644
--- a/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/GNU */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -82,6 +82,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -337,11 +339,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m4/iar/inc/tx_port.h b/ports_module/cortex_m4/iar/inc/tx_port.h
index 2f620957..73cb0069 100644
--- a/ports_module/cortex_m4/iar/inc/tx_port.h
+++ b/ports_module/cortex_m4/iar/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M4/IAR */
-/* 6.1.11 */
+/* tx_port.h Cortex-M4 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,27 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
-#include <intrinsics.h>
-#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* Define various constants for the ThreadX Cortex-M4 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 *((volatile ULONG *) 0x0a800024)
@@ -166,7 +191,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,7 +205,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
/* Define the TX_THREAD control block extensions for this port. The main reason
- for the multiple macros is so that backward compatibility can be maintained with
+ for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
@@ -216,7 +241,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID *tx_thread_module_reserved;
#endif
#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
-#define TX_THREAD_EXTENSION_3
+#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;
@@ -241,11 +266,11 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -255,27 +280,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_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_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_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
-
-#ifdef __ARMVFP__
+#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -284,28 +308,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.
@@ -315,76 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_CONTROL(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -409,16 +476,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
@@ -427,92 +516,211 @@ 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) );
+#else
+#error "Compiler not supported."
+#endif
+
+
+
+/* Define the interrupt disable/restore macros for each compiler. */
+
+#if defined(__GNUC__) || defined(__ICCARM__)
+
+/*** GCC/AC6 and IAR ***/
+
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
+{
+UINT 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(UINT 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(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
#endif
+}
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
+{
+UINT int_posture;
-/* 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. */
+ int_posture = __get_interrupt_posture();
-#ifdef TX_DISABLE_INLINE
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(TX_PORT_BASEPRI);
+#else
+ __asm__ volatile ("CPSID i" : : : "memory");
+#endif
+ return(int_posture);
+}
-UINT _tx_thread_interrupt_disable(VOID);
-VOID _tx_thread_interrupt_restore(UINT previous_posture);
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+{
+UINT interrupt_save;
-#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-#define TX_RESTORE _tx_thread_interrupt_restore(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
-#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);};
+static __inline unsigned int __disable_interrupts(void)
+{
+unsigned int int_posture;
-#define _tx_thread_system_return _tx_thread_system_return_inline
+ 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)
{
-__istate_t interrupt_save;
+unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_IPSR() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_interrupt_state();
- __enable_interrupt();
- __set_interrupt_state(interrupt_save);
+#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
}
}
-#endif
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing
- thread. These are no longer needed, but are preserved for backward compatibility only. */
+/*** End AC5 ***/
-void tx_thread_fpu_enable(void);
-void tx_thread_fpu_disable(void);
+#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
-/* Define the interrupt lockout macros for each ThreadX object. */
+#else /* TX_DISABLE_INLINE is defined */
-#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
+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);
+#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-M4/IAR Version 6.1.10 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -521,5 +729,4 @@ extern CHAR _tx_version_id[];
#endif
#endif
-
#endif
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
index 53c60fbc..ab3fef69 100644
--- a/ports_module/cortex_m4/iar/module_manager/src/tx_misra.s
+++ b/ports_module/cortex_m4/iar/module_manager/src/tx_misra.s
@@ -102,12 +102,22 @@
PUBLIC _tx_misra_fpccr_get
PUBLIC _tx_misra_vfp_touch
#endif
- PUBLIC _tx_version_id
+ PUBLIC _tx_misra_event_flags_group_not_used
+ PUBLIC _tx_misra_event_flags_set_notify_not_used
+ PUBLIC _tx_misra_queue_not_used
+ PUBLIC _tx_misra_queue_send_notify_not_used
+ PUBLIC _tx_misra_semaphore_not_used
+ PUBLIC _tx_misra_semaphore_put_notify_not_used
+ PUBLIC _tx_misra_thread_entry_exit_notify_not_used
+ PUBLIC _tx_misra_thread_not_used
+
+#ifdef TX_MISRA_ENABLE
+ PUBLIC _tx_version_id
SECTION `.data`:DATA:REORDER:NOROOT(2)
DATA
-// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *";
+// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *";
_tx_version_id:
DC8 43H, 6FH, 70H, 79H, 72H, 69H, 67H, 68H
DC8 74H, 20H, 28H, 63H, 29H, 20H, 31H, 39H
@@ -115,11 +125,12 @@ _tx_version_id:
DC8 45H, 78H, 70H, 72H, 65H, 73H, 73H, 20H
DC8 4CH, 6FH, 67H, 69H, 63H, 20H, 49H, 6EH
DC8 63H, 2EH, 20H, 2AH, 20H, 54H, 68H, 72H
- DC8 65H, 61H, 64H, 58H, 20H, 35H, 2EH, 38H
+ DC8 65H, 61H, 64H, 58H, 20H, 36H, 2EH, 31H
DC8 20H, 4DH, 49H, 53H, 52H, 41H, 20H, 43H
DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H
DC8 6EH, 74H, 20H, 2AH, 0
DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+#endif //TX_MISRA_ENABLE
/**************************************************************************/
/**************************************************************************/
@@ -139,7 +150,7 @@ _tx_misra_memset:
MOVS R1,R0
MOVS R0,R4
BL __aeabi_memset
- POP {R4,PC} ;; return
+ POP {R4,PC} // return
/**************************************************************************/
/**************************************************************************/
@@ -153,7 +164,7 @@ _tx_misra_memset:
THUMB
_tx_misra_uchar_pointer_add:
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -169,7 +180,7 @@ _tx_misra_uchar_pointer_add:
_tx_misra_uchar_pointer_sub:
RSBS R1,R1,#+0
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -184,21 +195,97 @@ _tx_misra_uchar_pointer_sub:
THUMB
_tx_misra_uchar_pointer_dif:
SUBS R0,R0,R1
- BX LR ;; return
-
+ BX LR // return
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
+/************************************************************************************************************************************/
+/************************************************************************************************************************************/
+/** */
+/** This single function serves all of the below prototypes. */
+/** */
+/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */
+/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */
+/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */
+/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */
+/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */
+/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */
+/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */
+/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */
+/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */
+/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */
+/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */
+/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */
+/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */
+/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */
+/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */
+/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */
+/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */
+/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */
+/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */
+/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */
+/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */
+/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */
+/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */
+/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */
+/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */
+/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */
+/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */
+/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */
+/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */
+/** VOID _tx_misra_event_flags_group_not_used(TX_EVENT_FLAGS_GROUP *group_ptr); */
+/** VOID _tx_misra_event_flags_set_notify_not_used(VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); */
+/** VOID _tx_misra_queue_not_used(TX_QUEUE *queue_ptr); */
+/** VOID _tx_misra_queue_send_notify_not_used(VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); */
+/** VOID _tx_misra_semaphore_not_used(TX_SEMAPHORE *semaphore_ptr); */
+/** VOID _tx_misra_semaphore_put_notify_not_used(VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); */
+/** VOID _tx_misra_thread_not_used(TX_THREAD *thread_ptr); */
+/** VOID _tx_misra_thread_entry_exit_notify_not_used(VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT id)); */
+/** */
+/************************************************************************************************************************************/
+/************************************************************************************************************************************/
SECTION `.text`:CODE:NOROOT(1)
THUMB
_tx_misra_pointer_to_ulong_convert:
- BX LR ;; return
+_tx_misra_ulong_to_pointer_convert:
+_tx_misra_indirect_void_to_uchar_pointer_convert:
+_tx_misra_uchar_to_indirect_uchar_pointer_convert:
+_tx_misra_block_pool_to_uchar_pointer_convert:
+_tx_misra_void_to_block_pool_pointer_convert:
+_tx_misra_void_to_uchar_pointer_convert:
+_tx_misra_uchar_to_block_pool_pointer_convert:
+_tx_misra_void_to_indirect_uchar_pointer_convert:
+_tx_misra_void_to_byte_pool_pointer_convert:
+_tx_misra_byte_pool_to_uchar_pointer_convert:
+_tx_misra_uchar_to_align_type_pointer_convert:
+_tx_misra_uchar_to_indirect_byte_pool_pointer_convert:
+_tx_misra_void_to_event_flags_pointer_convert:
+_tx_misra_void_to_ulong_pointer_convert:
+_tx_misra_void_to_mutex_pointer_convert:
+_tx_misra_void_to_queue_pointer_convert:
+_tx_misra_void_to_semaphore_pointer_convert:
+_tx_misra_uchar_to_void_pointer_convert:
+_tx_misra_ulong_to_thread_pointer_convert:
+_tx_misra_timer_indirect_to_void_pointer_convert:
+_tx_misra_const_char_to_char_pointer_convert:
+_tx_misra_void_to_thread_pointer_convert:
+#ifdef TX_ENABLE_EVENT_TRACE
+_tx_misra_object_to_uchar_pointer_convert:
+_tx_misra_uchar_to_object_pointer_convert:
+_tx_misra_uchar_to_header_pointer_convert:
+_tx_misra_uchar_to_entry_pointer_convert:
+_tx_misra_entry_to_uchar_pointer_convert:
+#endif
+_tx_misra_char_to_uchar_pointer_convert:
+_tx_misra_event_flags_group_not_used:
+_tx_misra_event_flags_set_notify_not_used:
+_tx_misra_queue_not_used:
+_tx_misra_queue_send_notify_not_used:
+_tx_misra_semaphore_not_used:
+_tx_misra_semaphore_put_notify_not_used:
+_tx_misra_thread_entry_exit_notify_not_used:
+_tx_misra_thread_not_used:
+
+ BX LR // return
/**************************************************************************/
@@ -213,7 +300,7 @@ _tx_misra_pointer_to_ulong_convert:
THUMB
_tx_misra_ulong_pointer_add:
ADD R0,R0,R1, LSL #+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -230,7 +317,7 @@ _tx_misra_ulong_pointer_sub:
MVNS R2,#+3
MULS R1,R2,R1
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -246,21 +333,7 @@ _tx_misra_ulong_pointer_sub:
_tx_misra_ulong_pointer_dif:
SUBS R0,R0,R1
ASRS R0,R0,#+2
- BX LR ;; return
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_ulong_to_pointer_convert:
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -299,7 +372,7 @@ _tx_misra_message_copy:
STR R3,[R0, #+0]
STR R4,[R1, #+0]
POP {R4,R5}
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -316,7 +389,7 @@ _tx_misra_message_copy:
_tx_misra_timer_pointer_dif:
SUBS R0,R0,R1
ASRS R0,R0,#+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -332,7 +405,7 @@ _tx_misra_timer_pointer_dif:
THUMB
_tx_misra_timer_pointer_add:
ADD R0,R0,R1, LSL #+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -347,12 +420,9 @@ _tx_misra_timer_pointer_add:
SECTION `.text`:CODE:NOROOT(1)
THUMB
_tx_misra_user_timer_pointer_get:
- ADDS R2,R0,#+8
- SUBS R2,R2,R0
- RSBS R2,R2,#+0
- ADD R0,R0,R2
- STR R0,[R1, #+0]
- BX LR ;; return
+ SUBS R0,#8
+ STR R0,[R1, #+0]
+ BX LR // return
/**************************************************************************/
@@ -374,7 +444,7 @@ _tx_misra_thread_stack_check:
CMP R4,#+0
BEQ.N ??_tx_misra_thread_stack_check_0
LDR R1,[R4, #+0]
- LDR.N R2,??DataTable2 ;; 0x54485244
+ LDR.N R2,??DataTable2 // 0x54485244
CMP R1,R2
BNE.N ??_tx_misra_thread_stack_check_0
LDR R1,[R4, #+8]
@@ -412,7 +482,7 @@ _tx_misra_thread_stack_check:
BL _tx_thread_interrupt_disable
??_tx_misra_thread_stack_check_0:
BL _tx_thread_interrupt_restore
- POP {R0,R4,R5,PC} ;; return
+ POP {R0,R4,R5,PC} // return
#ifdef TX_ENABLE_EVENT_TRACE
@@ -500,7 +570,7 @@ _tx_misra_trace_event_insert:
LDR R0,[R0, #+0]
STR R4,[R0, #+32]
??_tx_misra_trace_event_insert_0:
- POP {R0,R4-R7,PC} ;; return
+ POP {R0,R4-R7,PC} // return
SECTION `.text`:CODE:NOROOT(2)
@@ -552,7 +622,7 @@ _tx_misra_trace_event_insert:
THUMB
_tx_misra_time_stamp_get:
MOVS R0,#+0
- BX LR ;; return
+ BX LR // return
#endif
@@ -587,203 +657,7 @@ _tx_misra_time_stamp_get:
THUMB
_tx_misra_always_true:
MOVS R0,#+1
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_indirect_void_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_indirect_uchar_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************/
-/***********************************************************************************/
-/** */
-/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */
-/** */
-/***********************************************************************************/
-/***********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_block_pool_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_block_pool_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************/
-/*****************************************************************************/
-/** */
-/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************/
-/*****************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/************************************************************************************/
-/************************************************************************************/
-/** */
-/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */
-/** */
-/************************************************************************************/
-/************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_block_pool_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************************/
-/**************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */
-/** */
-/**************************************************************************************/
-/**************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_indirect_uchar_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************************/
-/*****************************************************************************************/
-/** */
-/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************************/
-/*****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_byte_pool_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_byte_pool_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************************/
-/*****************************************************************************************/
-/** */
-/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */
-/** */
-/*****************************************************************************************/
-/*****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_align_type_pointer_convert:
- BX LR ;; return
-
-
-/****************************************************************************************************/
-/****************************************************************************************************/
-/** */
-/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */
-/** */
-/****************************************************************************************************/
-/****************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_indirect_byte_pool_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************************************/
-/**************************************************************************************************/
-/** */
-/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */
-/** */
-/**************************************************************************************************/
-/**************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_event_flags_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************/
-/*****************************************************************************/
-/** */
-/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************/
-/*****************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_ulong_pointer_convert:
- BX LR ;; return
-
-
-/********************************************************************************/
-/********************************************************************************/
-/** */
-/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */
-/** */
-/********************************************************************************/
-/********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_mutex_pointer_convert:
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -798,192 +672,7 @@ _tx_misra_void_to_mutex_pointer_convert:
THUMB
_tx_misra_status_get:
MOVS R0,#+0
- BX LR ;; return
-
-
-/********************************************************************************/
-/********************************************************************************/
-/** */
-/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */
-/** */
-/********************************************************************************/
-/********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_queue_pointer_convert:
- BX LR ;; return
-
-
-/****************************************************************************************/
-/****************************************************************************************/
-/** */
-/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */
-/** */
-/****************************************************************************************/
-/****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_semaphore_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_void_pointer_convert:
- BX LR ;; return
-
-
-/*********************************************************************************/
-/*********************************************************************************/
-/** */
-/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */
-/** */
-/*********************************************************************************/
-/*********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_ulong_to_thread_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************************/
-/***************************************************************************************************/
-/** */
-/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */
-/** */
-/***************************************************************************************************/
-/***************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_timer_indirect_to_void_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_const_char_to_char_pointer_convert:
- BX LR ;; return
-
-
-/**********************************************************************************/
-/**********************************************************************************/
-/** */
-/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */
-/** */
-/**********************************************************************************/
-/**********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_thread_pointer_convert:
- BX LR ;; return
-
-
-#ifdef TX_ENABLE_EVENT_TRACE
-
-/************************************************************************************************/
-/************************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */
-/** */
-/************************************************************************************************/
-/************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_object_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/************************************************************************************************/
-/************************************************************************************************/
-/** */
-/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */
-/** */
-/************************************************************************************************/
-/************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_object_pointer_convert:
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_header_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_entry_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_entry_to_uchar_pointer_convert:
- BX LR ;; return
-#endif
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_char_to_uchar_pointer_convert:
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -998,7 +687,7 @@ _tx_misra_char_to_uchar_pointer_convert:
THUMB
_tx_misra_ipsr_get:
MRS R0, IPSR
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -1013,7 +702,7 @@ _tx_misra_ipsr_get:
THUMB
_tx_misra_control_get:
MRS R0, CONTROL
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -1028,7 +717,7 @@ _tx_misra_control_get:
THUMB
_tx_misra_control_set:
MSR CONTROL, R0
- BX LR ;; return
+ BX LR // return
#ifdef __ARMVFP__
@@ -1044,9 +733,9 @@ _tx_misra_control_set:
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
+ LDR r0, =0xE000EF34 // Build FPCCR address
+ LDR r0, [r0] // Load FPCCR value
+ BX LR // return
/***********************************************************************************************/
@@ -1061,7 +750,7 @@ _tx_misra_fpccr_get:
THUMB
_tx_misra_vfp_touch:
vmov.f32 s0, s0
- BX LR ;; return
+ BX LR // return
#endif
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
index 8291f334..2a1761c1 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
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/IAR */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -77,6 +77,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -325,11 +327,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m7/ac5/inc/tx_port.h b/ports_module/cortex_m7/ac5/inc/tx_port.h
index 9aca7f4b..1b6fa4fb 100644
--- a/ports_module/cortex_m7/ac5/inc/tx_port.h
+++ b/ports_module/cortex_m7/ac5/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M7/AC5 */
-/* 6.1.11 */
+/* tx_port.h Cortex-M7 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,14 +278,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);
-#ifndef TX_MISRA_ENABLE
-register unsigned int _ipsr __asm("ipsr");
+#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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -231,37 +308,72 @@ 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); \
- }
-
-#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
@@ -270,78 +382,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 = *((volatile 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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -366,16 +476,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
@@ -387,70 +519,197 @@ ULONG _tx_misra_ipsr_get(VOID);
#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 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) );
+#else
+#error "Compiler not supported."
#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. */
-UINT _tx_thread_interrupt_disable(VOID);
-VOID _tx_thread_interrupt_restore(UINT previous_posture);
+#if defined(__GNUC__) || defined(__ICCARM__)
-#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+/*** GCC/AC6 and IAR ***/
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
+{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
+}
-#define TX_INTERRUPT_SAVE_AREA UINT was_masked;
-#define TX_DISABLE was_masked = __disable_irq();
-#define TX_RESTORE if (was_masked == 0) __enable_irq();
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
+{
+UINT int_posture;
-#define _tx_thread_system_return _tx_thread_system_return_inline
+ 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);
+}
-static void _tx_thread_system_return_inline(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+{
+UINT interrupt_save;
+
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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 UINT 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 was_masked;
+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. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_ipsr == 0)
{
- was_masked = __disable_irq();
+#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 (was_masked != 0)
+ if (interrupt_save != 0)
__disable_irq();
+#endif
}
}
-#endif
-/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
+#define TX_INTERRUPT_SAVE_AREA UINT 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);
+
+#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);
@@ -460,8 +719,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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -470,5 +729,4 @@ extern CHAR _tx_version_id[];
#endif
#endif
-
#endif
diff --git a/ports_module/cortex_m7/ac5/inc/txm_module_port.h b/ports_module/cortex_m7/ac5/inc/txm_module_port.h
index 3ac5acf7..ae4bdf24 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/AC5 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -44,6 +44,8 @@
/* 07-29-2022 Scott Larson Enabled user-defined and */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Configure heap size, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -94,6 +96,11 @@ The following extensions must also be defined in tx_port.h:
VOID (*tx_timer_module_expiration_function)(ULONG id);
*/
+/* Users can define the module heap size. */
+#ifndef TXM_MODULE_HEAP_SIZE
+#define TXM_MODULE_HEAP_SIZE 512
+#endif
+
/* Define the kernel stack size for a module thread. */
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
#define TXM_MODULE_KERNEL_STACK_SIZE 768
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
index 21b92ae7..95870c57 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/AC5 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -80,6 +80,9 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* fixed label syntax, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -324,11 +327,25 @@ __tx_ts_wait
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
@@ -411,11 +428,11 @@ __tx_ts_restore
#ifdef TXM_MODULE_MPU_DEFAULT
B config_mpu // configure MPU for module
-default_mpu:
+default_mpu
LDR r0, =txm_module_default_mpu_registers // default MPU configuration
#endif
-config_mpu:
+config_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
@@ -572,7 +589,7 @@ _tx_thread_user_return
BIC r3, #1 // Clear LSPACT
LDR r1, =0xE000EF34 // Address of FPCCR
STR r3, [r1] // Save updated FPCCR
-_tx_no_lazy_clear:
+_tx_no_lazy_clear
#endif
LDR r0, [r2, #0xB0] // Load the module thread stack pointer
diff --git a/ports_module/cortex_m7/ac6/inc/tx_port.h b/ports_module/cortex_m7/ac6/inc/tx_port.h
index 56f2531f..1b6fa4fb 100644
--- a/ports_module/cortex_m7/ac6/inc/tx_port.h
+++ b/ports_module/cortex_m7/ac6/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M7/AC6 */
-/* 6.1.11 */
+/* tx_port.h Cortex-M7 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,11 +278,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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -228,26 +308,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_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 ) ) static inline void __set_control(ULONG control_value)
+__attribute__( ( always_inline ) ) ULONG __get_control_value(void)
{
+ULONG control_value;
- __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" );
+ __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
+#endif /* TX_MISRA_ENABLE */
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
@@ -255,23 +358,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
@@ -280,77 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_control(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -375,133 +476,240 @@ __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) );
-
+#else
+#error "Compiler not supported."
#endif
-#ifndef TX_DISABLE_INLINE
-/* 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. */
+/* 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 __disable_interrupts(void)
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-unsigned int primask_value;
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- __asm__ volatile (" CPSID i" : : : "memory" );
- return(primask_value);
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
}
-__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value)
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
{
+UINT int_posture;
+
+ int_posture = __get_interrupt_posture();
- __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" );
+#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 unsigned int __get_primask_value(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
{
+UINT interrupt_save;
-unsigned int primask_value;
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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);
+ }
+}
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- return(primask_value);
+#define TX_INTERRUPT_SAVE_AREA UINT 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);
}
-__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+#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;
- __asm__ volatile (" CPSIE i": : : "memory" );
+ 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
+}
-__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+static void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_ipsr_value() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_primask_value();
- __enable_interrupts();
- __restore_interrupts(interrupt_save);
- }
+#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_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 /* TX_DISABLE_INLINE is defined */
-#else
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
-#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
-#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
-#endif
+#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
+/* 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);
@@ -511,11 +719,14 @@ 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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *";
+#else
+#ifdef TX_MISRA_ENABLE
+extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
-
+#endif
#endif
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
index 7111ccf1..a7261d41 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
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/AC6 */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -82,6 +82,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -337,11 +339,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m7/gnu/inc/tx_port.h b/ports_module/cortex_m7/gnu/inc/tx_port.h
index 0d9feee7..1b6fa4fb 100644
--- a/ports_module/cortex_m7/gnu/inc/tx_port.h
+++ b/ports_module/cortex_m7/gnu/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M7/GNU */
-/* 6.1.11 */
+/* tx_port.h Cortex-M7 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,23 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -131,9 +160,15 @@ typedef unsigned short USHORT;
*/
+#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((volatile 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
@@ -149,26 +184,48 @@ typedef unsigned short USHORT;
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
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
+ VOID *tx_thread_module_entry_info_ptr; \
+ ULONG tx_thread_module_current_user_mode; \
+ ULONG tx_thread_module_user_mode; \
+ ULONG tx_thread_module_saved_lr; \
+ VOID *tx_thread_module_kernel_stack_start; \
+ VOID *tx_thread_module_kernel_stack_end; \
+ ULONG tx_thread_module_kernel_stack_size; \
+ VOID *tx_thread_module_stack_ptr; \
+ VOID *tx_thread_module_stack_start; \
+ VOID *tx_thread_module_stack_end; \
+ ULONG tx_thread_module_stack_size; \
+ VOID *tx_thread_module_reserved; \
+ VOID *tx_thread_iar_tls_pointer;
+#else
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
@@ -182,7 +239,13 @@ typedef unsigned short USHORT;
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
+#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. */
@@ -203,11 +266,11 @@ typedef unsigned short USHORT;
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -215,11 +278,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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -228,26 +308,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_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 ) ) static inline void __set_control(ULONG control_value)
+__attribute__( ( always_inline ) ) ULONG __get_control_value(void)
{
+ULONG control_value;
- __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" );
+ __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
+#endif /* TX_MISRA_ENABLE */
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
@@ -255,23 +358,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
@@ -280,77 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_control(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -375,127 +476,240 @@ __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) );
-
+#else
+#error "Compiler not supported."
#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 __disable_interrupts(void)
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
{
+UINT posture;
+#ifdef TX_PORT_USE_BASEPRI
+ __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
+#else
+ __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
+#endif
+ return(posture);
+}
-unsigned int primask_value;
+#ifdef TX_PORT_USE_BASEPRI
+__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
+}
+#else
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+ __asm__ volatile ("CPSIE i": : : "memory");
+}
+#endif
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- __asm__ volatile (" CPSID i" : : : "memory" );
- return(primask_value);
+__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
+#endif
}
-__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value)
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
{
+UINT int_posture;
- __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" );
+ 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 unsigned int __get_primask_value(void)
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
{
+UINT interrupt_save;
+
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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 UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-unsigned int primask_value;
+/*** 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);
+}
- __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
- return(primask_value);
+#ifdef TX_PORT_USE_BASEPRI
+static __inline void __set_basepri_value(unsigned int basepri_value)
+{
+ __asm__ volatile ("MSR BASEPRI, #basepri_value");
}
+#endif
-__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+static __inline unsigned int __disable_interrupts(void)
{
+unsigned int int_posture;
+
+ int_posture = __get_interrupt_posture();
- __asm__ volatile (" CPSIE i": : : "memory" );
+#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
+}
-__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+static void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_ipsr_value() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_primask_value();
- __enable_interrupts();
- __restore_interrupts(interrupt_save);
- }
+#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_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 /* TX_DISABLE_INLINE is defined */
-#else
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
-#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
-#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
-#endif
+#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
+/* 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);
@@ -505,11 +719,14 @@ 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.11 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *";
+#else
+#ifdef TX_MISRA_ENABLE
+extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
-
+#endif
#endif
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
index 69cb74bb..8d28f92d 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
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/GNU */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -82,6 +82,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -337,11 +339,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
diff --git a/ports_module/cortex_m7/iar/inc/tx_port.h b/ports_module/cortex_m7/iar/inc/tx_port.h
index 70975f91..1b6fa4fb 100644
--- a/ports_module/cortex_m7/iar/inc/tx_port.h
+++ b/ports_module/cortex_m7/iar/inc/tx_port.h
@@ -25,12 +25,12 @@
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
-/* tx_port.h Cortex-M7/IAR */
-/* 6.1.11 */
+/* tx_port.h Cortex-M7 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
-/* William E. Lamie, Microsoft Corporation */
+/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
@@ -43,6 +43,9 @@
/* 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 */
@@ -57,27 +60,42 @@
#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
+/* 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
-
+#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
-#include <intrinsics.h>
-#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
+
+#ifdef __ICCARM__
+#include <intrinsics.h> /* IAR Intrinsics */
+#define __asm__ __asm /* Define to make all inline asm look similar */
+#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
+#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
+#endif /* __ICCARM__ */
+
+#ifdef __ghs__
+#include <arm_ghs.h>
+#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,25 @@ 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
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
-/* 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 *((volatile ULONG *) 0x0a800024)
@@ -166,7 +191,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,7 +205,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
/* Define the TX_THREAD control block extensions for this port. The main reason
- for the multiple macros is so that backward compatibility can be maintained with
+ for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
@@ -216,7 +241,7 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID *tx_thread_module_reserved;
#endif
#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
-#define TX_THREAD_EXTENSION_3
+#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;
@@ -241,11 +266,11 @@ ULONG _tx_misra_time_stamp_get(VOID);
VOID (*tx_timer_module_expiration_function)(ULONG id);
-/* Define the user extension field of the thread control block. Nothing
+/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
-#define TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
#endif
@@ -255,27 +280,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_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_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_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
-
-#ifdef __ARMVFP__
+#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
@@ -284,28 +308,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.
@@ -315,76 +382,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 = *((volatile ULONG *) 0xE000EF34); \
- _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
- if (_tx_fpccr == ((ULONG) 0x01)) \
- { \
- ULONG _tx_vfp_state; \
- _tx_vfp_state = __get_CONTROL(); \
- _tx_vfp_state = _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 = *((volatile 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(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
@@ -409,16 +476,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
@@ -427,92 +516,211 @@ 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) );
+#else
+#error "Compiler not supported."
+#endif
+
+
+
+/* Define the interrupt disable/restore macros for each compiler. */
+
+#if defined(__GNUC__) || defined(__ICCARM__)
+
+/*** GCC/AC6 and IAR ***/
+
+__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void)
+{
+UINT 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(UINT 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(UINT int_posture)
+{
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(int_posture);
+#else
+ __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
#endif
+}
+__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void)
+{
+UINT int_posture;
-/* 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. */
+ int_posture = __get_interrupt_posture();
-#ifdef TX_DISABLE_INLINE
+#ifdef TX_PORT_USE_BASEPRI
+ __set_basepri_value(TX_PORT_BASEPRI);
+#else
+ __asm__ volatile ("CPSID i" : : : "memory");
+#endif
+ return(int_posture);
+}
-UINT _tx_thread_interrupt_disable(VOID);
-VOID _tx_thread_interrupt_restore(UINT previous_posture);
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+{
+UINT interrupt_save;
-#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+ /* Set PendSV to invoke ThreadX scheduler. */
+ *((volatile 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_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-#define TX_RESTORE _tx_thread_interrupt_restore(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
-#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);};
+static __inline unsigned int __disable_interrupts(void)
+{
+unsigned int int_posture;
-#define _tx_thread_system_return _tx_thread_system_return_inline
+ 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)
{
-__istate_t interrupt_save;
+unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_IPSR() == 0)
+ if (_ipsr == 0)
{
- interrupt_save = __get_interrupt_state();
- __enable_interrupt();
- __set_interrupt_state(interrupt_save);
+#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
}
}
-#endif
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupt(interrupt_save);
-/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing
- thread. These are no longer needed, but are preserved for backward compatibility only. */
+/*** End AC5 ***/
-void tx_thread_fpu_enable(void);
-void tx_thread_fpu_disable(void);
+#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
-/* Define the interrupt lockout macros for each ThreadX object. */
+#else /* TX_DISABLE_INLINE is defined */
-#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
+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);
+#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-M7/IAR Version 6.1.10 *";
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
@@ -521,5 +729,4 @@ extern CHAR _tx_version_id[];
#endif
#endif
-
#endif
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
index 53c60fbc..ab3fef69 100644
--- a/ports_module/cortex_m7/iar/module_manager/src/tx_misra.s
+++ b/ports_module/cortex_m7/iar/module_manager/src/tx_misra.s
@@ -102,12 +102,22 @@
PUBLIC _tx_misra_fpccr_get
PUBLIC _tx_misra_vfp_touch
#endif
- PUBLIC _tx_version_id
+ PUBLIC _tx_misra_event_flags_group_not_used
+ PUBLIC _tx_misra_event_flags_set_notify_not_used
+ PUBLIC _tx_misra_queue_not_used
+ PUBLIC _tx_misra_queue_send_notify_not_used
+ PUBLIC _tx_misra_semaphore_not_used
+ PUBLIC _tx_misra_semaphore_put_notify_not_used
+ PUBLIC _tx_misra_thread_entry_exit_notify_not_used
+ PUBLIC _tx_misra_thread_not_used
+
+#ifdef TX_MISRA_ENABLE
+ PUBLIC _tx_version_id
SECTION `.data`:DATA:REORDER:NOROOT(2)
DATA
-// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *";
+// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *";
_tx_version_id:
DC8 43H, 6FH, 70H, 79H, 72H, 69H, 67H, 68H
DC8 74H, 20H, 28H, 63H, 29H, 20H, 31H, 39H
@@ -115,11 +125,12 @@ _tx_version_id:
DC8 45H, 78H, 70H, 72H, 65H, 73H, 73H, 20H
DC8 4CH, 6FH, 67H, 69H, 63H, 20H, 49H, 6EH
DC8 63H, 2EH, 20H, 2AH, 20H, 54H, 68H, 72H
- DC8 65H, 61H, 64H, 58H, 20H, 35H, 2EH, 38H
+ DC8 65H, 61H, 64H, 58H, 20H, 36H, 2EH, 31H
DC8 20H, 4DH, 49H, 53H, 52H, 41H, 20H, 43H
DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H
DC8 6EH, 74H, 20H, 2AH, 0
DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+#endif //TX_MISRA_ENABLE
/**************************************************************************/
/**************************************************************************/
@@ -139,7 +150,7 @@ _tx_misra_memset:
MOVS R1,R0
MOVS R0,R4
BL __aeabi_memset
- POP {R4,PC} ;; return
+ POP {R4,PC} // return
/**************************************************************************/
/**************************************************************************/
@@ -153,7 +164,7 @@ _tx_misra_memset:
THUMB
_tx_misra_uchar_pointer_add:
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -169,7 +180,7 @@ _tx_misra_uchar_pointer_add:
_tx_misra_uchar_pointer_sub:
RSBS R1,R1,#+0
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -184,21 +195,97 @@ _tx_misra_uchar_pointer_sub:
THUMB
_tx_misra_uchar_pointer_dif:
SUBS R0,R0,R1
- BX LR ;; return
-
+ BX LR // return
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
+/************************************************************************************************************************************/
+/************************************************************************************************************************************/
+/** */
+/** This single function serves all of the below prototypes. */
+/** */
+/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */
+/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */
+/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */
+/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */
+/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */
+/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */
+/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */
+/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */
+/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */
+/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */
+/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */
+/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */
+/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */
+/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */
+/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */
+/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */
+/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */
+/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */
+/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */
+/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */
+/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */
+/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */
+/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */
+/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */
+/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */
+/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */
+/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */
+/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */
+/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */
+/** VOID _tx_misra_event_flags_group_not_used(TX_EVENT_FLAGS_GROUP *group_ptr); */
+/** VOID _tx_misra_event_flags_set_notify_not_used(VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); */
+/** VOID _tx_misra_queue_not_used(TX_QUEUE *queue_ptr); */
+/** VOID _tx_misra_queue_send_notify_not_used(VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); */
+/** VOID _tx_misra_semaphore_not_used(TX_SEMAPHORE *semaphore_ptr); */
+/** VOID _tx_misra_semaphore_put_notify_not_used(VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); */
+/** VOID _tx_misra_thread_not_used(TX_THREAD *thread_ptr); */
+/** VOID _tx_misra_thread_entry_exit_notify_not_used(VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT id)); */
+/** */
+/************************************************************************************************************************************/
+/************************************************************************************************************************************/
SECTION `.text`:CODE:NOROOT(1)
THUMB
_tx_misra_pointer_to_ulong_convert:
- BX LR ;; return
+_tx_misra_ulong_to_pointer_convert:
+_tx_misra_indirect_void_to_uchar_pointer_convert:
+_tx_misra_uchar_to_indirect_uchar_pointer_convert:
+_tx_misra_block_pool_to_uchar_pointer_convert:
+_tx_misra_void_to_block_pool_pointer_convert:
+_tx_misra_void_to_uchar_pointer_convert:
+_tx_misra_uchar_to_block_pool_pointer_convert:
+_tx_misra_void_to_indirect_uchar_pointer_convert:
+_tx_misra_void_to_byte_pool_pointer_convert:
+_tx_misra_byte_pool_to_uchar_pointer_convert:
+_tx_misra_uchar_to_align_type_pointer_convert:
+_tx_misra_uchar_to_indirect_byte_pool_pointer_convert:
+_tx_misra_void_to_event_flags_pointer_convert:
+_tx_misra_void_to_ulong_pointer_convert:
+_tx_misra_void_to_mutex_pointer_convert:
+_tx_misra_void_to_queue_pointer_convert:
+_tx_misra_void_to_semaphore_pointer_convert:
+_tx_misra_uchar_to_void_pointer_convert:
+_tx_misra_ulong_to_thread_pointer_convert:
+_tx_misra_timer_indirect_to_void_pointer_convert:
+_tx_misra_const_char_to_char_pointer_convert:
+_tx_misra_void_to_thread_pointer_convert:
+#ifdef TX_ENABLE_EVENT_TRACE
+_tx_misra_object_to_uchar_pointer_convert:
+_tx_misra_uchar_to_object_pointer_convert:
+_tx_misra_uchar_to_header_pointer_convert:
+_tx_misra_uchar_to_entry_pointer_convert:
+_tx_misra_entry_to_uchar_pointer_convert:
+#endif
+_tx_misra_char_to_uchar_pointer_convert:
+_tx_misra_event_flags_group_not_used:
+_tx_misra_event_flags_set_notify_not_used:
+_tx_misra_queue_not_used:
+_tx_misra_queue_send_notify_not_used:
+_tx_misra_semaphore_not_used:
+_tx_misra_semaphore_put_notify_not_used:
+_tx_misra_thread_entry_exit_notify_not_used:
+_tx_misra_thread_not_used:
+
+ BX LR // return
/**************************************************************************/
@@ -213,7 +300,7 @@ _tx_misra_pointer_to_ulong_convert:
THUMB
_tx_misra_ulong_pointer_add:
ADD R0,R0,R1, LSL #+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -230,7 +317,7 @@ _tx_misra_ulong_pointer_sub:
MVNS R2,#+3
MULS R1,R2,R1
ADD R0,R0,R1
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -246,21 +333,7 @@ _tx_misra_ulong_pointer_sub:
_tx_misra_ulong_pointer_dif:
SUBS R0,R0,R1
ASRS R0,R0,#+2
- BX LR ;; return
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_ulong_to_pointer_convert:
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -299,7 +372,7 @@ _tx_misra_message_copy:
STR R3,[R0, #+0]
STR R4,[R1, #+0]
POP {R4,R5}
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -316,7 +389,7 @@ _tx_misra_message_copy:
_tx_misra_timer_pointer_dif:
SUBS R0,R0,R1
ASRS R0,R0,#+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -332,7 +405,7 @@ _tx_misra_timer_pointer_dif:
THUMB
_tx_misra_timer_pointer_add:
ADD R0,R0,R1, LSL #+2
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -347,12 +420,9 @@ _tx_misra_timer_pointer_add:
SECTION `.text`:CODE:NOROOT(1)
THUMB
_tx_misra_user_timer_pointer_get:
- ADDS R2,R0,#+8
- SUBS R2,R2,R0
- RSBS R2,R2,#+0
- ADD R0,R0,R2
- STR R0,[R1, #+0]
- BX LR ;; return
+ SUBS R0,#8
+ STR R0,[R1, #+0]
+ BX LR // return
/**************************************************************************/
@@ -374,7 +444,7 @@ _tx_misra_thread_stack_check:
CMP R4,#+0
BEQ.N ??_tx_misra_thread_stack_check_0
LDR R1,[R4, #+0]
- LDR.N R2,??DataTable2 ;; 0x54485244
+ LDR.N R2,??DataTable2 // 0x54485244
CMP R1,R2
BNE.N ??_tx_misra_thread_stack_check_0
LDR R1,[R4, #+8]
@@ -412,7 +482,7 @@ _tx_misra_thread_stack_check:
BL _tx_thread_interrupt_disable
??_tx_misra_thread_stack_check_0:
BL _tx_thread_interrupt_restore
- POP {R0,R4,R5,PC} ;; return
+ POP {R0,R4,R5,PC} // return
#ifdef TX_ENABLE_EVENT_TRACE
@@ -500,7 +570,7 @@ _tx_misra_trace_event_insert:
LDR R0,[R0, #+0]
STR R4,[R0, #+32]
??_tx_misra_trace_event_insert_0:
- POP {R0,R4-R7,PC} ;; return
+ POP {R0,R4-R7,PC} // return
SECTION `.text`:CODE:NOROOT(2)
@@ -552,7 +622,7 @@ _tx_misra_trace_event_insert:
THUMB
_tx_misra_time_stamp_get:
MOVS R0,#+0
- BX LR ;; return
+ BX LR // return
#endif
@@ -587,203 +657,7 @@ _tx_misra_time_stamp_get:
THUMB
_tx_misra_always_true:
MOVS R0,#+1
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_indirect_void_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_indirect_uchar_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************/
-/***********************************************************************************/
-/** */
-/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */
-/** */
-/***********************************************************************************/
-/***********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_block_pool_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_block_pool_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************/
-/*****************************************************************************/
-/** */
-/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************/
-/*****************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/************************************************************************************/
-/************************************************************************************/
-/** */
-/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */
-/** */
-/************************************************************************************/
-/************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_block_pool_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************************/
-/**************************************************************************************/
-/** */
-/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */
-/** */
-/**************************************************************************************/
-/**************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_indirect_uchar_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************************/
-/*****************************************************************************************/
-/** */
-/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************************/
-/*****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_byte_pool_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_byte_pool_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************************/
-/*****************************************************************************************/
-/** */
-/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */
-/** */
-/*****************************************************************************************/
-/*****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_align_type_pointer_convert:
- BX LR ;; return
-
-
-/****************************************************************************************************/
-/****************************************************************************************************/
-/** */
-/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */
-/** */
-/****************************************************************************************************/
-/****************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_indirect_byte_pool_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************************************/
-/**************************************************************************************************/
-/** */
-/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */
-/** */
-/**************************************************************************************************/
-/**************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_event_flags_pointer_convert:
- BX LR ;; return
-
-
-/*****************************************************************************/
-/*****************************************************************************/
-/** */
-/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */
-/** */
-/*****************************************************************************/
-/*****************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_ulong_pointer_convert:
- BX LR ;; return
-
-
-/********************************************************************************/
-/********************************************************************************/
-/** */
-/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */
-/** */
-/********************************************************************************/
-/********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_mutex_pointer_convert:
- BX LR ;; return
+ BX LR // return
/**************************************************************************/
@@ -798,192 +672,7 @@ _tx_misra_void_to_mutex_pointer_convert:
THUMB
_tx_misra_status_get:
MOVS R0,#+0
- BX LR ;; return
-
-
-/********************************************************************************/
-/********************************************************************************/
-/** */
-/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */
-/** */
-/********************************************************************************/
-/********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_queue_pointer_convert:
- BX LR ;; return
-
-
-/****************************************************************************************/
-/****************************************************************************************/
-/** */
-/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */
-/** */
-/****************************************************************************************/
-/****************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_semaphore_pointer_convert:
- BX LR ;; return
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_void_pointer_convert:
- BX LR ;; return
-
-
-/*********************************************************************************/
-/*********************************************************************************/
-/** */
-/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */
-/** */
-/*********************************************************************************/
-/*********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_ulong_to_thread_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************************/
-/***************************************************************************************************/
-/** */
-/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */
-/** */
-/***************************************************************************************************/
-/***************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_timer_indirect_to_void_pointer_convert:
- BX LR ;; return
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/** */
-/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */
-/** */
-/***************************************************************************************/
-/***************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_const_char_to_char_pointer_convert:
- BX LR ;; return
-
-
-/**********************************************************************************/
-/**********************************************************************************/
-/** */
-/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */
-/** */
-/**********************************************************************************/
-/**********************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_void_to_thread_pointer_convert:
- BX LR ;; return
-
-
-#ifdef TX_ENABLE_EVENT_TRACE
-
-/************************************************************************************************/
-/************************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */
-/** */
-/************************************************************************************************/
-/************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_object_to_uchar_pointer_convert:
- BX LR ;; return
-
-
-/************************************************************************************************/
-/************************************************************************************************/
-/** */
-/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */
-/** */
-/************************************************************************************************/
-/************************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_object_pointer_convert:
- BX LR ;; return
-
-
-/******************************************************************************************/
-/******************************************************************************************/
-/** */
-/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */
-/** */
-/******************************************************************************************/
-/******************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_header_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_uchar_to_entry_pointer_convert:
- BX LR ;; return
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_entry_to_uchar_pointer_convert:
- BX LR ;; return
-#endif
-
-
-/***********************************************************************************************/
-/***********************************************************************************************/
-/** */
-/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */
-/** */
-/***********************************************************************************************/
-/***********************************************************************************************/
-
- SECTION `.text`:CODE:NOROOT(1)
- THUMB
-_tx_misra_char_to_uchar_pointer_convert:
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -998,7 +687,7 @@ _tx_misra_char_to_uchar_pointer_convert:
THUMB
_tx_misra_ipsr_get:
MRS R0, IPSR
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -1013,7 +702,7 @@ _tx_misra_ipsr_get:
THUMB
_tx_misra_control_get:
MRS R0, CONTROL
- BX LR ;; return
+ BX LR // return
/***********************************************************************************************/
@@ -1028,7 +717,7 @@ _tx_misra_control_get:
THUMB
_tx_misra_control_set:
MSR CONTROL, R0
- BX LR ;; return
+ BX LR // return
#ifdef __ARMVFP__
@@ -1044,9 +733,9 @@ _tx_misra_control_set:
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
+ LDR r0, =0xE000EF34 // Build FPCCR address
+ LDR r0, [r0] // Load FPCCR value
+ BX LR // return
/***********************************************************************************************/
@@ -1061,7 +750,7 @@ _tx_misra_fpccr_get:
THUMB
_tx_misra_vfp_touch:
vmov.f32 s0, s0
- BX LR ;; return
+ BX LR // return
#endif
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
index 632b507c..4e0ab544 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
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/IAR */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -77,6 +77,8 @@
/* MPU reloading, optional */
/* default MPU settings, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Scott Larson Added low power support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -325,11 +327,25 @@ __tx_ts_wait:
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ 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
#endif
+
+#ifdef TX_LOW_POWER
+ PUSH {r0-r3}
+ BL tx_low_power_exit // Exit low power mode
+ POP {r0-r3}
+#endif
+
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4