summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryuxin-azrtos <[email protected]>2021-09-23 19:57:35 -0700
committerGitHub <[email protected]>2021-09-23 19:57:35 -0700
commit215df45d4b59d4ce8606a88f566d1d426e64a84c (patch)
tree59ea35a539c0d16c5c7247dad5ca12b040577d35
parentd0dab582506f132690b35b36ffea129ad51110b0 (diff)
parent06064828eff72aa906b6f0b02d86fd1db39c5987 (diff)
Merge pull request #139 from azure-rtos/tizho/release_rxv1
Add RXv1 port.
-rw-r--r--ports/rxv1/ccrx/inc/tx_port.h281
-rw-r--r--ports/rxv1/ccrx/readme_threadx.txt164
-rw-r--r--ports/rxv1/ccrx/src/tx_initialize_low_level.src101
-rw-r--r--ports/rxv1/ccrx/src/tx_thread_context_restore.src200
-rw-r--r--ports/rxv1/ccrx/src/tx_thread_context_save.src168
-rw-r--r--ports/rxv1/ccrx/src/tx_thread_interrupt_control.src96
-rw-r--r--ports/rxv1/ccrx/src/tx_thread_schedule.src174
-rw-r--r--ports/rxv1/ccrx/src/tx_thread_stack_build.src145
-rw-r--r--ports/rxv1/ccrx/src/tx_thread_system_return.src127
-rw-r--r--ports/rxv1/ccrx/src/tx_timer_interrupt.src251
-rw-r--r--ports/rxv1/gnu/inc/tx_port.h264
-rw-r--r--ports/rxv1/gnu/readme_threadx.txt157
-rw-r--r--ports/rxv1/gnu/src/tx_initialize_low_level.S93
-rw-r--r--ports/rxv1/gnu/src/tx_thread_context_restore.S200
-rw-r--r--ports/rxv1/gnu/src/tx_thread_context_save.S158
-rw-r--r--ports/rxv1/gnu/src/tx_thread_interrupt_control.S87
-rw-r--r--ports/rxv1/gnu/src/tx_thread_schedule.S163
-rw-r--r--ports/rxv1/gnu/src/tx_thread_stack_build.S137
-rw-r--r--ports/rxv1/gnu/src/tx_thread_system_return.S117
-rw-r--r--ports/rxv1/gnu/src/tx_timer_interrupt.S239
-rw-r--r--ports/rxv1/iar/inc/tx_port.h273
-rw-r--r--ports/rxv1/iar/readme_threadx.txt153
-rw-r--r--ports/rxv1/iar/src/tx_initialize_low_level.s99
-rw-r--r--ports/rxv1/iar/src/tx_thread_context_restore.s187
-rw-r--r--ports/rxv1/iar/src/tx_thread_context_save.s157
-rw-r--r--ports/rxv1/iar/src/tx_thread_interrupt_control.s85
-rw-r--r--ports/rxv1/iar/src/tx_thread_schedule.s162
-rw-r--r--ports/rxv1/iar/src/tx_thread_stack_build.s137
-rw-r--r--ports/rxv1/iar/src/tx_thread_system_return.s74
-rw-r--r--ports/rxv1/iar/src/tx_timer_interrupt.s235
30 files changed, 4884 insertions, 0 deletions
diff --git a/ports/rxv1/ccrx/inc/tx_port.h b/ports/rxv1/ccrx/inc/tx_port.h
new file mode 100644
index 00000000..662975d1
--- /dev/null
+++ b/ports/rxv1/ccrx/inc/tx_port.h
@@ -0,0 +1,281 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h RXv1/CCRX */
+/* 6.1.8 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+/* UINT _tx_thread_interrupt_control(UINT new_posture); */
+
+#pragma inline_asm _tx_thread_interrupt_disable
+static UINT _tx_thread_interrupt_disable(void){
+ MVFC PSW,R1 ;
+ CLRPSW I ;
+}
+
+
+#pragma inline_asm _tx_thread_interrupt_restore
+static void _tx_thread_interrupt_restore(UINT old_posture){
+ MVFC PSW, R2 ;
+ BTST #16,r1 ;
+ BMC #16,r2 ;
+ MVTC r2,PSW ;
+}
+
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+
+
+#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+
+
+#define _tx_thread_system_return _tx_thread_system_return_inline
+
+static void _tx_thread_system_return_inline(void)
+{
+ UINT interrupt_save;
+
+ interrupt_save = _tx_thread_interrupt_disable();
+
+ *((volatile UCHAR *)(0x872E0u)) = 1u;
+
+ _tx_thread_interrupt_restore(interrupt_save);
+}
+
+
+#ifndef TX_THREAD_GET_SYSTEM_STATE
+
+#pragma inline_asm _get_psw
+static UINT _get_psw(void){
+ MVFC PSW,R1 ;
+}
+
+extern volatile ULONG _tx_thread_system_state;
+#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | ((~_get_psw()) & (1u << 17u)))
+#endif
+
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv1/CCRX Version 6.1.8 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+
+#endif
+
diff --git a/ports/rxv1/ccrx/readme_threadx.txt b/ports/rxv1/ccrx/readme_threadx.txt
new file mode 100644
index 00000000..8035a79e
--- /dev/null
+++ b/ports/rxv1/ccrx/readme_threadx.txt
@@ -0,0 +1,164 @@
+ Microsoft's Azure RTOS ThreadX for Renesas RXv1
+
+ Using the CC-RX Tools
+
+1. Building the ThreadX run-time Library
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv1.
+
+
+2. Demonstration System
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv1
+
+
+3. System Initialization
+
+The system entry point using Renesas tools is at the label _PowerON_Reset_PC.
+Use the resetprg.c file that comes with your release. Most notable is that Threadx
+applications run in supervisor mode and do not use user mode. Hence switching to
+user mode has been commented out.
+
+The vector area is set up using either intprg.c or in the file tx_initialize_low_level.src.
+The file tx_initialize_low_level.src is responsible for setting up various system data
+structures, interrupt vectors, and a periodic timer. This is the ideal place add
+application specific hardware initialization code.
+
+ThreadX utilizes CMT0 as a periodic timer interrupt source. The CMT0 interrupt is
+typically setup for 10ms periodic interrupts and the interrupt priority level is set to
+level 7. You may change any of the timer parameters to suit your needs.
+
+In addition, _tx_initialize_low_level determines the first available address for use by
+the application, which is supplied as the sole input parameter to your application
+definition function, tx_application_define(). The mechanism is implemented by creating the
+FREEMEM section, this section should be linked last in the RAM area. tx_initialize_low_level
+will pick up the starting label of this section and put it in the global variable:
+_tx_initialize_unused_memory
+
+
+4. Context Switch, Register Usage and Stack Frames
+
+The RXv1 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17,
+to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT
+should not be manipulated in any way by the application. The port will setup the
+interrupt within _tx_initialize_low_level and the compiler will automatically install
+the necessary interrupt vector. As such no additional initialization is necessary by the
+application.
+
+The following defines the saved context stack frame used by the ThreadX port. The
+state of the CPU registers at the time of a context switch is saved on the running
+thread's stack The top of the suspended thread's stack is pointed to by
+tx_thread_stack_ptr in the associated thread control block TX_THREAD.
+
+ Offset Interrupted Stack Frame
+
+ 0x00 1
+ 0x04 ACC0
+ 0x0C R6
+ 0x10 R7
+ 0x14 R8
+ 0x18 R9
+ 0x1C R10
+ 0x20 R11
+ 0x24 R12
+ 0x28 R13
+ 0x30 R14
+ 0x34 R15
+ 0x38 R3
+ 0x3C R4
+ 0x40 R5
+ 0x44 R1
+ 0x48 R2
+ 0x4C PC - return address
+ 0x50 PSW
+
+Note: By default ccrx does not save the state of the accumulator register ACC0
+when entering an ISR. This means that if the ISR uses any of the DSP instructions the
+content of the register could be corrupted. Saving and restoring of the accumulator
+can be enabled by adding the -save_acc command line option.
+
+
+5. Improving Performance
+
+The distribution version of ThreadX is built without any compiler
+optimizations. This makes it easy to debug because you can trace or set
+breakpoints inside of ThreadX itself. Of course, this costs some
+performance. To make ThreadX run faster, you can change the ThreadX Library
+project to disable debug information and enable the desired optimizations.
+
+In addition, you can eliminate the ThreadX basic API error checking by
+compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
+defined before tx_api.h is included.
+
+
+6. Timer Processing
+
+Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done
+from within the callback of a periodic timer with a period of 100Hz. In the sample projects
+a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source.
+
+
+7. Interrupt Handling
+
+Interrupt handling is unaffected by the ThreadX port as such user interrupts can be
+written according to the toolchain's documentation. It is recommended not to use interrupt
+priority 15 as this is the priority of the context switch interrupt. However using interrupt
+priority 15 won't cause any negative side effectd but doing so may may slightly reduce
+performance. Please refer to the toolchain documentation for additional details on how to
+define interupt service routines.
+
+
+8. Execution Profiling
+
+The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists
+of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation
+of the EPK for generic usage details.
+
+To add the EPK to your RXv1 release make the following modifications:
+
+* Enable the following define for both the Threadx library and the application
+TX_EXECUTION_PROFILE_ENABLE
+
+* Setup CMT1 as a free running 16 bit timer.
+
+* In tx_execution_profile.h, change following around line 52:
+
+#ifdef TX_EXECUTION_64BIT_TIME
+typedef unsigned long long EXECUTION_TIME;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF
+#else
+typedef unsigned long EXECUTION_TIME;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF
+#endif
+
+/* Define basic constants for the execution profile kit. */
+
+#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A)
+
+Rebuild the Threadx library and the application.
+Refer to the EPK documentation how to interpret the results.
+
+
+9. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+08-02-2021 Initial ThreadX release for the RXv1 using CC-RXX tools, version 6.1.8
+
+
+Copyright(c) 1996-2021 Microsoft Corporation
+
+
+https://azure.com/rtos
+
+
+
+www.expresslogic.com \ No newline at end of file
diff --git a/ports/rxv1/ccrx/src/tx_initialize_low_level.src b/ports/rxv1/ccrx/src/tx_initialize_low_level.src
new file mode 100644
index 00000000..1a439a09
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_initialize_low_level.src
@@ -0,0 +1,101 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Initialize */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ .GLB __tx_initialize_unused_memory
+
+ IPR03 .EQU 87303H
+ IEN03 .EQU 87203H
+
+ .SECTION P,CODE
+
+;
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_initialize_low_level RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for any low-level processor */
+;/* initialization, including setting up interrupt vectors, setting */
+;/* up a periodic timer interrupt source, saving the system stack */
+;/* pointer for use in ISR processing later, and finding the first */
+;/* available RAM memory address for tx_application_define. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+
+ .GLB __tx_initialize_low_level
+__tx_initialize_low_level:
+;
+; /* Save the first available memory address. */
+; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start;
+;
+ MOV.L #free_mem_start, R1 ; Pickup unused memory address
+ MOV.L #__tx_initialize_unused_memory,R2
+ MOV.L R1,[R2] ; Save first free memory address
+
+; /* Set priority of SWINT to 1. */
+ MOV.L #IPR03, r1
+ MOV.L #1, r2
+ MOV.B r2, [r1]
+
+; /* Enable SWINT. */
+ MOV.L #IEN03,r1
+ MOV.B [r1], r2
+ OR #(1 << 3), r2
+ MOV.B r2, [r1]
+
+ RTS
+
+ .SECTION FREEMEM ,DATA, ALIGN=4
+free_mem_start:
+ .BLKL 8 ; this section is last in the link map so we can access the end of RAM memory
+
+ .END
diff --git a/ports/rxv1/ccrx/src/tx_thread_context_restore.src b/ports/rxv1/ccrx/src/tx_thread_context_restore.src
new file mode 100644
index 00000000..b92a2e0b
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_thread_context_restore.src
@@ -0,0 +1,200 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+ .GLB __tx_thread_system_state
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_thread_system_stack_ptr
+ .GLB __tx_thread_execute_ptr
+ .GLB __tx_timer_time_slice
+ .GLB __tx_thread_schedule
+ .GLB __tx_thread_preempt_disable
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_restore RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the interrupt context if it is processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_restore(VOID)
+;{
+ .GLB __tx_thread_context_restore
+__tx_thread_context_restore:
+;
+; /* Lockout interrupts. */
+
+ CLRPSW I ; disable interrupts
+
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+
+ MOV.L #__tx_thread_system_state, R1
+ MOV.L [R1], R2
+ SUB #1, R2
+ MOV.L R2,[R1]
+ BEQ __tx_thread_not_nested_restore
+
+;
+; /* Interrupts are nested. */
+;
+; /* Recover the saved registers from the interrupt stack
+; and return to the point of interrupt. */
+;
+__tx_thread_nested_restore:
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+; }
+
+__tx_thread_not_nested_restore:
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+
+ MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address
+ MOV.L [R1], R2
+ CMP #0, R2
+ BEQ __tx_thread_idle_system_restore
+
+ MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag
+ MOV.L [R3], R3
+ CMP #0, R3
+ BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless
+
+ MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
+ CMP [R3], R2
+ BNE __tx_thread_preempt_restore ; jump to pre-empt restoring
+;
+__tx_thread_no_preempt_restore:
+ SETPSW U ; user stack
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+
+; }
+; else
+; {
+
+__tx_thread_preempt_restore:
+
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+
+ MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address
+ MOV.L [R3],R4 ; Pickup actual time-slice
+ CMP #0, R4
+ BEQ __tx_thread_dont_save_ts ; no time slice to save
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R4,24[R2] ; Save thread's time slice
+ MOV.L #0,R4 ; Clear value
+ MOV.L R4,[R3] ; Disable global time slice flag
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Now store the remaining registers! */
+
+ SETPSW U ; user stack
+ PUSHM R6-R13
+
+ MVFACHI R5
+ MVFACMI R6
+ PUSHM R5-R6
+
+ MOV.L #1, R3 ; indicate interrupt stack frame
+ PUSH.L R3
+
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+; R1 -> _tx_thread_current_ptr
+; R2 -> *_tx_thread_current_ptr
+
+ MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block
+ MOV.L #0,R2 ; Build NULL value
+ MOV.L R2,[R1] ; Set current thread to NULL
+
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+
+__tx_thread_idle_system_restore:
+ MVTC #0, PSW ; reset interrupt priority level to 0
+ BRA __tx_thread_schedule ; jump to scheduler
+; }
+;
+;}
+;
+ .END
+
diff --git a/ports/rxv1/ccrx/src/tx_thread_context_save.src b/ports/rxv1/ccrx/src/tx_thread_context_save.src
new file mode 100644
index 00000000..8d84f9a1
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_thread_context_save.src
@@ -0,0 +1,168 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+ .GLB __tx_thread_system_state
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_thread_system_stack_ptr
+
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ .GLB __tx_thread_context_save
+__tx_thread_context_save:
+;
+; /* Upon entry to this routine, it is assumed that interrupts are locked
+; out and the (interrupt) stack frame looks like the following:
+;
+; (lower address) SP -> [return address of this call]
+; SP+4 -> Saved R1
+; SP+8 -> Saved R2
+; SP+12-> Interrupted PC
+; SP+16-> Interrupted PSW
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+
+ MOV.L #__tx_thread_system_state, R1 ; pick up address of system state
+ MOV.L [R1], R2 ; pick up system state
+ CMP #0, R2 ; 0 -> no nesting
+ BEQ __tx_thread_not_nested_save
+;
+; /* Nested interrupt condition. */
+;
+ ADD #1, r2 ; _tx_thread_system_state++
+ MOV.L r2, [r1]
+
+;
+; /* Save the rest of the scratch registers on the interrupt stack and return to the
+; calling ISR. */
+ POP R1 ; recuperate return address from stack
+ PUSHM R3-R5
+ PUSHM R14-R15
+ JMP R1 ; return address was preserved in R1
+
+;
+__tx_thread_not_nested_save:
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD #1, R2 ; _tx_thread_system_state++
+ MOV.L R2, [R1]
+
+ MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer
+ MOV.L [R2], R2
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore
+;
+; /* Move stack frame over to the current threads stack. */
+; /* complete stack frame with registers not saved yet (R3-R5, R14-R15) */
+;
+ MVFC USP, R1 ; pick up user stack pointer
+ MOV.L 16[R0], R2
+ MOV.L R2, [-R1] ; save PSW on thread stack
+ MOV.L 12[R0], R2
+ MOV.L R2, [-R1] ; save PC on thread stack
+ MOV.L 8[R0], R2
+ MOV.L R2, [-R1] ; save R2 on thread stack
+ MOV.L 4[R0], R2
+ MOV.L R2, [-R1] ; save R1 on thread stack
+ MOV.L R5, [-R1] ; save R5 on thread stack
+ MOV.L R4, [-R1] ; save R4 on thread stack
+ MOV.L R3, [-R1] ; save R3 on thread stack
+ MOV.L R15, [-R1] ; save R15 on thread stack
+ MOV.L R14, [-R1] ; save R14 on thread stack
+
+ POP R2 ; pick up return address from interrupt stack
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom
+ MVTC R1, USP ; set user/thread stack pointer
+ JMP R2 ; return to ISR
+
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save:
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+ POP R1 ; pick up return address
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
+ JMP R1 ; return to caller
+;
+; }
+;}
+ .END
+
diff --git a/ports/rxv1/ccrx/src/tx_thread_interrupt_control.src b/ports/rxv1/ccrx/src/tx_thread_interrupt_control.src
new file mode 100644
index 00000000..d2c75fca
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_thread_interrupt_control.src
@@ -0,0 +1,96 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_control RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for changing the interrupt lockout */
+;/* posture of the system. */
+;/* */
+;/* INPUT */
+;/* */
+;/* new_posture New interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_control(UINT new_posture)
+;{
+
+.GLB __tx_thread_interrupt_control
+__tx_thread_interrupt_control:
+;
+; /* Pickup current interrupt lockout posture. */
+;
+
+ MVFC PSW, R2 ; Save PSW to R2
+ MOV.L R2, R3 ; Make a copy of PSW in r3
+
+;
+; /* Apply the new interrupt posture. */
+;
+
+ BTST #16, R1 ; test I bit of PSW of "new posture"
+ BMNE #16, R2 ; conditionally set I bit of intermediate posture
+
+ MVTC R2, PSW ; save intermediate posture to PSW
+
+ MOV.L R3,R1 ; Get original SR
+ RTS ; Return to caller
+;}
+ .END
+
diff --git a/ports/rxv1/ccrx/src/tx_thread_schedule.src b/ports/rxv1/ccrx/src/tx_thread_schedule.src
new file mode 100644
index 00000000..88018528
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_thread_schedule.src
@@ -0,0 +1,174 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+ .GLB __tx_thread_execute_ptr
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_timer_time_slice
+;
+ .SECTION P,CODE
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_schedule RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function waits for a thread control block pointer to appear in */
+;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+;/* in the variable, the corresponding thread is resumed. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* _tx_thread_system_return Return to system from thread */
+;/* _tx_thread_context_restore Restore thread's context */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_schedule(VOID)
+;{
+ .GLB __tx_thread_schedule
+__tx_thread_schedule:
+;
+; /* Enable interrupts. */
+;
+ SETPSW I
+;
+; /* Wait for a thread to execute. */
+; do
+; {
+ MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr
+__tx_thread_schedule_loop:
+ MOV.L [R1],R2 ; Pickup next thread to execute
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking
+;
+; }
+; while(_tx_thread_execute_ptr == TX_NULL);
+;
+; /* Yes! We have a thread to execute. Lockout interrupts and
+; transfer control to it. */
+;
+ CLRPSW I ; disable interrupts
+;
+; /* Setup the current thread pointer. */
+; _tx_thread_current_ptr = _tx_thread_execute_ptr;
+;
+ MOV.L #__tx_thread_current_ptr, R3
+ MOV.L R2,[R3] ; Setup current thread pointer
+;
+; /* Increment the run count for this thread. */
+; _tx_thread_current_ptr -> tx_thread_run_count++;
+;
+ MOV.L 4[R2],R3 ; Pickup run count
+ ADD #1,R3 ; Increment run counter
+ MOV.L R3,4[R2] ; Store it back in control block
+;
+; /* Setup time-slice, if present. */
+; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+;
+ MOV.L 24[R2],R3 ; Pickup thread time-slice
+ MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice
+ MOV.L R3, [R4] ; Setup time-slice
+;
+; /* Switch to the thread's stack. */
+; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+ SETPSW U ; user stack mode
+ MOV.L 8[R2],R0 ; Pickup stack pointer
+;
+; /* Determine if an interrupt frame or a synchronous task suspension frame
+; is present. */
+;
+ POP R1 ; Pickup stack type
+ CMP #1, R1 ; Is it an interrupt stack?
+ BNE __tx_thread_synch_return ; No, a synchronous return frame is present.
+
+ POPM R1-R2 ; Restore accumulator.
+ MVTACLO R2
+ MVTACHI R1
+
+ POPM R6-R13 ; Recover interrupt stack frame
+ POPM R14-R15
+ POPM R3-R5
+ POPM R1-R2
+ RTE ; return to point of interrupt, this restores PC and PSW
+
+__tx_thread_synch_return:
+ POPC PSW
+ POPM R6-R13 ; Recover solicited stack frame
+ RTS
+;
+;}
+
+
+.GLB __tx_thread_context_save
+.GLB __tx_thread_context_restore
+
+; Software triggered interrupt used to perform context switches.
+; The priority of this interrupt is set to the lowest priority within
+; tx_initialize_low_level() and triggered by ThreadX when calling
+; _tx_thread_system_return().
+.RVECTOR 27, _tx_software_interrupt_entry
+.GLB _tx_software_interrupt_entry
+_tx_software_interrupt_entry:
+
+ PUSHM R1-R2
+
+ BSR __tx_thread_context_save
+
+ BRA __tx_thread_context_restore
+
+ .END
diff --git a/ports/rxv1/ccrx/src/tx_thread_stack_build.src b/ports/rxv1/ccrx/src/tx_thread_stack_build.src
new file mode 100644
index 00000000..93408c72
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_thread_stack_build.src
@@ -0,0 +1,145 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_stack_build RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function builds a stack frame on the supplied thread's stack. */
+;/* The stack frame results in a fake interrupt return to the supplied */
+;/* function pointer. */
+;/* */
+;/* INPUT */
+;/* */
+;/* thread_ptr Pointer to thread control blk */
+;/* function_ptr Pointer to return function */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_thread_create Create thread service */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+;{
+ .GLB __tx_thread_stack_build
+__tx_thread_stack_build:
+;
+;
+; /* Build an interrupt frame. The form of the fake interrupt stack
+; on the Renesas RX should look like the following after it is built:
+;
+; Stack Top: 1 Interrupt stack frame type
+; ACC0
+; R6
+; R7
+; R8
+; R9
+; R10
+; R11
+; R12
+; R13
+; R14
+; R15
+; R3
+; R4
+; R5
+; R1
+; R2
+; PC
+; PSW
+
+;
+; Stack Bottom: (higher memory address) */
+;
+ MOV.L 16[R1],R3 ; Pickup end of stack area
+ BCLR #0, R3 ; mask for 4-byte alignment
+ BCLR #1, R3
+;
+; /* Build the stack frame. */
+;
+ MOV.L #30000h, R4
+ MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set)
+ MOV.L R2, [-R3] ; initial PC
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R2 ...
+ MOV.L R4,[-R3] ; initial R1 ...
+ MOV.L R4,[-R3] ; initial R5 ...
+ MOV.L R4,[-R3] ; initial R4 ...
+ MOV.L R4,[-R3] ; initial R3 ...
+ MOV.L R4,[-R3] ; initial R15 ...
+ MOV.L R4,[-R3] ; initial R14 ...
+ MOV.L R4,[-R3] ; initial R13 ...
+ MOV.L R4,[-R3] ; initial R12 ...
+ MOV.L R4,[-R3] ; initial R11 ...
+ MOV.L R4,[-R3] ; initial R10 ...
+ MOV.L R4,[-R3] ; initial R9 ...
+ MOV.L R4,[-R3] ; initial R8 ...
+ MOV.L R4,[-R3] ; initial R7 ...
+ MOV.L R4,[-R3] ; initial R6 ...
+
+ MOV.L R4,[-R3] ; Accumulator 0
+ MOV.L R4,[-R3]
+
+ MOV.L #1, R4
+ MOV.L R4,[-R3] ; indicate interrupt stack frame
+; /* Setup stack pointer. */
+; thread_ptr -> tx_thread_stack_ptr = R1;
+ MOV.L R3, 8[R1]
+ ; store initial SP in thread control block
+ RTS
+
+;}
+ .END
+
diff --git a/ports/rxv1/ccrx/src/tx_thread_system_return.src b/ports/rxv1/ccrx/src/tx_thread_system_return.src
new file mode 100644
index 00000000..2c3a73e4
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_thread_system_return.src
@@ -0,0 +1,127 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_timer_time_slice
+ .GLB __tx_thread_schedule
+
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_system_return RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is target processor specific. It is used to transfer */
+;/* control from a thread back to the system. Only a minimal context */
+;/* is saved since the compiler assumes temp registers are going to get */
+;/* slicked by a function call anyway. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling loop */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ThreadX components */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_system_return(VOID)
+;{
+ .GLB __tx_thread_system_return
+__tx_thread_system_return:
+;
+; /* Save call save registers on the stack. */
+;
+ PUSHM R6-R13
+ PUSHC PSW
+ MOV.L #0, R1
+ PUSH.L R1 ; solicited stack frame
+;
+; /* Lockout interrupts. */
+;
+ CLRPSW I ; Lockout interrupts
+;
+; /* Save current stack in current Thread controle block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
+ MOV.L #__tx_thread_current_ptr, R2
+ MOV.L [R2], R3
+ MOV.L R0, 8[R3]
+
+ MOV.L #__tx_timer_time_slice, R4
+ MOV.L [R4], R5
+
+; /* Determine if the time-slice is active. */
+; if (_tx_timer_time_slice)
+; {
+;
+ CMP #0,R5 ; Is a time-slice present?
+ BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice
+;
+; /* Save time-slice for the thread and clear the current time-slice. */
+ ; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+ MOV.L R5,24[R3]
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R1, [R4] ; Disable the time-slice
+;
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Clear the current thread pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+;
+ MOV.L R1, [R2]
+ BRA __tx_thread_schedule
+;}
+ .END
+
diff --git a/ports/rxv1/ccrx/src/tx_timer_interrupt.src b/ports/rxv1/ccrx/src/tx_timer_interrupt.src
new file mode 100644
index 00000000..1236ec95
--- /dev/null
+++ b/ports/rxv1/ccrx/src/tx_timer_interrupt.src
@@ -0,0 +1,251 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Timer */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_timer.h"
+;#include "tx_thread.h"
+;
+;
+;Define Assembly language external references...
+;
+ .GLB __tx_timer_time_slice
+ .GLB __tx_timer_system_clock
+ .GLB __tx_timer_current_ptr
+ .GLB __tx_timer_list_start
+ .GLB __tx_timer_list_end
+ .GLB __tx_timer_expired_time_slice
+ .GLB __tx_timer_expired
+ .GLB __tx_timer_expiration_process
+ .GLB __tx_thread_context_save
+ .GLB __tx_thread_time_slice
+ .GLB __tx_thread_context_restore
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_timer_interrupt RXv1/CCRX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function processes the hardware timer interrupt. This */
+;/* processing includes incrementing the system clock and checking for */
+;/* time slice and/or timer expiration. If either is found, the */
+;/* interrupt context save/restore functions are called along with the */
+;/* expiration functions. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_context_save Save interrupted context */
+;/* _tx_timer_expiration_process Timer expiration processing */
+;/* _tx_thread_time_slice Time slice interrupted thread */
+;/* _tx_thread_context_restore Restore interrupted context */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* interrupt vector */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_timer_interrupt(VOID)
+;{
+ .GLB __tx_timer_interrupt
+__tx_timer_interrupt:
+;
+; /* Upon entry to this routine, it is assumed that all interrupts are locked
+; out and the stack looks like the following:
+; SP+4 -> Interrupted PC
+; SP+8-> Interrupted SR
+; */
+;
+; /* Increment the system clock. */
+; _tx_timer_system_clock++;
+;
+ PUSHM R14-R15
+ PUSHM R1-R5
+
+ MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock
+ MOV.L [R1], R2 ; Pickup system clock
+ ADD #1, R2 ; Increment system clock
+ MOV.L R2,[R1] ; Store new system clock
+;
+; /* Test for time-slice expiration. */
+; if (_tx_timer_time_slice)
+; {
+;
+ MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice
+ MOV.L [R1], R2 ; Pickup the current time slice
+ CMP #0, R2 ; Is a time slice active?
+ BEQ __tx_timer_no_time_slice ; No, skip timer slice processing
+;
+; /* Decrement the time_slice. */
+; _tx_timer_time_slice--;
+;
+ SUB #1, R2 ; Decrement the time-slice
+ MOV.L R2, [R1] ; Store time-slice
+;
+; /* Check for expiration. */
+; if (__tx_timer_time_slice == 0)
+;
+ CMP #0, R2 ; Has it expired?
+ BNE __tx_timer_no_time_slice ; No, time-slice has not expired
+;
+; /* Set the time-slice expired flag. */
+; _tx_timer_expired_time_slice = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice
+ MOV.L #1, R2 ; Build expired value
+ MOV.L R2, [R1] ; Set expired time slice variable
+; }
+;
+__tx_timer_no_time_slice:
+;
+; /* Test for timer expiration. */
+; if (*_tx_timer_current_ptr)
+; {
+;
+ MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr
+ MOV.L [R1], R2 ; Pickup current pointer
+ MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++
+ CMP #0, R1 ; Is timer pointer NULL?
+ BEQ __tx_timer_no_timer ; Yes, no timer has expired
+
+;
+; /* Set expiration flag. */
+; _tx_timer_expired = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired,R2 ; Build address of expired flag
+ MOV.L #1, R1 ; Build expired value
+ MOV.L R1, [R2]
+ BRA __tx_timer_done ; Finished with timer processing
+;
+; }
+; else
+; {
+__tx_timer_no_timer:
+;
+; /* No timer expired, increment the timer pointer. */
+; _tx_timer_current_ptr++;
+;
+; /* R2 already contains __tx_timer_current_ptr++ */
+;
+; /* Check for wrap-around. */
+; if (_tx_timer_current_ptr == _tx_timer_list_end)
+;
+ MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr
+ MOV.L [R1], R1 ; Pickup actual timer list end
+ CMP R1, R2 ; Are we at list end?
+ BNE __tx_timer_skip_wrap ; No, don't move pointer to the
+ ; top of the list
+;
+; /* Wrap to beginning of list. */
+; _tx_timer_current_ptr = _tx_timer_list_start;
+;
+ MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr
+ MOV.L [R2], R2 ; Pickup the start of the list
+; }
+;
+__tx_timer_skip_wrap:
+ MOV.L #__tx_timer_current_ptr,R1
+ MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr
+
+__tx_timer_done:
+;
+; /* See if anything has expired. */
+; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr
+ MOV.L [R1], R1 ; Pickup expired time slice
+ MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address
+ MOV.L [R2], R2 ; Pickup actual flag
+ OR R1, R2 ; Or flags together
+ BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired
+
+__tx_something_expired:
+; /* Did a timer expire? */
+; if (_tx_timer_expired)
+; {
+ MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address
+ MOV.L [R1], R1 ; Pickup expired flag
+ CMP #0,R1 ; Is the expired timer flag set?
+ BEQ __tx_timer_dont_activate ; No, skip timer activation
+;
+; /* Process timer expiration. */
+; _tx_timer_expiration_process();
+;
+ BSR __tx_timer_expiration_process ; Call the timer expiration handling routine
+;
+; }
+__tx_timer_dont_activate:
+;
+; /* Did time slice expire? */
+; if (_tx_timer_expired_time_slice)
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr
+ MOV.L [R1], R1 ; Pickup actual flag
+ CMP #0,R1 ; Has time-slice expired?
+ BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration
+;
+; /* Time slice interrupted thread. */
+; _tx_thread_time_slice();
+
+ BSR __tx_thread_time_slice ; Call time-slice processing
+; }
+;
+__tx_timer_not_ts_expiration:
+
+__tx_timer_nothing_expired:
+
+ POPM R1-R5
+ POPM R14-R15
+;
+ RTS ; return to point of interrupt
+;
+;}
+
+ .END
+
diff --git a/ports/rxv1/gnu/inc/tx_port.h b/ports/rxv1/gnu/inc/tx_port.h
new file mode 100644
index 00000000..33d4b886
--- /dev/null
+++ b/ports/rxv1/gnu/inc/tx_port.h
@@ -0,0 +1,264 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h RXv1/GNURX */
+/* 6.1.8 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+#include <string.h>
+//#include <intrinsics.h>
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+#ifdef TX_DISABLE_INLINE
+
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
+
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+
+#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+
+#else
+
+#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
+#define TX_DISABLE {interrupt_save = ((UINT)__builtin_rx_mvfc(0u) && 0x8u); __builtin_rx_clrpsw(8u);};
+#define TX_RESTORE {if(interrupt_save != 0u) {__builtin_rx_setpsw(8u);}};
+
+#define _tx_thread_system_return _tx_thread_system_return_inline
+
+static void _tx_thread_system_return_inline(void)
+{
+ TX_INTERRUPT_SAVE_AREA
+
+ TX_DISABLE
+
+ *((volatile UCHAR *)(0x872E0u)) = 1u;
+
+ TX_RESTORE
+}
+
+#endif
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv1/GNURX Version 6.1.8 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+#endif
+
diff --git a/ports/rxv1/gnu/readme_threadx.txt b/ports/rxv1/gnu/readme_threadx.txt
new file mode 100644
index 00000000..9f252a5f
--- /dev/null
+++ b/ports/rxv1/gnu/readme_threadx.txt
@@ -0,0 +1,157 @@
+ Microsoft's Azure RTOS ThreadX for Renesas RXv1
+
+ Using the GNU Tools
+
+
+1. Building the ThreadX run-time Library
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv1.
+
+
+2. Demonstration System
+
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv1.
+
+
+3. System Initialization
+
+The system entry point using the GNU tools is at the label _PowerON_Reset.
+
+The vector area is setup in the file tx_initialize_low_level.S. This file is also
+responsible for setting up various system data structures, interrupt vectors, and
+the periodic timer interrupt. This file is also an ideal place to add additional hardware
+initialization code.
+
+The ThreadX demonstration for the RXv1 utilizes CMT0 as a periodic timer interrupt
+source. The CMT0 interrupt is typically setup for 10ms periodic interrupts and the
+interrupt priority level is set to level 7. You may change any of the timer
+parameters as needed. Increasing the timer interrupt frequency increases the overhead
+of the timer handling code on the system.
+
+In addition, _tx_initialize_low_level determines the first available address for use
+by the application, which is supplied as the sole input parameter to your application
+definition function, tx_application_define. The first available memory is determined
+by the location of the '_end' label the is defined in the linker script.
+'_end' should reference the first memory AFTER all other RAM
+sections in your linker control file.
+
+
+4. Context Switch, Register Usage and Stack Frames
+
+The RXv1 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17,
+to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT
+should not be manipulated in any way by the application. The port will setup the
+interrupt within _tx_initialize_low_level and the compiler will automatically install
+the necessary interrupt vector. As such no additional initialization is necessary by the
+application.
+
+The following defines the saved context stack frame used by the ThreadX port. The
+state of the CPU registers at the time of a context switch is saved on the running
+thread's stack The top of the suspended thread's stack is pointed to by
+tx_thread_stack_ptr in the associated thread control block TX_THREAD.
+
+ Offset Interrupted Stack Frame
+
+ 0x00 1
+ 0x04 ACC0
+ 0x0C R6
+ 0x10 R7
+ 0x14 R8
+ 0x18 R9
+ 0x1C R10
+ 0x20 R11
+ 0x24 R12
+ 0x28 R13
+ 0x30 R14
+ 0x34 R15
+ 0x38 R3
+ 0x3C R4
+ 0x40 R5
+ 0x44 R1
+ 0x48 R2
+ 0x4C PC - return address
+ 0x50 PSW
+
+Note: By default GNURX does not save the state of the accumulator register ACC0
+when entering an ISR. This means that if the ISR uses any of the DSP instructions the
+content of the accumulator could be corrupted. Saving and restoring of the accumulator
+can be enabled by adding the -msave-acc-in-interrupts command line option.
+
+
+5. Improving Performance
+
+The distribution version of ThreadX is built without any compiler optimizations. This
+makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself.
+Of course, this costs some performance. To make ThreadX run faster, you can change the
+ThreadX Library project to disable debug information and enable the desired optimizations.
+
+In addition, you can eliminate the ThreadX basic API error checking by compiling your
+application code with the symbol TX_DISABLE_ERROR_CHECKING defined before tx_api.h
+is included.
+
+
+6. Timer Processing
+
+Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done
+from within the callback of a periodic timer with a period of 100Hz. In the sample projects
+a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source.
+
+
+7. Interrupt Handling
+
+Interrupt handling is unaffected by the ThreadX port as such user interrupts can be
+written according to the toolchain's documentation. It is recommended not to use interrupt
+priority 15 as this is the priority of the context switch interrupt. However using interrupt
+priority 15 won't cause any negative side effects but doing so may slightly reduce
+performance. Please refer to the toolchain documentation for additional details on how to
+define interrupt service routines.
+
+
+8. Execution Profiling
+
+The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists
+of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation
+of the EPK for generic usage details.
+
+To add the EPK to your RXv1 release make the following modifications:
+
+* Enable the following define for both the Threadx library and the application
+TX_EXECUTION_PROFILE_ENABLE
+
+* Setup CMT1 as a free running 16 bit timer.
+
+* In tx_execution_profile.h, change following around line 52:
+
+#ifdef TX_EXECUTION_64BIT_TIME
+typedef unsigned long long EXECUTION_TIME;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF
+#else
+typedef unsigned long EXECUTION_TIME;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF
+#endif
+
+/* Define basic constants for the execution profile kit. */
+
+#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A)
+
+Rebuild the Threadx library and the application.
+Refer to the EPK documentation how to interpret the results.
+
+
+9. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+08-02-2021 Initial ThreadX release for the RXv1 using GNURX tools, version 6.1.8
+
+
+Copyright(c) 1996-2021 Microsoft Corporation
+
+
+https://azure.com/rtos
+
diff --git a/ports/rxv1/gnu/src/tx_initialize_low_level.S b/ports/rxv1/gnu/src/tx_initialize_low_level.S
new file mode 100644
index 00000000..181688a6
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_initialize_low_level.S
@@ -0,0 +1,93 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Initialize */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ .text
+
+;
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_initialize_low_level RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for any low-level processor */
+;/* initialization, including setting up interrupt vectors, setting */
+;/* up a periodic timer interrupt source, saving the system stack */
+;/* pointer for use in ISR processing later, and finding the first */
+;/* available RAM memory address for tx_application_define. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+ .global __tx_initialize_low_level
+__tx_initialize_low_level:
+
+;
+; /* Save the first available memory address. */
+; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start;
+;
+ MOV.L #_end, R1 ; Pickup unused memory address
+ MOV.L #__tx_initialize_unused_memory, R2
+ MOV.L R1,[R2] ; Save first free memory address
+
+; /* Set priority of SWINT to 1. */
+ MOV.L #0x87303, r1
+ MOV.L #1, r2
+ MOV.B r2, [r1]
+
+; /* Enable SWINT. */
+ MOV.L #0x87203,r1
+ MOV.B [r1], r2
+ OR #(1 << 3), r2
+ MOV.B r2, [r1]
+
+ RTS
+
+
+ .end
diff --git a/ports/rxv1/gnu/src/tx_thread_context_restore.S b/ports/rxv1/gnu/src/tx_thread_context_restore.S
new file mode 100644
index 00000000..e6d7d4cf
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_thread_context_restore.S
@@ -0,0 +1,200 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+ .global __tx_thread_system_state
+ .global __tx_thread_current_ptr
+ .global __tx_thread_system_stack_ptr
+ .global __tx_thread_execute_ptr
+ .global __tx_timer_time_slice
+ .global __tx_thread_schedule
+ .global __tx_thread_preempt_disable
+
+ .text
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_restore RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the interrupt context if it is processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_restore(VOID)
+;{
+ .global __tx_thread_context_restore
+__tx_thread_context_restore:
+;
+; /* Lockout interrupts. */
+
+ CLRPSW I ; disable interrupts
+
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+
+ MOV.L #__tx_thread_system_state, R1
+ MOV.L [R1], R2
+ SUB #1, R2
+ MOV.L R2,[R1]
+ BEQ __tx_thread_not_nested_restore
+
+;
+; /* Interrupts are nested. */
+;
+; /* Recover the saved registers from the interrupt stack
+; and return to the point of interrupt. */
+;
+__tx_thread_nested_restore:
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+; }
+
+__tx_thread_not_nested_restore:
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+
+ MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address
+ MOV.L [R1], R2
+ CMP #0, R2
+ BEQ __tx_thread_idle_system_restore
+
+ MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag
+ MOV.L [R3], R3
+ CMP #0, R3
+ BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless
+
+ MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
+ CMP [R3], R2
+ BNE __tx_thread_preempt_restore ; jump to pre-empt restoring
+;
+__tx_thread_no_preempt_restore:
+ SETPSW U ; user stack
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+
+; }
+; else
+; {
+
+__tx_thread_preempt_restore:
+
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+
+ MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address
+ MOV.L [R3],R4 ; Pickup actual time-slice
+ CMP #0, R4
+ BEQ __tx_thread_dont_save_ts ; no time slice to save
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R4,24[R2] ; Save thread's time slice
+ MOV.L #0,R4 ; Clear value
+ MOV.L R4,[R3] ; Disable global time slice flag
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Now store the remaining registers! */
+
+ SETPSW U ; user stack
+ PUSHM R6-R13
+
+ MVFACHI R5
+ MVFACMI R6
+ PUSHM R5-R6
+
+ MOV.L #1, R3 ; indicate interrupt stack frame
+ PUSH.L R3
+
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+; R1 -> _tx_thread_current_ptr
+; R2 -> *_tx_thread_current_ptr
+
+ MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block
+ MOV.L #0,R2 ; Build NULL value
+ MOV.L R2,[R1] ; Set current thread to NULL
+
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+
+__tx_thread_idle_system_restore:
+ MVTC #0, PSW ; reset interrupt priority level to 0
+ BRA __tx_thread_schedule ; jump to scheduler
+; }
+;
+;}
+;
+ .end
diff --git a/ports/rxv1/gnu/src/tx_thread_context_save.S b/ports/rxv1/gnu/src/tx_thread_context_save.S
new file mode 100644
index 00000000..e7a4cd4b
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_thread_context_save.S
@@ -0,0 +1,158 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ .global __tx_thread_system_state
+ .global __tx_thread_current_ptr
+ .global __tx_thread_system_stack_ptr
+
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ .global __tx_thread_context_save
+__tx_thread_context_save:
+;
+; /* Upon entry to this routine, it is assumed that interrupts are locked
+; out and the (interrupt) stack frame looks like the following:
+;
+; (lower address) SP -> [return address of this call]
+; SP+4 -> Saved R1
+; SP+8 -> Saved R2
+; SP+12-> Interrupted PC
+; SP+16-> Interrupted PSW
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+
+ MOV.L #__tx_thread_system_state, R1 ; pick up address of system state
+ MOV.L [R1], R2 ; pick up system state
+ CMP #0, R2 ; 0 -> no nesting
+ BEQ __tx_thread_not_nested_save
+;
+; /* Nested interrupt condition. */
+;
+ ADD #1, r2 ; _tx_thread_system_state++
+ MOV.L r2, [r1]
+
+;
+; /* Save the rest of the scratch registers on the interrupt stack and return to the
+; calling ISR. */
+ POP R1 ; recuperate return address from stack
+ PUSHM R3-R5
+ PUSHM R14-R15
+ JMP R1 ; return address was preserved in R1
+
+;
+__tx_thread_not_nested_save:
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD #1, R2 ; _tx_thread_system_state++
+ MOV.L R2, [R1]
+
+ MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer
+ MOV.L [R2], R2
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore
+;
+; /* Move stack frame over to the current threads stack. */
+; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */
+;
+ MVFC USP, R1 ; pick up user stack pointer
+ MOV.L 16[R0], R2
+ MOV.L R2, [-R1] ; save PSW on thread stack
+ MOV.L 12[R0], R2
+ MOV.L R2, [-R1] ; save PC on thread stack
+ MOV.L 8[R0], R2
+ MOV.L R2, [-R1] ; save R2 on thread stack
+ MOV.L 4[R0], R2
+ MOV.L R2, [-R1] ; save R1 on thread stack
+ MOV.L R5, [-R1] ; save R5 on thread stack
+ MOV.L R4, [-R1] ; save R4 on thread stack
+ MOV.L R3, [-R1] ; save R3 on thread stack
+ MOV.L R15, [-R1] ; save R15 on thread stack
+ MOV.L R14, [-R1] ; save R14 on thread stack
+
+ POP R2 ; pick up return address from interrupt stack
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom
+ MVTC R1, USP ; set user/thread stack pointer
+ JMP R2 ; return to ISR
+
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save:
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+ POP R1 ; pick up return address
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
+ JMP R1 ; return to caller
+;
+; }
+;}
+ .end
+
diff --git a/ports/rxv1/gnu/src/tx_thread_interrupt_control.S b/ports/rxv1/gnu/src/tx_thread_interrupt_control.S
new file mode 100644
index 00000000..87b5ebe3
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_thread_interrupt_control.S
@@ -0,0 +1,87 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_control RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for changing the interrupt lockout */
+;/* posture of the system. */
+;/* */
+;/* INPUT */
+;/* */
+;/* new_posture New interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_control(UINT new_posture)
+;{
+
+ .global __tx_thread_interrupt_control
+__tx_thread_interrupt_control:
+;
+; /* Pickup current interrupt lockout posture. */
+;
+
+ MVFC PSW, R2 ; Save PSW to R2
+ MOV.L R2, R3 ; Make a copy of PSW in r3
+
+;
+; /* Apply the new interrupt posture. */
+;
+
+ BTST #16, R1 ; test I bit of PSW of "new posture"
+ BMNE #16, R2 ; conditionally set I bit of intermediate posture
+
+ MVTC R2, PSW ; save intermediate posture to PSW
+
+ MOV.L R3,R1 ; Get original SR
+ RTS ; Return to caller
+;}
+ .end
+
diff --git a/ports/rxv1/gnu/src/tx_thread_schedule.S b/ports/rxv1/gnu/src/tx_thread_schedule.S
new file mode 100644
index 00000000..1a6779da
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_thread_schedule.S
@@ -0,0 +1,163 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ .global __tx_thread_execute_ptr
+ .global __tx_thread_current_ptr
+ .global __tx_timer_time_slice
+;
+ .text
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_schedule RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function waits for a thread control block pointer to appear in */
+;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+;/* in the variable, the corresponding thread is resumed. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* _tx_thread_system_return Return to system from thread */
+;/* _tx_thread_context_restore Restore thread's context */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_schedule(VOID)
+;{
+ .global __tx_thread_schedule
+__tx_thread_schedule:
+;
+; /* Enable interrupts. */
+;
+ SETPSW I
+;
+; /* Wait for a thread to execute. */
+; do
+; {
+ MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr
+__tx_thread_schedule_loop:
+ MOV.L [R1],R2 ; Pickup next thread to execute
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking
+;
+; }
+; while(_tx_thread_execute_ptr == TX_NULL);
+;
+; /* Yes! We have a thread to execute. Lockout interrupts and
+; transfer control to it. */
+;
+ CLRPSW I ; disable interrupts
+;
+; /* Setup the current thread pointer. */
+; _tx_thread_current_ptr = _tx_thread_execute_ptr;
+;
+ MOV.L #__tx_thread_current_ptr, R3
+ MOV.L R2,[R3] ; Setup current thread pointer
+;
+; /* Increment the run count for this thread. */
+; _tx_thread_current_ptr -> tx_thread_run_count++;
+;
+ MOV.L 4[R2],R3 ; Pickup run count
+ ADD #1,R3 ; Increment run counter
+ MOV.L R3,4[R2] ; Store it back in control block
+;
+; /* Setup time-slice, if present. */
+; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+;
+ MOV.L 24[R2],R3 ; Pickup thread time-slice
+ MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice
+ MOV.L R3, [R4] ; Setup time-slice
+;
+; /* Switch to the thread's stack. */
+; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+ SETPSW U ; user stack mode
+ MOV.L 8[R2],R0 ; Pickup stack pointer
+;
+; /* Determine if an interrupt frame or a synchronous task suspension frame
+; is present. */
+;
+ POP R1 ; Pickup stack type
+ CMP #1, R1 ; Is it an interrupt stack?
+ BNE __tx_thread_synch_return ; No, a synchronous return frame is present.
+
+ POPM R1-R2 ; Restore accumulator.
+ MVTACLO R2
+ MVTACHI R1
+
+ POPM R6-R13 ; Recover interrupt stack frame
+ POPM R14-R15
+ POPM R3-R5
+ POPM R1-R2
+ RTE ; return to point of interrupt, this restores PC and PSW
+
+__tx_thread_synch_return:
+ POPC PSW
+ POPM R6-R13 ; Recover solicited stack frame
+ RTS
+;
+;}
+
+
+.global __tx_thread_context_save
+.global __tx_thread_context_restore
+
+
+; Software triggered interrupt used to perform context switches.
+; The priority of this interrupt is set to the lowest priority within
+; tx_initialize_low_level() and triggered by ThreadX when calling
+; _tx_thread_system_return().
+.global $tableentry$27$.rvectors
+$tableentry$27$.rvectors:
+
+ PUSHM R1-R2
+
+ BSR __tx_thread_context_save
+
+ BRA __tx_thread_context_restore
+
+ .end
diff --git a/ports/rxv1/gnu/src/tx_thread_stack_build.S b/ports/rxv1/gnu/src/tx_thread_stack_build.S
new file mode 100644
index 00000000..dd0f42f5
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_thread_stack_build.S
@@ -0,0 +1,137 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_stack_build RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function builds a stack frame on the supplied thread's stack. */
+;/* The stack frame results in a fake interrupt return to the supplied */
+;/* function pointer. */
+;/* */
+;/* INPUT */
+;/* */
+;/* thread_ptr Pointer to thread control blk */
+;/* function_ptr Pointer to return function */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_thread_create Create thread service */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+;{
+ .global __tx_thread_stack_build
+__tx_thread_stack_build:
+;
+;
+; /* Build an interrupt frame. The form of the fake interrupt stack
+; on the Renesas RX should look like the following after it is built:
+;
+; Stack Top: 1 Interrupt stack frame type
+; ACC0
+; ACC1
+; R6
+; R7
+; R8
+; R9
+; R10
+; R11
+; R12
+; R13
+; FPSW
+; R14
+; R15
+; R3
+; R4
+; R5
+; R1
+; R2
+; PC
+; PSW
+
+;
+; Stack Bottom: (higher memory address) */
+;
+ MOV.L 16[R1],R3 ; Pickup end of stack area
+ BCLR #0, R3 ; mask for 4-byte alignment
+ BCLR #1, R3
+;
+; /* Build the stack frame. */
+;
+ MOV.L #30000h, R4
+ MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set)
+ MOV.L R2, [-R3] ; initial PC
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R2 ...
+ MOV.L R4,[-R3] ; initial R1 ...
+ MOV.L R4,[-R3] ; initial R5 ...
+ MOV.L R4,[-R3] ; initial R4 ...
+ MOV.L R4,[-R3] ; initial R3 ...
+ MOV.L R4,[-R3] ; initial R15 ...
+ MOV.L R4,[-R3] ; initial R14 ...
+ MOV.L R4,[-R3] ; initial R13 ...
+ MOV.L R4,[-R3] ; initial R12 ...
+ MOV.L R4,[-R3] ; initial R11 ...
+ MOV.L R4,[-R3] ; initial R10 ...
+ MOV.L R4,[-R3] ; initial R9 ...
+ MOV.L R4,[-R3] ; initial R8 ...
+ MOV.L R4,[-R3] ; initial R7 ...
+ MOV.L R4,[-R3] ; initial R6 ...
+
+ MOV.L R4,[-R3] ; Accumulator 0
+ MOV.L R4,[-R3]
+
+ MOV.L #1, R4
+ MOV.L R4,[-R3] ; indicate interrupt stack frame
+; /* Setup stack pointer. */
+; thread_ptr -> tx_thread_stack_ptr = R1;
+ MOV.L R3, 8[R1]
+ ; store initial SP in thread control block
+ RTS
+
+;}
+ .end
+
diff --git a/ports/rxv1/gnu/src/tx_thread_system_return.S b/ports/rxv1/gnu/src/tx_thread_system_return.S
new file mode 100644
index 00000000..d1393744
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_thread_system_return.S
@@ -0,0 +1,117 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ .global __tx_thread_current_ptr
+ .global __tx_timer_time_slice
+ .global __tx_thread_schedule
+
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_system_return RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is target processor specific. It is used to transfer */
+;/* control from a thread back to the system. Only a minimal context */
+;/* is saved since the compiler assumes temp registers are going to get */
+;/* slicked by a function call anyway. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling loop */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ThreadX components */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_system_return(VOID)
+;{
+ .GLB __tx_thread_system_return
+__tx_thread_system_return:
+;
+; /* Save call save registers on the stack. */
+;
+ PUSHM R6-R13
+ PUSHC PSW
+ MOV.L #0, R1
+ PUSH.L R1 ; solicited stack frame
+;
+; /* Lockout interrupts. */
+;
+ CLRPSW I ; Lockout interrupts
+;
+; /* Save current stack in current Thread controle block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
+ MOV.L #__tx_thread_current_ptr, R2
+ MOV.L [R2], R3
+ MOV.L R0, 8[R3]
+
+ MOV.L #__tx_timer_time_slice, R4
+ MOV.L [R4], R5
+
+; /* Determine if the time-slice is active. */
+; if (_tx_timer_time_slice)
+; {
+;
+ CMP #0,R5 ; Is a time-slice present?
+ BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice
+;
+; /* Save time-slice for the thread and clear the current time-slice. */
+ ; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+ MOV.L R5,24[R3]
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R1, [R4] ; Disable the time-slice
+;
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Clear the current thread pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+;
+ MOV.L R1, [R2]
+ BRA __tx_thread_schedule
+;}
+ .end
+
diff --git a/ports/rxv1/gnu/src/tx_timer_interrupt.S b/ports/rxv1/gnu/src/tx_timer_interrupt.S
new file mode 100644
index 00000000..bec00c57
--- /dev/null
+++ b/ports/rxv1/gnu/src/tx_timer_interrupt.S
@@ -0,0 +1,239 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Timer */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ .global __tx_timer_time_slice
+ .global __tx_timer_system_clock
+ .global __tx_timer_current_ptr
+ .global __tx_timer_list_start
+ .global __tx_timer_list_end
+ .global __tx_timer_expired_time_slice
+ .global __tx_timer_expired
+ .global __tx_timer_expiration_process
+ .global __tx_thread_context_save
+ .global __tx_thread_time_slice
+ .global __tx_thread_context_restore
+
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_timer_interrupt RXv1/GNURX */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function processes the hardware timer interrupt. This */
+;/* processing includes incrementing the system clock and checking for */
+;/* time slice and/or timer expiration. If either is found, the */
+;/* interrupt context save/restore functions are called along with the */
+;/* expiration functions. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_context_save Save interrupted context */
+;/* _tx_timer_expiration_process Timer expiration processing */
+;/* _tx_thread_time_slice Time slice interrupted thread */
+;/* _tx_thread_context_restore Restore interrupted context */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* interrupt vector */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_timer_interrupt(VOID)
+;{
+ .global __tx_timer_interrupt
+__tx_timer_interrupt:
+;
+; /* Upon entry to this routine, it is assumed that all interrupts are locked
+; out and the stack looks like the following:
+; SP+4 -> Interrupted PC
+; SP+8-> Interrupted SR
+; */
+;
+; /* Increment the system clock. */
+; _tx_timer_system_clock++;
+;
+ PUSHM R14-R15
+ PUSHM R1-R5
+
+ MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock
+ MOV.L [R1], R2 ; Pickup system clock
+ ADD #1, R2 ; Increment system clock
+ MOV.L R2,[R1] ; Store new system clock
+;
+; /* Test for time-slice expiration. */
+; if (_tx_timer_time_slice)
+; {
+;
+ MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice
+ MOV.L [R1], R2 ; Pickup the current time slice
+ CMP #0, R2 ; Is a time slice active?
+ BEQ __tx_timer_no_time_slice ; No, skip timer slice processing
+;
+; /* Decrement the time_slice. */
+; _tx_timer_time_slice--;
+;
+ SUB #1, R2 ; Decrement the time-slice
+ MOV.L R2, [R1] ; Store time-slice
+;
+; /* Check for expiration. */
+; if (__tx_timer_time_slice == 0)
+;
+ CMP #0, R2 ; Has it expired?
+ BNE __tx_timer_no_time_slice ; No, time-slice has not expired
+;
+; /* Set the time-slice expired flag. */
+; _tx_timer_expired_time_slice = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice
+ MOV.L #1, R2 ; Build expired value
+ MOV.L R2, [R1] ; Set expired time slice variable
+; }
+;
+__tx_timer_no_time_slice:
+;
+; /* Test for timer expiration. */
+; if (*_tx_timer_current_ptr)
+; {
+;
+ MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr
+ MOV.L [R1], R2 ; Pickup current pointer
+ MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++
+ CMP #0, R1 ; Is timer pointer NULL?
+ BEQ __tx_timer_no_timer ; Yes, no timer has expired
+
+;
+; /* Set expiration flag. */
+; _tx_timer_expired = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired,R2 ; Build address of expired flag
+ MOV.L #1, R1 ; Build expired value
+ MOV.L R1, [R2]
+ BRA __tx_timer_done ; Finished with timer processing
+;
+; }
+; else
+; {
+__tx_timer_no_timer:
+;
+; /* No timer expired, increment the timer pointer. */
+; _tx_timer_current_ptr++;
+;
+; /* R2 already contains __tx_timer_current_ptr++ */
+;
+; /* Check for wrap-around. */
+; if (_tx_timer_current_ptr == _tx_timer_list_end)
+;
+ MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr
+ MOV.L [R1], R1 ; Pickup actual timer list end
+ CMP R1, R2 ; Are we at list end?
+ BNE __tx_timer_skip_wrap ; No, don't move pointer to the
+ ; top of the list
+;
+; /* Wrap to beginning of list. */
+; _tx_timer_current_ptr = _tx_timer_list_start;
+;
+ MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr
+ MOV.L [R2], R2 ; Pickup the start of the list
+; }
+;
+__tx_timer_skip_wrap:
+ MOV.L #__tx_timer_current_ptr,R1
+ MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr
+
+__tx_timer_done:
+;
+; /* See if anything has expired. */
+; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr
+ MOV.L [R1], R1 ; Pickup expired time slice
+ MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address
+ MOV.L [R2], R2 ; Pickup actual flag
+ OR R1, R2 ; Or flags together
+ BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired
+
+__tx_something_expired:
+; /* Did a timer expire? */
+; if (_tx_timer_expired)
+; {
+ MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address
+ MOV.L [R1], R1 ; Pickup expired flag
+ CMP #0,R1 ; Is the expired timer flag set?
+ BEQ __tx_timer_dont_activate ; No, skip timer activation
+;
+; /* Process timer expiration. */
+; _tx_timer_expiration_process();
+;
+ BSR __tx_timer_expiration_process ; Call the timer expiration handling routine
+;
+; }
+__tx_timer_dont_activate:
+;
+; /* Did time slice expire? */
+; if (_tx_timer_expired_time_slice)
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr
+ MOV.L [R1], R1 ; Pickup actual flag
+ CMP #0,R1 ; Has time-slice expired?
+ BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration
+;
+; /* Time slice interrupted thread. */
+; _tx_thread_time_slice();
+
+ BSR __tx_thread_time_slice ; Call time-slice processing
+; }
+;
+__tx_timer_not_ts_expiration:
+
+__tx_timer_nothing_expired:
+
+ POPM R1-R5
+ POPM R14-R15
+;
+ RTS ; return to point of interrupt
+;
+;}
+
+ .end
+
diff --git a/ports/rxv1/iar/inc/tx_port.h b/ports/rxv1/iar/inc/tx_port.h
new file mode 100644
index 00000000..880ff6d7
--- /dev/null
+++ b/ports/rxv1/iar/inc/tx_port.h
@@ -0,0 +1,273 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h RXv1/IAR */
+/* 6.1.8 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+#include <string.h>
+#include <intrinsics.h>
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+#ifdef TX_DISABLE_INLINE
+
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
+
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+
+#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+
+#else
+
+#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save;
+#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();};
+#define TX_RESTORE {__set_interrupt_state(interrupt_save);};
+
+#define _tx_thread_system_return _tx_thread_system_return_inline
+
+static void _tx_thread_system_return_inline(void)
+{
+ TX_INTERRUPT_SAVE_AREA
+
+ TX_DISABLE
+
+ *((volatile UCHAR *)(0x872E0u)) = 1u;
+
+ TX_RESTORE
+}
+
+#endif
+
+
+#ifndef TX_THREAD_GET_SYSTEM_STATE
+
+extern volatile ULONG _tx_thread_system_state;
+#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | ((~__get_PSW_register()) & (1u << 17u)))
+#endif
+
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RXv1/IAR Version 6.1.8 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+
+#endif
+
diff --git a/ports/rxv1/iar/readme_threadx.txt b/ports/rxv1/iar/readme_threadx.txt
new file mode 100644
index 00000000..c36fb88f
--- /dev/null
+++ b/ports/rxv1/iar/readme_threadx.txt
@@ -0,0 +1,153 @@
+ Microsoft's Azure RTOS ThreadX for Renesas RXv1
+
+ Using the IAR Tools
+
+
+1. Building the ThreadX run-time Library
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv1.
+
+
+2. Demonstration System
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv1.
+
+
+3. System Initialization
+
+The system entry point using the IAR tools is at the label __iar_program_start.
+
+The vector area is setup in the file tx_initialize_low_level.s. This file is also
+responsible for setting up various system data structures, interrupt vectors, and
+the periodic timer interrupt. This file is also an ideal place add hardware
+initialization code.
+
+The ThreadX demonstration for the RXv1 utilizes CMT0 as a periodic timer interrupt
+source. The CMT0 interrupt is typically setup for 10ms periodic interrupts and the
+interrupt priority level is set to level 7. You may change any of the timer
+parameters as needed.
+
+In addition, _tx_initialize_low_level determines the first available address for use
+by the application, which is supplied as the sole input parameter to your application
+definition function, tx_application_define. The first available memory is determined
+by the location of the FREEMEM section so it should be placed AFTER all other RAM
+sections in your linker control file.
+
+
+4. Context Switch, Register Usage and Stack Frames
+
+The RXv1 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17,
+to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT
+should not be manipulated in any way by the application. The port will setup the
+interrupt within _tx_initialize_low_level and the compiler will automatically install
+the necessary interrupt vector. As such no additional initialization is necessary by the
+application.
+
+The following defines the saved context stack frame used by the ThreadX port. The
+state of the CPU registers at the time of a context switch is saved on the running
+thread's stack The top of the suspended thread's stack is pointed to by
+tx_thread_stack_ptr in the associated thread control block TX_THREAD.
+
+ Offset Interrupted Stack Frame
+
+ 0x00 1
+ 0x04 ACC0
+ 0x0C R6
+ 0x10 R7
+ 0x14 R8
+ 0x18 R9
+ 0x1C R10
+ 0x20 R11
+ 0x24 R12
+ 0x28 R13
+ 0x30 R14
+ 0x34 R15
+ 0x38 R3
+ 0x3C R4
+ 0x40 R5
+ 0x44 R1
+ 0x48 R2
+ 0x4C PC - return address
+ 0x50 PSW
+
+Note: By default IAR does not save the state of the accumulator register ACC0
+when entering an ISR. This means that if the ISR uses any of the DSP instructions the
+content of the accumulator could be corrupted. Saving and restoring of the accumulator
+can be enabled by adding the --save_acc command line option.
+
+
+5. Improving Performance
+
+The distribution version of ThreadX is built without any compiler optimizations. This
+makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself.
+Of course, this costs some performance. To make ThreadX run faster, you can change the
+ThreadX Library project to disable debug information and enable the desired optimizations.
+
+In addition, you can eliminate the ThreadX basic API error checking by compiling your
+application code with the symbol TX_DISABLE_ERROR_CHECKING defined before tx_api.h
+is included.
+
+
+6. Timer Processing
+
+Timer procession is performed by calling __tx_timer_interrupt(). This should usually be done
+from within the callback of a periodic timer with a period of 100Hz. In the sample projects
+a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source.
+
+
+7. Interrupt Handling
+
+Interrupt handling is unaffected by the ThreadX port as such user interrupts can be
+written according to the toolchain's documentation. It is recommended not to use interrupt
+priority 15 as this is the priority of the context switch interrupt. However using interrupt
+priority 15 won't cause any negative side effects but doing so may slightly reduce
+performance. Please refer to the toolchain documentation for additional details on how to
+define interrupt service routines.
+
+
+8. Execution Profiling
+
+The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists
+of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation
+of the EPK for generic usage details.
+
+To add the EPK to your RXv1 release make the following modifications:
+
+* Enable the following define for both the Threadx library and the application
+TX_EXECUTION_PROFILE_ENABLE
+
+* Setup CMT1 as a free running 16 bit timer.
+
+* In tx_execution_profile.h, change following around line 52:
+
+#ifdef TX_EXECUTION_64BIT_TIME
+typedef unsigned long long EXECUTION_TIME;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF
+#else
+typedef unsigned long EXECUTION_TIME;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF
+#endif
+
+/* Define basic constants for the execution profile kit. */
+
+#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A)
+
+Rebuild the Threadx library and the application.
+Refer to the EPK documentation how to interpret the results.
+
+
+9. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+08-02-2021 Initial ThreadX release for the RXv1using IAR tools, version 6.1.8
+
+
+Copyright(c) 1996-2021 Microsoft Corporation
+
+
+https://azure.com/rtos \ No newline at end of file
diff --git a/ports/rxv1/iar/src/tx_initialize_low_level.s b/ports/rxv1/iar/src/tx_initialize_low_level.s
new file mode 100644
index 00000000..9d33e8d3
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_initialize_low_level.s
@@ -0,0 +1,99 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Initialize */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ extern __tx_initialize_unused_memory
+
+ section .text:CODE:ROOT
+
+;
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_initialize_low_level RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for any low-level processor */
+;/* initialization, including setting up interrupt vectors, setting */
+;/* up a periodic timer interrupt source, saving the system stack */
+;/* pointer for use in ISR processing later, and finding the first */
+;/* available RAM memory address for tx_application_define. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+ public __tx_initialize_low_level
+
+__tx_initialize_low_level:
+
+; /* Save the first available memory address. */
+; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start;
+;
+ MOV.L #__tx_free_memory_start, R1 ; Pickup unused memory address
+ MOV.L #__tx_initialize_unused_memory,R2
+ MOV.L R1,[R2] ; Save first free memory address
+
+; /* Set priority of SWINT to 1. */
+ MOV.L #0x87303, r1
+ MOV.L #1, r2
+ MOV.B r2, [r1]
+
+; /* Enable SWINT. */
+ MOV.L #0x87203, r1
+ MOV.B [r1], r2
+ OR #(1 << 3), r2
+ MOV.B r2, [r1]
+
+ RTS
+
+ section FREEMEM:DATA
+ public __tx_free_memory_start
+__tx_free_memory_start
+ DS32 4
+
+ END
diff --git a/ports/rxv1/iar/src/tx_thread_context_restore.s b/ports/rxv1/iar/src/tx_thread_context_restore.s
new file mode 100644
index 00000000..cb1746e2
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_thread_context_restore.s
@@ -0,0 +1,187 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ extern __tx_thread_system_state
+ extern __tx_thread_current_ptr
+ extern __tx_thread_preempt_disable
+ extern __tx_thread_execute_ptr
+ extern __tx_timer_time_slice
+ extern __tx_thread_schedule
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_restore RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the interrupt context if it is processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+ public __tx_thread_context_restore
+
+__tx_thread_context_restore:
+;
+; /* Lockout interrupts. */
+
+ CLRPSW I ; disable interrupts
+
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+
+ MOV.L #__tx_thread_system_state, R1
+ MOV.L [R1], R2
+ SUB #1, R2
+ MOV.L R2,[R1]
+ BEQ __tx_thread_not_nested_restore
+
+;
+; /* Interrupts are nested. */
+;
+; /* Recover the saved registers from the interrupt stack
+; and return to the point of interrupt. */
+;
+__tx_thread_nested_restore:
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+; }
+
+__tx_thread_not_nested_restore:
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+
+ MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address
+ MOV.L [R1], R2
+ CMP #0, R2
+ BEQ __tx_thread_idle_system_restore
+
+ MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag
+ MOV.L [R3], R3
+ CMP #0, R3
+ BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless
+
+ MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
+ CMP [R3], R2
+ BNE __tx_thread_preempt_restore ; jump to pre-empt restoring
+;
+__tx_thread_no_preempt_restore:
+ SETPSW U ; user stack
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+
+; }
+; else
+; {
+
+__tx_thread_preempt_restore:
+
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+
+ MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address
+ MOV.L [R3],R4 ; Pickup actual time-slice
+ CMP #0, R4
+ BEQ __tx_thread_dont_save_ts ; no time slice to save
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R4,24[R2] ; Save thread's time slice
+ MOV.L #0,R4 ; Clear value
+ MOV.L R4,[R3] ; Disable global time slice flag
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Now store the remaining registers! */
+
+ SETPSW U ; user stack
+ PUSHM R6-R13
+
+ MVFACHI R5
+ MVFACMI R6
+ PUSHM R5-R6
+
+ MOV.L #1, R3 ; indicate interrupt stack frame
+ PUSH.L R3
+
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+; R1 -> _tx_thread_current_ptr
+; R2 -> *_tx_thread_current_ptr
+
+ MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block
+ MOV.L #0,R2 ; Build NULL value
+ MOV.L R2,[R1] ; Set current thread to NULL
+
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+
+__tx_thread_idle_system_restore:
+ MVTC #0, PSW ; reset interrupt priority level to 0
+ BRA __tx_thread_schedule ; jump to scheduler
+; }
+;
+;}
+;
+ END
diff --git a/ports/rxv1/iar/src/tx_thread_context_save.s b/ports/rxv1/iar/src/tx_thread_context_save.s
new file mode 100644
index 00000000..4b07ffeb
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_thread_context_save.s
@@ -0,0 +1,157 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ extern __tx_thread_system_state
+ extern __tx_thread_current_ptr
+
+ section .text:CODE:ROOT
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ public __tx_thread_context_save
+
+__tx_thread_context_save:
+;
+; /* Upon entry to this routine, it is assumed that interrupts are locked
+; out and the (interrupt) stack frame looks like the following:
+;
+; (lower address) SP -> [return address of this call]
+; SP+4 -> Saved R1
+; SP+8 -> Saved R2
+; SP+12-> Interrupted PC
+; SP+16-> Interrupted PSW
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+
+ MOV.L #__tx_thread_system_state, R1 ; pick up address of system state
+ MOV.L [R1], R2 ; pick up system state
+ CMP #0, R2 ; 0 -> no nesting
+ BEQ __tx_thread_not_nested_save
+;
+; /* Nested interrupt condition. */
+;
+ ADD #1, r2 ; _tx_thread_system_state++
+ MOV.L r2, [r1]
+
+;
+; /* Save the rest of the scratch registers on the interrupt stack and return to the
+; calling ISR. */
+ POP R1 ; recuperate return address from stack
+ PUSHM R3-R5
+ PUSHM R14-R15
+ JMP R1 ; return address was preserved in R1
+
+;
+__tx_thread_not_nested_save:
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD #1, R2 ; _tx_thread_system_state++
+ MOV.L R2, [R1]
+
+ MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer
+ MOV.L [R2], R2
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore
+;
+; /* Move stack frame over to the current threads stack. */
+; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */
+;
+ MVFC USP, R1 ; pick up user stack pointer
+ MOV.L 16[R0], R2
+ MOV.L R2, [-R1] ; save PSW on thread stack
+ MOV.L 12[R0], R2
+ MOV.L R2, [-R1] ; save PC on thread stack
+ MOV.L 8[R0], R2
+ MOV.L R2, [-R1] ; save R2 on thread stack
+ MOV.L 4[R0], R2
+ MOV.L R2, [-R1] ; save R1 on thread stack
+ MOV.L R5, [-R1] ; save R5 on thread stack
+ MOV.L R4, [-R1] ; save R4 on thread stack
+ MOV.L R3, [-R1] ; save R3 on thread stack
+ MOV.L R15, [-R1] ; save R15 on thread stack
+ MOV.L R14, [-R1] ; save R14 on thread stack
+
+ POP R2 ; pick up return address from interrupt stack
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom
+ MVTC R1, USP ; set user/thread stack pointer
+ JMP R2 ; return to ISR
+
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save:
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+ POP R1 ; pick up return address
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
+ JMP R1 ; return to caller
+;
+; }
+;}
+ END
diff --git a/ports/rxv1/iar/src/tx_thread_interrupt_control.s b/ports/rxv1/iar/src/tx_thread_interrupt_control.s
new file mode 100644
index 00000000..17de512c
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_thread_interrupt_control.s
@@ -0,0 +1,85 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ section .text:CODE:ROOT
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_control RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for changing the interrupt lockout */
+;/* posture of the system. */
+;/* */
+;/* INPUT */
+;/* */
+;/* new_posture New interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_control(UINT new_posture)
+;{
+ public __tx_thread_interrupt_control
+__tx_thread_interrupt_control:
+;
+; /* Pickup current interrupt lockout posture. */
+;
+
+ MVFC PSW, R2 ; Save PSW to R2
+ MOV.L R2, R3 ; Make a copy of PSW in r3
+
+;
+; /* Apply the new interrupt posture. */
+;
+
+ BTST #16, R1 ; test I bit of PSW of "new posture"
+ BMNE #16, R2 ; conditionally set I bit of intermediate posture
+
+ MVTC R2, PSW ; save intermediate posture to PSW
+
+ MOV.L R3,R1 ; Get original SR
+ RTS ; Return to caller
+;}
+ END
diff --git a/ports/rxv1/iar/src/tx_thread_schedule.s b/ports/rxv1/iar/src/tx_thread_schedule.s
new file mode 100644
index 00000000..14b42907
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_thread_schedule.s
@@ -0,0 +1,162 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ extern __tx_thread_execute_ptr
+ extern __tx_thread_current_ptr
+ extern __tx_timer_time_slice
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_schedule RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function waits for a thread control block pointer to appear in */
+;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+;/* in the variable, the corresponding thread is resumed. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* _tx_thread_system_return Return to system from thread */
+;/* _tx_thread_context_restore Restore thread's context */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_schedule(VOID)
+;{
+ public __tx_thread_schedule
+
+__tx_thread_schedule:
+;
+; /* Enable interrupts. */
+;
+ SETPSW I
+;
+; /* Wait for a thread to execute. */
+; do
+; {
+ MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr
+__tx_thread_schedule_loop:
+ MOV.L [R1],R2 ; Pickup next thread to execute
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking
+;
+; }
+; while(_tx_thread_execute_ptr == TX_NULL);
+;
+; /* Yes! We have a thread to execute. Lockout interrupts and
+; transfer control to it. */
+;
+ CLRPSW I ; disable interrupts
+;
+; /* Setup the current thread pointer. */
+; _tx_thread_current_ptr = _tx_thread_execute_ptr;
+;
+ MOV.L #__tx_thread_current_ptr, R3
+ MOV.L R2,[R3] ; Setup current thread pointer
+;
+; /* Increment the run count for this thread. */
+; _tx_thread_current_ptr -> tx_thread_run_count++;
+;
+ MOV.L 4[R2],R3 ; Pickup run count
+ ADD #1,R3 ; Increment run counter
+ MOV.L R3,4[R2] ; Store it back in control block
+;
+; /* Setup time-slice, if present. */
+; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+;
+ MOV.L 24[R2],R3 ; Pickup thread time-slice
+ MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice
+ MOV.L R3, [R4] ; Setup time-slice
+;
+; /* Switch to the thread's stack. */
+; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+ SETPSW U ; user stack mode
+ MOV.L 8[R2],R0 ; Pickup stack pointer
+;
+; /* Determine if an interrupt frame or a synchronous task suspension frame
+; is present. */
+;
+ POP R1 ; Pickup stack type
+ CMP #1, R1 ; Is it an interrupt stack?
+ BNE __tx_thread_synch_return ; No, a synchronous return frame is present.
+
+ POPM R1-R2 ; Restore accumulator.
+ MVTACLO R2
+ MVTACHI R1
+
+ POPM R6-R13 ; Recover interrupt stack frame
+ POPM R14-R15
+ POPM R3-R5
+ POPM R1-R2
+ RTE ; return to point of interrupt, this restores PC and PSW
+
+__tx_thread_synch_return:
+ POPC PSW
+ POPM R6-R13 ; Recover solicited stack frame
+ RTS
+;
+;}
+
+ extern __tx_thread_context_save
+ extern __tx_thread_context_restore
+
+; Software triggered interrupt used to perform context switches.
+; The priority of this interrupt is set to the lowest priority within
+; tx_initialize_low_level() and triggered by ThreadX when calling
+; _tx_thread_system_return().
+ public ___interrupt_27
+___interrupt_27:
+
+ PUSHM R1-R2
+
+ BSR __tx_thread_context_save
+
+ BRA __tx_thread_context_restore
+
+ END
diff --git a/ports/rxv1/iar/src/tx_thread_stack_build.s b/ports/rxv1/iar/src/tx_thread_stack_build.s
new file mode 100644
index 00000000..d52a40e9
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_thread_stack_build.s
@@ -0,0 +1,137 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_stack_build RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function builds a stack frame on the supplied thread's stack. */
+;/* The stack frame results in a fake interrupt return to the supplied */
+;/* function pointer. */
+;/* */
+;/* INPUT */
+;/* */
+;/* thread_ptr Pointer to thread control blk */
+;/* function_ptr Pointer to return function */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_thread_create Create thread service */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+
+ public __tx_thread_stack_build
+
+__tx_thread_stack_build:
+;
+;
+; /* Build an interrupt frame. The form of the fake interrupt stack
+; on the Renesas RX should look like the following after it is built:
+;
+; Stack Top: 1 Interrupt stack frame type
+; ACC0
+; R6
+; R7
+; R8
+; R9
+; R10
+; R11
+; R12
+; R13
+; R14
+; R15
+; R3
+; R4
+; R5
+; R1
+; R2
+; PC
+; PSW
+
+;
+; Stack Bottom: (higher memory address) */
+;
+ MOV.L 16[R1],R3 ; Pickup end of stack area
+ BCLR #0, R3 ; mask for 4-byte alignment
+ BCLR #1, R3
+;
+; /* Build the stack frame. */
+;
+ MOV.L #30000h, R4
+ MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set)
+ MOV.L R2, [-R3] ; initial PC
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R2 ...
+ MOV.L R4,[-R3] ; initial R1 ...
+ MOV.L R4,[-R3] ; initial R5 ...
+ MOV.L R4,[-R3] ; initial R4 ...
+ MOV.L R4,[-R3] ; initial R3 ...
+ MOV.L R4,[-R3] ; initial R15 ...
+ MOV.L R4,[-R3] ; initial R14 ...
+ MOV.L R4,[-R3] ; initial R13 ...
+ MOV.L R4,[-R3] ; initial R12 ...
+ MOV.L R4,[-R3] ; initial R11 ...
+ MOV.L R4,[-R3] ; initial R10 ...
+ MOV.L R4,[-R3] ; initial R9 ...
+ MOV.L R4,[-R3] ; initial R8 ...
+ MOV.L R4,[-R3] ; initial R7 ...
+ MOV.L R4,[-R3] ; initial R6 ...
+
+ MOV.L R4,[-R3] ; Accumulator 0
+ MOV.L R4,[-R3]
+
+ MOV.L #1, R4
+ MOV.L R4,[-R3] ; indicate interrupt stack frame
+; /* Setup stack pointer. */
+; thread_ptr -> tx_thread_stack_ptr = R1;
+ MOV.L R3, 8[R1]
+ ; store initial SP in thread control block
+ RTS
+
+;}
+
+ END
diff --git a/ports/rxv1/iar/src/tx_thread_system_return.s b/ports/rxv1/iar/src/tx_thread_system_return.s
new file mode 100644
index 00000000..de17e189
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_thread_system_return.s
@@ -0,0 +1,74 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_system_return RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is target processor specific. It is used to transfer */
+;/* control from a thread back to the system. Only a minimal context */
+;/* is saved since the compiler assumes temp registers are going to get */
+;/* slicked by a function call anyway. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling loop */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ThreadX components */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+
+ public __tx_thread_system_return
+
+__tx_thread_system_return:
+
+ BRA __tx_thread_system_return
+
+ RTS
+
+ END
diff --git a/ports/rxv1/iar/src/tx_timer_interrupt.s b/ports/rxv1/iar/src/tx_timer_interrupt.s
new file mode 100644
index 00000000..35591477
--- /dev/null
+++ b/ports/rxv1/iar/src/tx_timer_interrupt.s
@@ -0,0 +1,235 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ extern __tx_timer_expiration_process
+ extern __tx_timer_system_clock
+ extern __tx_timer_expired_time_slice
+ extern __tx_timer_current_ptr
+ extern __tx_timer_expired
+ extern __tx_timer_list_start
+ extern __tx_timer_time_slice
+ extern __tx_timer_list_end
+ extern __tx_thread_time_slice
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_timer_interrupt RXv1/IAR */
+;/* 6.1.8 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function processes the hardware timer interrupt. This */
+;/* processing includes incrementing the system clock and checking for */
+;/* time slice and/or timer expiration. If either is found, the */
+;/* interrupt context save/restore functions are called along with the */
+;/* expiration functions. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_context_save Save interrupted context */
+;/* _tx_timer_expiration_process Timer expiration processing */
+;/* _tx_thread_time_slice Time slice interrupted thread */
+;/* _tx_thread_context_restore Restore interrupted context */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* interrupt vector */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */
+;/* */
+;/**************************************************************************/
+
+ public __tx_timer_interrupt
+__tx_timer_interrupt:
+;
+; /* Upon entry to this routine, it is assumed that all interrupts are locked
+; out and the stack looks like the following:
+; SP+4 -> Interrupted PC
+; SP+8-> Interrupted SR
+; */
+;
+; /* Increment the system clock. */
+; _tx_timer_system_clock++;
+;
+ PUSHM R14-R15
+ PUSHM R1-R5
+
+ MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock
+ MOV.L [R1], R2 ; Pickup system clock
+ ADD #1, R2 ; Increment system clock
+ MOV.L R2,[R1] ; Store new system clock
+;
+; /* Test for time-slice expiration. */
+; if (_tx_timer_time_slice)
+; {
+;
+ MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice
+ MOV.L [R1], R2 ; Pickup the current time slice
+ CMP #0, R2 ; Is a time slice active?
+ BEQ __tx_timer_no_time_slice ; No, skip timer slice processing
+;
+; /* Decrement the time_slice. */
+; _tx_timer_time_slice--;
+;
+ SUB #1, R2 ; Decrement the time-slice
+ MOV.L R2, [R1] ; Store time-slice
+;
+; /* Check for expiration. */
+; if (__tx_timer_time_slice == 0)
+;
+ CMP #0, R2 ; Has it expired?
+ BNE __tx_timer_no_time_slice ; No, time-slice has not expired
+;
+; /* Set the time-slice expired flag. */
+; _tx_timer_expired_time_slice = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice
+ MOV.L #1, R2 ; Build expired value
+ MOV.L R2, [R1] ; Set expired time slice variable
+; }
+;
+__tx_timer_no_time_slice:
+;
+; /* Test for timer expiration. */
+; if (*_tx_timer_current_ptr)
+; {
+;
+ MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr
+ MOV.L [R1], R2 ; Pickup current pointer
+ MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++
+ CMP #0, R1 ; Is timer pointer NULL?
+ BEQ __tx_timer_no_timer ; Yes, no timer has expired
+
+;
+; /* Set expiration flag. */
+; _tx_timer_expired = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired,R2 ; Build address of expired flag
+ MOV.L #1, R1 ; Build expired value
+ MOV.L R1, [R2]
+ BRA __tx_timer_done ; Finished with timer processing
+;
+; }
+; else
+; {
+__tx_timer_no_timer:
+;
+; /* No timer expired, increment the timer pointer. */
+; _tx_timer_current_ptr++;
+;
+; /* R2 already contains __tx_timer_current_ptr++ */
+;
+; /* Check for wrap-around. */
+; if (_tx_timer_current_ptr == _tx_timer_list_end)
+;
+ MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr
+ MOV.L [R1], R1 ; Pickup actual timer list end
+ CMP R1, R2 ; Are we at list end?
+ BNE __tx_timer_skip_wrap ; No, don't move pointer to the
+ ; top of the list
+;
+; /* Wrap to beginning of list. */
+; _tx_timer_current_ptr = _tx_timer_list_start;
+;
+ MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr
+ MOV.L [R2], R2 ; Pickup the start of the list
+; }
+;
+__tx_timer_skip_wrap:
+ MOV.L #__tx_timer_current_ptr,R1
+ MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr
+
+__tx_timer_done:
+;
+; /* See if anything has expired. */
+; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr
+ MOV.L [R1], R1 ; Pickup expired time slice
+ MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address
+ MOV.L [R2], R2 ; Pickup actual flag
+ OR R1, R2 ; Or flags together
+ BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired
+
+__tx_something_expired:
+; /* Did a timer expire? */
+; if (_tx_timer_expired)
+; {
+ MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address
+ MOV.L [R1], R1 ; Pickup expired flag
+ CMP #0,R1 ; Is the expired timer flag set?
+ BEQ __tx_timer_dont_activate ; No, skip timer activation
+;
+; /* Process timer expiration. */
+; _tx_timer_expiration_process();
+;
+ BSR __tx_timer_expiration_process ; Call the timer expiration handling routine
+;
+; }
+__tx_timer_dont_activate:
+;
+; /* Did time slice expire? */
+; if (_tx_timer_expired_time_slice)
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr
+ MOV.L [R1], R1 ; Pickup actual flag
+ CMP #0,R1 ; Has time-slice expired?
+ BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration
+;
+; /* Time slice interrupted thread. */
+; _tx_thread_time_slice();
+
+ BSR __tx_thread_time_slice ; Call time-slice processing
+; }
+;
+__tx_timer_not_ts_expiration:
+
+__tx_timer_nothing_expired:
+
+ POPM R1-R5
+ POPM R14-R15
+;
+ RTS ; return to point of interrupt
+;
+;}
+ END \ No newline at end of file