Release 6.1.9

This commit is contained in:
Yuxin Zhou
2021-10-14 00:51:26 +00:00
parent 215df45d4b
commit 1af8404c54
1812 changed files with 60698 additions and 249862 deletions

View File

@@ -0,0 +1,189 @@
/* Adapted for use with IAR Embedded Workbench */
/***********************************************************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
* applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
*
* Copyright (C) 2012 Renesas Electronics Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : hwsetup.c
* Version : 1.0
* Device(s) : RX
* H/W Platform : RX65N
* Description : Defines the initialisation routines used each time the MCU is restarted.
***********************************************************************************************************************/
/***********************************************************************************************************************
Includes <System Includes> , "Project Includes"
***********************************************************************************************************************/
#include <stdint.h>
#include <intrinsics.h>
/* Contains delcarations for the functions defined in this file */
#include "hwsetup.h"
/***********************************************************************************************************************
Private global variables and functions
***********************************************************************************************************************/
/* Clock configuration function delcaration */
void operating_frequency_set(void);
/* MCU I/O port configuration function delcaration */
//static void output_ports_configure(void);
/* Interrupt configuration function delcaration */
static void interrupts_configure(void);
/* MCU peripheral module configuration function declaration */
//static void peripheral_modules_enable(void);
/*******************************************************************************
* Function name: hardware_setup
* Description : Contains setup functions called at device restart
* Arguments : none
* Return value : none
*******************************************************************************/
void hardware_setup(void)
{
operating_frequency_set();
interrupts_configure();
}
/*******************************************************************************
* Function name: operating_frequency_set
* Description : Configures the clock settings for each of the device clocks
* Arguments : none
* Return value : none
*******************************************************************************/
void operating_frequency_set(void)
{
/*
Clock Description Frequency
----------------------------------------
Input Clock Frequency............ 24 MHz
Divisor.......................... 2
PLL frequency (x16).............. 192 MHz
Internal Clock Frequency......... 96 MHz
Peripheral Clock Frequency....... 48 MHz
USB Clock Frequency.............. 48 MHz
External Bus Clock Frequency..... 24 MHz */
volatile unsigned int i;
/* Protect off. */
SYSTEM.PRCR.WORD = 0xA50B;
/* Uncomment if not using sub-clock */
//SYSTEM.SOSCCR.BYTE = 0x01; /* stop sub-clock */
SYSTEM.SOSCCR.BYTE = 0x00; /* Enable sub-clock for RTC */
/* Wait 131,072 cycles * 12 MHz = 10.9 ms */
SYSTEM.MOSCWTCR.BYTE = 0x0D;
/* x16 @PLL, 2 divisor */
SYSTEM.PLLCR.WORD = 0x0F01;
/* EXTAL ON */
SYSTEM.MOSCCR.BYTE = 0x00;
/* PLL ON */
SYSTEM.PLLCR2.BYTE = 0x00;
for(i = 0;i< 0x168;i++)
{
/* Wait over 12ms */
__no_operation();
}
/* Setup system clocks
SCKCR - System Clock Control Register
b31:b28 FCK[3:0] 0x02 = Flash clock: PLL/4 = (192 / 4) = 48 MHz
b27:b24 ICK[3:0] 0x01 = System clock: PLL/2 = (192 / 2) = 96 MHz
b23 PSTOP1 0x00 = BCLK pin output is enabled
b19:b16 BCK[3:0] 0x03 = BCLK: PLL/8 = 24 MHz
b11:b8 PCKB[3:0] 0x02 = Peripheral clock B: PLL/4 = 48 MHz
*/
SYSTEM.SCKCR.LONG = 0x21031222; /* ICK=PLL/2,BCK,FCK,PCK=PLL/4 */
/* Setup IEBUS and USB clocks
SCKCR2 - System Clock Control Register 2
b7:b4 UCK[3:0] 0x03 = USB clock is PLL/4 = 48 MHz
b3:b0 IEBCK[3:0] 0x01 = IE Bus clock is PLL/2 = 96 MHz
*/
SYSTEM.SCKCR2.WORD = 0x0031;
/* ICLK, PCLKB, FCLK, BCLK, IECLK, and USBCLK all come from PLL circuit */
SYSTEM.SCKCR3.WORD = 0x0400;
/* Protect on. */
SYSTEM.PRCR.WORD = 0xA500;
}
/***********************************************************************************************************************
* Function name: interrupts_configure
* Description : Configures interrupts used
* Arguments : none
* Return value : none
***********************************************************************************************************************/
void interrupts_configure(void)
{
/* Protect off. */
SYSTEM.PRCR.WORD = 0xA50B;
/* Enable the bus error interrupt to catch accesses to illegal/reserved areas
of memory. */
/* Clear any pending interrupts */
IR(BSC,BUSERR) = 0;
/* Make this the highest priority interrupt (adjust as necessary for your
application) */
IPR(BSC,BUSERR) = 0x0F;
/* Enable the interrupt in the ICU */
IEN(BSC,BUSERR) = 1;
/* Enable illegal address interrupt in the BSC */
BSC.BEREN.BIT.IGAEN = 1;
}
/******************************************************************************
* Function name: buserr_isr
* Description : Sample ISR for bus error (must do hardware setup first!)
* By default, this demo code enables the Bus Error Interrupt.
* This interrupt will fire if the user tries to access code
* or data from one of the reserved areas in the memory map,
* including the areas covered by disabled chip selects.
* A nop statement is included here as a convenient place
* to set a breakpoint during debugging and development, and
* further handling should be added by the user for their
* application.
* Arguments : none
* Return value : none
******************************************************************************/
#pragma vector = VECT_BSC_BUSERR
__interrupt void buserr_isr(void)
{
/* To find the address that was accessed when the bus error occured, read
the register BSC.BERSR2.WORD. The upper 13 bits of this register
contain the upper 13-bits of the offending address (in 512K byte units).
*/
/* Add your own code here to handle this interrupt */
__no_operation();
}

View File

@@ -0,0 +1,49 @@
/* Adapted for use with IAR Embedded Workbench */
/***********************************************************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
* applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
*
* Copyright (C) 2012 Renesas Electronics Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : hwsetup.h
* Version : 1.0
* Description : Hardware setup header file..
***********************************************************************************************************************/
/***********************************************************************************************************************
* History : DD.MM.YYYY Version Description
* : 26.10.2011 1.00 First Release
***********************************************************************************************************************/
/***********************************************************************************************************************
Macro definitions
***********************************************************************************************************************/
/* Multiple inclusion prevention macro */
#ifndef HWSETUP_H
#define HWSETUP_H
/***********************************************************************************************************************
Includes <System Includes> , "Project Includes"
***********************************************************************************************************************/
#include <iorx65n.h>
/***********************************************************************************************************************
Exported global functions (to be accessed by other files)
***********************************************************************************************************************/
/* Hardware setup funtion declaration */
void hardware_setup(void);
/* End of multiple inclusion prevention macro */
#endif

View File

@@ -0,0 +1,43 @@
/*
* lowinit.c
*
* This module contains the function '__low_level_init', a function
* that is called before the 'main' function of the program. Normally
* low-level initializations - such as setting the prefered interrupt
* level or setting the watchdog - can be performed here.
*
* Note that this function is called before the data segments are
* initialized, this means that this function can't rely on the
* values of global or static variables.
*
* When this function returns zero, the startup code will inhibit the
* initialization of the data segments. The result is faster startup,
* the drawback is that neither global nor static data will be
* initialized.
*
*
* Copyright 2009-2010 IAR Systems AB.
*
* $Revision: 2717 $
*/
#pragma language=extended
#include <iorx65n.h>
#include <intrinsics.h>
#include "hwsetup.h"
__intrinsic
int __low_level_init ( void )
{
hardware_setup();
/*==================================*/
/* Choose if segment initialization */
/* should be done or not. */
/* Return: 0 to omit seg_init */
/* 1 to run seg_init */
/*==================================*/
return (1);
}
#pragma language=default

View File

@@ -0,0 +1,57 @@
//-----------------------------------------------------------------------------
// ILINK command file template for the Renesas RX microcontroller R5F565N9
//-----------------------------------------------------------------------------
define exported symbol __link_file_version_4 = 1;
define memory mem with size = 4G;
// ID Code Protection
define exported symbol __ID_BYTES_1_4 = 0xFFFFFFFF;
define exported symbol __ID_BYTES_5_8 = 0xFFFFFFFF;
define exported symbol __ID_BYTES_9_12 = 0xFFFFFFFF;
define exported symbol __ID_BYTES_13_16 = 0xFFFFFFFF;
// Endian Select Register (MDE)
// Choose between Little endian=0xFFFFFFFF or Big endian=0xFFFFFFF8
define exported symbol __MDES = 0xFFFFFFFF;
// Option Function Select Register 0 (OFS0)
define exported symbol __OFS0 = 0xFFFFFFFF;
// Option Function Select Register 1 (OFS1)
define exported symbol __OFS1 = 0xFFFFFFFF;
define region ROM_region16 = mem:[from 0xFFFF8000 to 0xFFF10000];
define region RAM_region16 = mem:[from 0x00000004 to 0x0003FFFF];
define region ROM_region24 = mem:[from 0xFFF00000 to 0xFFF10000];
define region RAM_region24 = mem:[from 0x00000004 to 0x0003FFFF];
define region ROM_region32 = mem:[from 0xFFF00000 to 0xFFF10000];
define region RAM_region32 = mem:[from 0x00000004 to 0x0003FFFF];
initialize by copy { rw, ro section D, ro section D_1, ro section D_2 };
do not initialize { section .*.noinit };
define block HEAP with alignment = 4, size = _HEAP_SIZE { };
define block USTACK with alignment = 4, size = _USTACK_SIZE { };
define block ISTACK with alignment = 4, size = _ISTACK_SIZE { };
define block STACKS with fixed order { block ISTACK,
block USTACK };
place at address mem:0xFE7F5D00 { ro section .option_mem };
place at address mem:0xFFFFFF80 { ro section .exceptvect };
place at address mem:0xFFFFFFFC { ro section .resetvect };
"ROM16":place in ROM_region16 { ro section .code16*,
ro section .data16* };
"RAM16":place in RAM_region16 { rw section .data16*,
rw section __DLIB_PERTHREAD };
"ROM24":place in ROM_region24 { ro section .code24*,
ro section .data24* };
"RAM24":place in RAM_region24 { rw section .data24* };
"ROM32":place in ROM_region32 { ro };
"RAM32":place in RAM_region32 { rw,
ro section D,
ro section D_1,
ro section D_2,
block HEAP,
block STACKS,
last section FREEMEM };

View File

@@ -0,0 +1,78 @@
//-----------------------------------------------------------------------------
// ILINK command file template for the Renesas RX microcontroller R5F565N
//-----------------------------------------------------------------------------
define exported symbol __link_file_version_4 = 1;
define memory mem with size = 4G;
// ID Code Protection
define exported symbol __ID_BYTES_1_4 = 0xFFFFFFFF;
define exported symbol __ID_BYTES_5_8 = 0xFFFFFFFF;
define exported symbol __ID_BYTES_9_12 = 0xFFFFFFFF;
define exported symbol __ID_BYTES_13_16 = 0xFFFFFFFF;
// Endian Select Register (MDE)
// Choose between Little endian=0xFFFFFFFF or Big endian=0xFFFFFFF8
define exported symbol __MDES = 0xFFFFFFFF;
// Option Function Select Register 0 (OFS0)
define exported symbol __OFS0 = 0xFFFFFFFF;
// Option Function Select Register 1 (OFS1)
define exported symbol __OFS1 = 0xFFFFFFFF;
//define region ROM_region16 = mem:[from 0xFFFF8000 to 0xFFFFFFFF];
define region RAM_region16 = mem:[from 0x00010000 to 0x00017FFF];
//define region ROM_region24 = mem:[from 0xFFF00000 to 0xFFFFFFFF];
//define region RAM_region24 = mem:[from 0x00000004 to 0x0001FFFF];
define region ROM_region32 = mem:[from 0xFFF10400 to 0xFFFFFFFF];
//define region RAM_region32 = mem:[from 0x00000004 to 0x0001FFFF];
//define region DATA_FLASH_region = mem:[from 0x00100000 to 0x00107FFF];
initialize by copy { rw, ro section D, ro section D_1, ro section D_2 };
do not initialize { section .*.noinit };
define block HEAP with alignment = 4, size = _HEAP_SIZE { };
//define block USTACK with alignment = 4, size = _USTACK_SIZE { };
//define block ISTACK with alignment = 4, size = _ISTACK_SIZE { };
//define block STACKS with fixed order { block ISTACK,
// block USTACK };
//place at address mem:0xFFFFFF80 { ro section .nmivec };
//"ROM16":place in ROM_region16 { ro section .code16*,
// ro section .data16* };
//"RAM16":place in RAM_region16 { rw section .data16*,
// rw section __DLIB_PERTHREAD };
//"ROM24":place in ROM_region24 { ro section .code24*,
// ro section .data24* };
//"RAM24":place in RAM_region24 { rw section .data24* };
//"ROM32":place in ROM_region32 { ro };
//"RAM32":place in RAM_region32 { rw,
// ro section D,
// ro section D_1,
// ro section D_2,
// block HEAP,
// block STACKS,
// last section FREEMEM };
//"DATAFLASH":place in DATA_FLASH_region
// { ro section .dataflash* };
define movable block ROPI with alignment = 4, fixed order, static base CB
{
ro object txm_module_preamble_rx65n.o,
ro,
ro data
};
define movable block RWPI with alignment = 8, fixed order, static base SB
{
rw section .sbdata*,
rw section .sbrel*,
rw section __DLIB_PERTHREAD,
block HEAP
};
place in ROM_region32 { block ROPI };
place in RAM_region16 { block RWPI };

View File

@@ -0,0 +1,425 @@
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
event flags group, byte pool, and block pool. */
/* Specify that this is a module! */
#define TXM_MODULE
/* Include the ThreadX module definitions. */
#include "txm_module.h"
/* Define constants. */
#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
/* Define the pool space in the bss section of the module. ULONG is used to
get the word alignment. */
ULONG demo_module_pool_space[DEMO_BYTE_POOL_SIZE / 4];
/* Define the ThreadX object control blocks... */
TX_THREAD *thread_0;
TX_THREAD *thread_1;
TX_THREAD *thread_2;
TX_THREAD *thread_3;
TX_THREAD *thread_4;
TX_THREAD *thread_5;
TX_THREAD *thread_6;
TX_THREAD *thread_7;
TX_QUEUE *queue_0;
TX_SEMAPHORE *semaphore_0;
TX_MUTEX *mutex_0;
TX_EVENT_FLAGS_GROUP *event_flags_0;
TX_BYTE_POOL *byte_pool_0;
TX_BLOCK_POOL *block_pool_0;
/* Define the counters used in the demo application... */
ULONG thread_0_counter;
ULONG thread_1_counter;
ULONG thread_1_messages_sent;
ULONG thread_2_counter;
ULONG thread_2_messages_received;
ULONG thread_3_counter;
ULONG thread_4_counter;
ULONG thread_5_counter;
ULONG thread_6_counter;
ULONG thread_7_counter;
ULONG semaphore_0_puts;
ULONG event_0_sets;
ULONG queue_0_sends;
/* Define thread prototypes. */
void thread_0_entry(ULONG thread_input);
void thread_1_entry(ULONG thread_input);
void thread_2_entry(ULONG thread_input);
void thread_3_and_4_entry(ULONG thread_input);
void thread_5_entry(ULONG thread_input);
void thread_6_and_7_entry(ULONG thread_input);
void semaphore_0_notify(TX_SEMAPHORE *semaphore_ptr)
{
if (semaphore_ptr == semaphore_0)
semaphore_0_puts++;
}
void event_0_notify(TX_EVENT_FLAGS_GROUP *event_flag_group_ptr)
{
if (event_flag_group_ptr == event_flags_0)
event_0_sets++;
}
void queue_0_notify(TX_QUEUE *queue_ptr)
{
if (queue_ptr == queue_0)
queue_0_sends++;
}
/* Define the module start function. */
void demo_module_start(ULONG id)
{
CHAR *pointer;
/* Allocate all the objects. In MPU mode, modules cannot allocate control blocks within
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
the control block(s). */
txm_module_object_allocate((void*)&thread_0, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_1, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_2, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_3, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_4, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_5, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_6, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_7, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&queue_0, sizeof(TX_QUEUE));
txm_module_object_allocate((void*)&semaphore_0, sizeof(TX_SEMAPHORE));
txm_module_object_allocate((void*)&mutex_0, sizeof(TX_MUTEX));
txm_module_object_allocate((void*)&event_flags_0, sizeof(TX_EVENT_FLAGS_GROUP));
txm_module_object_allocate((void*)&byte_pool_0, sizeof(TX_BYTE_POOL));
txm_module_object_allocate((void*)&block_pool_0, sizeof(TX_BLOCK_POOL));
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(byte_pool_0, "module byte pool 0", demo_module_pool_space, DEMO_BYTE_POOL_SIZE);
/* Put system definition stuff in here, e.g. thread creates and other assorted
create information. */
/* Allocate the stack for thread 0. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create the main thread. */
tx_thread_create(thread_0, "module thread 0", thread_0_entry, 0,
pointer, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 1. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 1 and 2. These threads pass information through a ThreadX
message queue. It is also interesting to note that these threads have a time
slice. */
tx_thread_create(thread_1, "module thread 1", thread_1_entry, 1,
pointer, DEMO_STACK_SIZE,
16, 16, 4, TX_AUTO_START);
/* Allocate the stack for thread 2. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(thread_2, "module thread 2", thread_2_entry, 2,
pointer, DEMO_STACK_SIZE,
16, 16, 4, TX_AUTO_START);
/* Allocate the stack for thread 3. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
An interesting thing here is that both threads share the same instruction area. */
tx_thread_create(thread_3, "module thread 3", thread_3_and_4_entry, 3,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 4. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(thread_4, "module thread 4", thread_3_and_4_entry, 4,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 5. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create thread 5. This thread simply pends on an event flag which will be set
by thread_0. */
tx_thread_create(thread_5, "module thread 5", thread_5_entry, 5,
pointer, DEMO_STACK_SIZE,
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 6. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
tx_thread_create(thread_6, "module thread 6", thread_6_and_7_entry, 6,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 7. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(thread_7, "module thread 7", thread_6_and_7_entry, 7,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the message queue. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
/* Create the message queue shared by threads 1 and 2. */
tx_queue_create(queue_0, "module queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
tx_queue_send_notify(queue_0, queue_0_notify);
/* Create the semaphore used by threads 3 and 4. */
tx_semaphore_create(semaphore_0, "module semaphore 0", 1);
tx_semaphore_put_notify(semaphore_0, semaphore_0_notify);
/* Create the event flags group used by threads 1 and 5. */
tx_event_flags_create(event_flags_0, "module event flags 0");
tx_event_flags_set_notify(event_flags_0, event_0_notify);
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
tx_mutex_create(mutex_0, "module mutex 0", TX_NO_INHERIT);
/* Allocate the memory for a small block pool. */
tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
/* Create a block memory pool to allocate a message buffer from. */
tx_block_pool_create(block_pool_0, "module block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
/* Allocate a block and release the block memory. */
tx_block_allocate(block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
/* Release the block back to the pool. */
tx_block_release(pointer);
}
/* Define the test threads. */
void thread_0_entry(ULONG thread_input)
{
UINT status;
/* This thread simply sits in while-forever-sleep loop. */
while(1)
{
/* Increment the thread counter. */
thread_0_counter++;
/* Sleep for 10 ticks. */
tx_thread_sleep(10);
/* Set event flag 0 to wakeup thread 5. */
status = tx_event_flags_set(event_flags_0, 0x1, TX_OR);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}
void thread_1_entry(ULONG thread_input)
{
UINT status;
/* This thread simply sends messages to a queue shared by thread 2. */
while(1)
{
/* Increment the thread counter. */
thread_1_counter++;
/* Send message to queue 0. */
status = tx_queue_send(queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
/* Check completion status. */
if (status != TX_SUCCESS)
break;
/* Increment the message sent. */
thread_1_messages_sent++;
}
}
void thread_2_entry(ULONG thread_input)
{
ULONG received_message;
UINT status;
/* This thread retrieves messages placed on the queue by thread 1. */
while(1)
{
/* Write value to shared memory region. */
// *(ULONG *)0x00020000 = 0xCDCDCDCD;
/* Increment the thread counter. */
thread_2_counter++;
/* Retrieve a message from the queue. */
status = tx_queue_receive(queue_0, &received_message, TX_WAIT_FOREVER);
/* Check completion status and make sure the message is what we
expected. */
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
break;
/* Otherwise, all is okay. Increment the received message count. */
thread_2_messages_received++;
}
}
void thread_3_and_4_entry(ULONG thread_input)
{
UINT status;
/* This function is executed from thread 3 and thread 4. As the loop
below shows, these function compete for ownership of semaphore_0. */
while(1)
{
/* Increment the thread counter. */
if (thread_input == 3)
thread_3_counter++;
else
thread_4_counter++;
/* Get the semaphore with suspension. */
status = tx_semaphore_get(semaphore_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Sleep for 2 ticks to hold the semaphore. */
tx_thread_sleep(2);
/* Release the semaphore. */
status = tx_semaphore_put(semaphore_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}
void thread_5_entry(ULONG thread_input)
{
UINT status;
ULONG actual_flags;
/* This thread simply waits for an event in a forever loop. */
while(1)
{
/* Increment the thread counter. */
thread_5_counter++;
/* Wait for event flag 0. */
status = tx_event_flags_get(event_flags_0, 0x1, TX_OR_CLEAR,
&actual_flags, TX_WAIT_FOREVER);
/* Check status. */
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
break;
}
}
void thread_6_and_7_entry(ULONG thread_input)
{
UINT status;
/* This function is executed from thread 6 and thread 7. As the loop
below shows, these function compete for ownership of mutex_0. */
while(1)
{
/* Increment the thread counter. */
if (thread_input == 6)
thread_6_counter++;
else
thread_7_counter++;
/* Get the mutex with suspension. */
status = tx_mutex_get(mutex_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Get the mutex again with suspension. This shows
that an owning thread may retrieve the mutex it
owns multiple times. */
status = tx_mutex_get(mutex_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Sleep for 2 ticks to hold the mutex. */
tx_thread_sleep(2);
/* Release the mutex. */
status = tx_mutex_put(mutex_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Release the mutex again. This will actually
release ownership since it was obtained twice. */
status = tx_mutex_put(mutex_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}

View File

@@ -0,0 +1,113 @@
/* Small demonstration of the ThreadX module manager. */
#include "tx_api.h"
#include "txm_module.h"
#define DEMO_STACK_SIZE 1024
/* Define the ThreadX object control blocks... */
TX_THREAD module_manager;
TXM_MODULE_INSTANCE my_module;
/* Define the object pool area. */
UCHAR object_memory[8192];
/* Define the count of memory faults. */
ULONG memory_faults;
/* Define thread prototypes. */
void module_manager_entry(ULONG thread_input);
/* Define fault handler. */
VOID module_fault_handler(TX_THREAD *thread, TXM_MODULE_INSTANCE *module)
{
/* Just increment the fault counter. */
memory_faults++;
}
/* Define main entry point. */
int main()
{
/* Enter the ThreadX kernel. */
tx_kernel_enter();
}
/* Define what the initial system looks like. */
void tx_application_define(void *first_unused_memory)
{
CHAR *pointer = (CHAR*)first_unused_memory;
tx_thread_create(&module_manager, "Module Manager Thread", module_manager_entry, 0,
pointer, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
pointer = pointer + DEMO_STACK_SIZE;
}
/* Define the test threads. */
void module_manager_entry(ULONG thread_input)
{
/* Initialize the module manager. */
txm_module_manager_initialize((VOID *) 0x00018000, 0x00008000);
txm_module_manager_object_pool_create(object_memory, sizeof(object_memory));
/* Register a fault handler. */
txm_module_manager_memory_fault_notify(module_fault_handler);
/* Load the module that is already there, in this example it is placed there by the multiple image download. */
txm_module_manager_in_place_load(&my_module, "my module", (VOID *) 0xFFF10400);
/* Enable 128 byte read/write shared memory region at 0x00020000. */
txm_module_manager_external_memory_enable(&my_module, (void *) 0x00020000, 128, TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_READ | TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE);
/* Start the module. */
txm_module_manager_start(&my_module);
/* Sleep for a while.... */
tx_thread_sleep(1000);
/* Stop the module. */
txm_module_manager_stop(&my_module);
/* Unload the module. */
txm_module_manager_unload(&my_module);
/* Load the module that is already there. */
txm_module_manager_in_place_load(&my_module, "my module", (VOID *) 0xFFF10400);
/* Set maximum module priority to 5. */
txm_module_manager_maximum_module_priority_set(&my_module, 5);
/* Start the module again. */
txm_module_manager_start(&my_module);
/* Now just spin... */
while(1)
{
tx_thread_sleep(100);
}
}

View File

@@ -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 RXv2/IAR */
;/* 6.x */
;/* 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 */
;/* */
;/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
;/* */
;/**************************************************************************/
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

View File

@@ -0,0 +1,69 @@
/* Alignment of 4 (16-byte) */
SECTION .text:CODE (4)
/* Define public symbols. */
PUBLIC __txm_module_preamble
/* Define application-specific start/stop entry points for the module. */
EXTERN _demo_module_start
/* Define common external refrences. */
EXTERN __txm_module_thread_shell_entry
EXTERN __txm_module_callback_request_thread_entry
EXTERN ROPI$$Length
EXTERN RWPI$$Length
DATA
__txm_module_preamble:
DC32 0x4D4F4455 // Module ID
DC32 0x5 // Module Major Version
DC32 0x6 // Module Minor Version
DC32 32 // Module Preamble Size in 32-bit words
DC32 0x12345678 // Module ID (application defined)
DC32 0x00000007 // Module Properties where:
// Bits 31-24: Compiler ID
// 0 -> IAR
// 1 -> RVDS
// 2 -> GNU
// Bit 0: 0 -> Privileged mode execution
// 1 -> User mode execution
// Bit 1: 0 -> No MPU protection
// 1 -> MPU protection (must have user mode selected)
// Bit 2: 0 -> Disable shared/external memory access
// 1 -> Enable shared/external memory access
DC32 __txm_module_thread_shell_entry - $ // Module Shell Entry Point
DC32 _demo_module_start - $ // Module Start Thread Entry Point
DC32 0 // Module Stop Thread Entry Point
DC32 1 // Module Start/Stop Thread Priority
DC32 1024 // Module Start/Stop Thread Stack Size
DC32 __txm_module_callback_request_thread_entry - $ // Module Callback Thread Entry
DC32 1 // Module Callback Thread Priority
DC32 1024 // Module Callback Thread Stack Size
DC32 ROPI$$Length // Module Code Size
DC32 RWPI$$Length // Module Data Size
DC32 0 // Reserved 0
DC32 0 // Reserved 1
DC32 0 // Reserved 2
DC32 0 // Reserved 3
DC32 0 // Reserved 4
DC32 0 // Reserved 5
DC32 0 // Reserved 6
DC32 0 // Reserved 7
DC32 0 // Reserved 8
DC32 0 // Reserved 9
DC32 0 // Reserved 10
DC32 0 // Reserved 11
DC32 0 // Reserved 12
DC32 0 // Reserved 13
DC32 0 // Reserved 14
DC32 0 // Reserved 15
END

View File

@@ -0,0 +1,292 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the 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 RXv2/IAR */
/* 6.x */
/* */
/* 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 */
/* */
/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
/* */
/**************************************************************************/
#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 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved; \
VOID *tx_thread_iar_tls_pointer;
#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_MUTEX_EXTENSION
#define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
/* 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 RXv2/IAR Version 6.x *";
#else
extern CHAR _tx_version_id[];
#endif
#endif

View File

@@ -0,0 +1,401 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h RXv2/IAR */
/* 6.x */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the basic module constants, interface structures, */
/* and function prototypes. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-xxxx Scott Larson Initial Version 6.x */
/* */
/**************************************************************************/
#ifndef TXM_MODULE_PORT_H
#define TXM_MODULE_PORT_H
/* Determine if the optional Modules user define file should be used. */
#ifdef TXM_MODULE_INCLUDE_USER_DEFINE_FILE
/* Yes, include the user defines in txm_module_user.h. The defines in this file may
alternately be defined on the command line. */
#include "txm_module_user.h"
#endif
/* It is assumed that the base ThreadX tx_port.h file has been modified to add the
following extensions to the ThreadX thread control block (this code should replace
the corresponding macro define in tx_port.h):
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved; \
VOID *tx_thread_iar_tls_pointer;
The following extensions must also be defined in tx_port.h:
#define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
*/
#define TXM_MODULE_THREAD_ENTRY_INFO_USER_EXTENSION
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
#define TXM_MODULE_RVDS_COMPILER 0x01000000
#define TXM_MODULE_GNU_COMPILER 0x02000000
#define TXM_MODULE_COMPILER_MASK 0xFF000000
#define TXM_MODULE_OPTIONS_MASK 0x000000FF
/* Define the properties for this particular module port. */
#define TXM_MODULE_MEMORY_PROTECTION_ENABLED
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
#define TXM_MODULE_REQUIRE_ALLOCATED_OBJECT_MEMORY
#else
#define TXM_MODULE_REQUIRE_LOCAL_OBJECT_MEMORY
#endif
#define TXM_MODULE_USER_MODE 0x00000001
#define TXM_MODULE_MEMORY_PROTECTION 0x00000002
#define TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS 0x00000004
/* Define the kernel stack size for a module thread. */
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
#define TXM_MODULE_KERNEL_STACK_SIZE 512
#endif
/* Define the supported options for this module. */
#define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_USER_MODE | TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)
#define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0
/* Define offset adjustments according to the compiler used to build the module. */
#define TXM_MODULE_IAR_SHELL_ADJUST 24
#define TXM_MODULE_IAR_START_ADJUST 28
#define TXM_MODULE_IAR_STOP_ADJUST 32
#define TXM_MODULE_IAR_CALLBACK_ADJUST 44
#define TXM_MODULE_RVDS_SHELL_ADJUST 0
#define TXM_MODULE_RVDS_START_ADJUST 0
#define TXM_MODULE_RVDS_STOP_ADJUST 0
#define TXM_MODULE_RVDS_CALLBACK_ADJUST 0
#define TXM_MODULE_GNU_SHELL_ADJUST 24
#define TXM_MODULE_GNU_START_ADJUST 28
#define TXM_MODULE_GNU_STOP_ADJUST 32
#define TXM_MODULE_GNU_CALLBACK_ADJUST 44
/* Define other module port-specific constants. */
/* Define INLINE_DECLARE to inline for IAR compiler. */
#define INLINE_DECLARE inline
/* Define the data area alignment mask, must be a power of 2. */
#ifndef TXM_MODULE_DATA_ALIGNMENT
#define TXM_MODULE_DATA_ALIGNMENT 16
#endif
/* Define the code area alignment mask, must be a power of 2. */
#ifndef TXM_MODULE_CODE_ALIGNMENT
#define TXM_MODULE_CODE_ALIGNMENT 16
#endif
/* Define the number of MPU entries assigned to the code and data sections. */
#define TXM_MODULE_MANAGER_CODE_MPU_ENTRIES 2
#define TXM_MODULE_MANAGER_DATA_MPU_ENTRIES 1
/* Total MPU entries available. */
#define TXM_MODULE_MANAGER_RX_MPU_ENTRIES 8
#define TXM_MODULE_MANAGER_REGISTERS_PER_MPU_ENTRY 2
#define TXM_MODULE_MANAGER_MPU_TABLE_SIZE (TXM_MODULE_MANAGER_RX_MPU_ENTRIES * TXM_MODULE_MANAGER_REGISTERS_PER_MPU_ENTRY)
/* Shared memory MPU index. */
#define TXM_MODULE_MANAGER_SHARED_MPU_INDEX 6
/* Addresses of MPU registers for trampoline protection. */
#define RSPAGE0 (*(ULONG *) 0x00086400)
#define REPAGE0 (*(ULONG *) 0x00086404)
/* Shared memory region attributes. */
#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_EXECUTE 1
#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 2
#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_READ 4
#define TXM_MODULE_MANAGER_ATTRIBUTE_EXECUTE_MPU_BIT (TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_EXECUTE << 1)
#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT (TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE << 1)
#define TXM_MODULE_MANAGER_ATTRIBUTE_READ_MPU_BIT (TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_READ << 1)
/* Define the port-extensions to the module manager instance structure. */
#define TXM_MODULE_MANAGER_PORT_EXTENSION \
ULONG txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_MPU_TABLE_SIZE]; \
ULONG txm_module_instance_shared_memory_address; \
ULONG txm_module_instance_shared_memory_length;
/* Define the memory fault information structure that is populated when a memory fault occurs. */
typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT
{
TX_THREAD *txm_module_manager_memory_fault_info_thread_ptr;
VOID *txm_module_manager_memory_fault_info_code_location;
ULONG txm_module_manager_memory_fault_info_mpests;
ULONG txm_module_manager_memory_fault_info_mpdea;
ULONG txm_module_manager_memory_fault_info_mhiti;
ULONG txm_module_manager_memory_fault_info_mhitd;
ULONG txm_module_manager_memory_fault_info_psw;
ULONG txm_module_manager_memory_fault_info_sp;
ULONG txm_module_manager_memory_fault_info_r1;
ULONG txm_module_manager_memory_fault_info_r2;
ULONG txm_module_manager_memory_fault_info_r3;
ULONG txm_module_manager_memory_fault_info_r4;
ULONG txm_module_manager_memory_fault_info_r5;
ULONG txm_module_manager_memory_fault_info_r6;
ULONG txm_module_manager_memory_fault_info_r7;
ULONG txm_module_manager_memory_fault_info_r8;
ULONG txm_module_manager_memory_fault_info_r9;
ULONG txm_module_manager_memory_fault_info_r10;
ULONG txm_module_manager_memory_fault_info_r11;
ULONG txm_module_manager_memory_fault_info_r12;
ULONG txm_module_manager_memory_fault_info_r13;
ULONG txm_module_manager_memory_fault_info_r14;
ULONG txm_module_manager_memory_fault_info_r15;
} TXM_MODULE_MANAGER_MEMORY_FAULT_INFO;
#define TXM_MODULE_MANAGER_FAULT_INFO \
TXM_MODULE_MANAGER_MEMORY_FAULT_INFO _txm_module_manager_memory_fault_info;
/* Define the macro to check the stack available in dispatch. */
//#define TXM_MODULE_MANAGER_CHECK_STACK_AVAILABLE \
// ULONG stack_available; \
// __asm("MOV SP, %0" : "=r"(stack_available)); \
// stack_available -= (ULONG)_tx_thread_current_ptr->tx_thread_stack_start; \
// if((stack_available < TXM_MODULE_MINIMUM_STACK_AVAILABLE) || \
// (stack_available > _tx_thread_current_ptr->tx_thread_stack_size)) \
// { \
// return(TX_SIZE_ERROR); \
// }
/* Define the macro to check the module version ID. */
#define TXM_MODULE_MANAGER_CHECK_PROPERTIES(properties) \
if ((properties & _txm_module_manager_properties_supported) != (properties & ~((ULONG) TXM_MODULE_COMPILER_MASK))) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_INVALID_PROPERTIES); \
} \
if ((_txm_module_manager_properties_required & properties) != _txm_module_manager_properties_required) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_INVALID_PROPERTIES); \
}
/* Define the macro to check the code alignment. */
#define TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment) \
{ \
ULONG temp; \
temp = (ULONG) module_location; \
temp = temp & (code_alignment - 1); \
if (temp) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_ALIGNMENT_ERROR); \
} \
}
/* Define the macro to adjust the alignment and size for code/data areas. */
#define TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size, data_alignment) _txm_module_manager_alignment_adjust(module_preamble, &code_size, &code_alignment, &data_size, &data_alignment);
/* Define the macro to adjust the symbols in the module preamble. */
#define TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(properties, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust) \
if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_IAR_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_IAR_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_IAR_START_ADJUST - (ULONG)(module_instance -> txm_module_instance_code_start); \
stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST - (ULONG)(module_instance -> txm_module_instance_code_start); \
callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST - (ULONG)(module_instance -> txm_module_instance_code_start); \
} \
else if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_RVDS_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_RVDS_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_RVDS_START_ADJUST; \
stop_function_adjust = TXM_MODULE_RVDS_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_RVDS_CALLBACK_ADJUST; \
} \
else \
{ \
shell_function_adjust = TXM_MODULE_GNU_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_GNU_START_ADJUST; \
stop_function_adjust = TXM_MODULE_GNU_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_GNU_CALLBACK_ADJUST; \
}
/* Define the macro to populate the thread control block with module port-specific information.
Check if the module is in user mode and set up txm_module_thread_entry_info_kernel_call_dispatcher accordingly.
*/
#define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \
thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \
thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \
if (thread_ptr -> tx_thread_module_user_mode) \
{ \
*(ULONG*)&(thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher) = \
(ULONG)_txm_module_manager_user_mode_entry - (ULONG)module_instance -> txm_module_instance_code_start; \
} \
else \
{ \
*(ULONG*)&(thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher) = \
(ULONG)_txm_module_manager_kernel_dispatch - (ULONG)module_instance -> txm_module_instance_code_start; \
}
/* Define the macro to populate the module control block with module port-specific information.
If memory protection is enabled, set up the MPU registers.
*/
#define TXM_MODULE_MANAGER_MODULE_SETUP(module_instance) \
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE) \
{ \
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION) \
{ \
_txm_module_manager_setup_mpu_registers(module_instance); \
} \
} \
else \
{ \
/* Do nothing. */ \
}
/* Define the macro to perform port-specific functions when unloading the module. */
/* Nothing needs to be done for this port. */
#define TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance)
/* Define the macro to perform port-specific functions when passing pointer to kernel. */
/* Determine if the pointer is within the module's data or shared memory. */
//#define TXM_MODULE_MANAGER_CHECK_DATA_POINTER(module_instance, pointer) \
// if ((pointer < (ULONG) module_instance -> txm_module_instance_data_start) || \
// ((pointer+sizeof(pointer)) > (ULONG) module_instance -> txm_module_instance_data_end)) \
// { \
// if((pointer < module_instance -> txm_module_instance_shared_memory_address) || \
// ((pointer+sizeof(pointer)) > module_instance -> txm_module_instance_shared_memory_address \
// + module_instance -> txm_module_instance_shared_memory_length)) \
// { \
// return(TXM_MODULE_INVALID_MEMORY); \
// } \
// }
/* Define the macro to perform port-specific functions when passing function pointer to kernel. */
/* Determine if the pointer is within the module's code memory. */
//#define TXM_MODULE_MANAGER_CHECK_FUNCTION_POINTER(module_instance, pointer) \
// if (((pointer < sizeof(TXM_MODULE_PREAMBLE)) || \
// ((pointer+sizeof(pointer)) > ((ULONG) module_instance -> txm_module_instance_code_end - \
// (ULONG) module_instance -> txm_module_instance_code_start))) \
// && (pointer != (ULONG) TX_NULL)) \
// { \
// return(TX_PTR_ERROR); \
// }
/* Define macro to make sure object is inside the module's data. */
#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
/* Check for overflow. */ \
(((obj_ptr) < ((obj_ptr) + (obj_size))) && \
/* Check if it's inside module data. */ \
((((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) && \
(((obj_ptr) + (obj_size)) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1))) || \
/* Check if it's inside shared memory. */ \
(((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address) && \
(((obj_ptr) + (obj_size)) <= (ALIGN_TYPE) (module_instance -> txm_module_instance_shared_memory_address + module_instance -> txm_module_instance_shared_memory_length)))))
/* Define some internal prototypes to this module port. */
#ifndef TX_SOURCE_CODE
#define txm_module_manager_memory_fault_notify _txm_module_manager_memory_fault_notify
#endif
#define TXM_MODULE_MANAGER_ADDITIONAL_PROTOTYPES \
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment); \
VOID _txm_module_manager_memory_fault_handler(VOID); \
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *)); \
VOID _txm_module_manager_setup_mpu_registers(TXM_MODULE_INSTANCE *module_instance);
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module RXv2/IAR Version 6.x *";
#endif

View File

@@ -0,0 +1,173 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module */
/** */
/**************************************************************************/
/**************************************************************************/
#ifndef TXM_MODULE
#define TXM_MODULE
#endif
#ifndef TX_SOURCE_CODE
#define TX_SOURCE_CODE
#endif
/* Include necessary system files. */
#include "txm_module.h"
#include "tx_thread.h"
/* Define the global module entry pointer from the start thread of the module. */
TXM_MODULE_THREAD_ENTRY_INFO *_txm_module_entry_info;
/* Define the dispatch function pointer used in the module implementation. */
ULONG (*_txm_module_kernel_call_dispatcher)(ULONG kernel_request, ULONG param_1, ULONG param_2, ULONG param3);
/* Define the IAR startup code that clears the uninitialized global data and sets up the
preset global variables. */
extern VOID __iar_data_init2(VOID);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry RXv2/IAR */
/* 6.1.9 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calls the specified entry function of the thread. It */
/* also provides a place for the thread's entry function to return. */
/* If the thread returns, this function places the thread in a */
/* "COMPLETED" state. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to current thread */
/* thread_info Pointer to thread entry info */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* __iar_data_init2 IAR global initialization function*/
/* thread_entry Thread's entry function */
/* tx_thread_resume Resume the module callback thread */
/* _txm_module_thread_system_suspend Module thread suspension routine */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* */
/**************************************************************************/
VOID _txm_module_thread_shell_entry(TX_THREAD *thread_ptr, TXM_MODULE_THREAD_ENTRY_INFO *thread_info)
{
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
VOID (*entry_exit_notify)(TX_THREAD *, UINT);
#endif
/* Determine if this is the start thread. If so, we must prepare the module for
execution. If not, simply skip the C startup code. */
if (thread_info -> txm_module_thread_entry_info_start_thread)
{
/* Initialize the IAR C environment. */
__iar_data_init2();
/* Save the entry info pointer, for later use. */
_txm_module_entry_info = thread_info;
/* Save the kernel function dispatch address. This is used to make all resident calls from
the module. */
_txm_module_kernel_call_dispatcher = thread_info -> txm_module_thread_entry_info_kernel_call_dispatcher;
/* Ensure that we have a valid pointer. */
while (!_txm_module_kernel_call_dispatcher)
{
/* Loop here, if an error is present getting the dispatch function pointer!
An error here typically indicates the resident portion of _tx_thread_schedule
is not supporting the trap to obtain the function pointer. */
}
/* Resume the module's callback thread, already created in the manager. */
_txe_thread_resume(thread_info -> txm_module_thread_entry_info_callback_request_thread);
}
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has been entered! */
(entry_exit_notify)(thread_ptr, TX_THREAD_ENTRY);
}
#endif
/* Call current thread's entry function. */
(thread_info -> txm_module_thread_entry_info_entry) (thread_info -> txm_module_thread_entry_info_parameter);
/* Suspend thread with a "completed" state. */
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine again. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has exited! */
(entry_exit_notify)(thread_ptr, TX_THREAD_EXIT);
}
#endif
/* Call actual thread suspension routine. */
_txm_module_thread_system_suspend(thread_ptr);
#ifdef TX_SAFETY_CRITICAL
/* If we ever get here, raise safety critical exception. */
TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
#endif
}

View File

@@ -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 */
/** */
/**************************************************************************/
/**************************************************************************/
extern __tx_initialize_unused_memory
section .text:CODE:ROOT
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level RXv2/IAR */
/* 6.x */
/* 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 */
/* */
/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
/* */
/**************************************************************************/
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 // Pick up 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]
/* Enable SWINT2. */
OR #(1 << 2), r2
MOV.B r2, [r1]
RTS
section FREEMEM:DATA
public __tx_free_memory_start
__tx_free_memory_start
DS32 4
END

View File

@@ -0,0 +1,194 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** 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 RXv2/IAR */
;/* 6.x */
;/* 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 */
;/* */
;/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
;/* */
;/**************************************************************************/
public __tx_thread_context_restore
__tx_thread_context_restore:
;
; /* Lockout interrupts. */
CLRPSW I ; disable interrupts
; /* Determine if interrupts are nested. */
; if (--_tx_thread_system_state)
; {
MOV.L #__tx_thread_system_state, R1
MOV.L [R1], R2
SUB #1, R2
MOV.L R2,[R1]
BEQ __tx_thread_not_nested_restore
;
; /* Interrupts are nested. */
;
; /* Recover the saved registers from the interrupt stack
; and return to the point of interrupt. */
;
__tx_thread_nested_restore:
POPC FPSW ; restore FPU status
POPM R14-R15 ; restore R14-R15
POPM R3-R5 ; restore R3-R5
POPM R1-R2 ; restore R1-R2
RTE ; return to point of interrupt, restore PSW including IPL
; }
__tx_thread_not_nested_restore:
;
; /* Determine if a thread was interrupted and no preemption is required. */
; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
; || (_tx_thread_preempt_disable))
; {
MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address
MOV.L [R1], R2
CMP #0, R2
BEQ __tx_thread_idle_system_restore
MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag
MOV.L [R3], R3
CMP #0, R3
BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless
MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
CMP [R3], R2
BNE __tx_thread_preempt_restore ; jump to pre-empt restoring
;
__tx_thread_no_preempt_restore:
SETPSW U ; user stack
POPC FPSW ; restore FPU status
POPM R14-R15 ; restore R14-R15
POPM R3-R5 ; restore R3-R5
POPM R1-R2 ; restore R1-R2
RTE ; return to point of interrupt, restore PSW including IPL
; }
; else
; {
__tx_thread_preempt_restore:
; /* Save the remaining time-slice and disable it. */
; if (_tx_timer_time_slice)
; {
MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address
MOV.L [R3],R4 ; Pickup actual time-slice
CMP #0, R4
BEQ __tx_thread_dont_save_ts ; no time slice to save
;
; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
; _tx_timer_time_slice = 0;
;
MOV.L R4,24[R2] ; Save thread's time slice
MOV.L #0,R4 ; Clear value
MOV.L R4,[R3] ; Disable global time slice flag
; }
__tx_thread_dont_save_ts:
;
; /* Now store the remaining registers! */
SETPSW U ; user stack
PUSHM R6-R13
MVFACGU #0, A1, R4 ; Save accumulators.
MVFACHI #0, A1, R5
MVFACLO #0, A1, R6
PUSHM R4-R6
MVFACGU #0, A0, R4
MVFACHI #0, A0, R5
MVFACLO #0, A0, R6
PUSHM R4-R6
MOV.L #1, R3 ; indicate interrupt stack frame
PUSH.L R3
;
; /* Clear the current task pointer. */
; _tx_thread_current_ptr = TX_NULL;
; R1 -> _tx_thread_current_ptr
; R2 -> *_tx_thread_current_ptr
MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block
MOV.L #0,R2 ; Build NULL value
MOV.L R2,[R1] ; Set current thread to NULL
; /* Return to the scheduler. */
; _tx_thread_schedule();
__tx_thread_idle_system_restore:
MVTC #0, PSW ; reset interrupt priority level to 0
BRA __tx_thread_schedule ; jump to scheduler
; }
;
;}
;
END

View File

@@ -0,0 +1,160 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the 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 RXv2/IAR */
;/* 6.x */
;/* 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 */
;/* */
;/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
;/* */
;/**************************************************************************/
;VOID _tx_thread_context_save(VOID)
;{
public __tx_thread_context_save
__tx_thread_context_save:
;
; /* Upon entry to this routine, it is assumed that interrupts are locked
; out and the (interrupt) stack frame looks like the following:
;
; (lower address) SP -> [return address of this call]
; SP+4 -> Saved R1
; SP+8 -> Saved R2
; SP+12-> Interrupted PC
; SP+16-> Interrupted PSW
;
; /* Check for a nested interrupt condition. */
; if (_tx_thread_system_state++)
; {
;
MOV.L #__tx_thread_system_state, R1 ; pick up address of system state
MOV.L [R1], R2 ; pick up system state
CMP #0, R2 ; 0 -> no nesting
BEQ __tx_thread_not_nested_save
;
; /* Nested interrupt condition. */
;
ADD #1, r2 ; _tx_thread_system_state++
MOV.L r2, [r1]
;
; /* Save the rest of the scratch registers on the interrupt stack and return to the
; calling ISR. */
POP R1 ; recuperate return address from stack
PUSHM R3-R5
PUSHM R14-R15
PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom)
JMP R1 ; return address was preserved in R1
;
__tx_thread_not_nested_save:
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
ADD #1, R2 ; _tx_thread_system_state++
MOV.L R2, [R1]
MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer
MOV.L [R2], R2
CMP #0,R2 ; Is it NULL?
BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore
;
; /* Move stack frame over to the current threads stack. */
; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */
;
MVFC USP, R1 ; pick up user stack pointer
MOV.L 16[R0], R2
MOV.L R2, [-R1] ; save PSW on thread stack
MOV.L 12[R0], R2
MOV.L R2, [-R1] ; save PC on thread stack
MOV.L 8[R0], R2
MOV.L R2, [-R1] ; save R2 on thread stack
MOV.L 4[R0], R2
MOV.L R2, [-R1] ; save R1 on thread stack
MOV.L R5, [-R1] ; save R5 on thread stack
MOV.L R4, [-R1] ; save R4 on thread stack
MOV.L R3, [-R1] ; save R3 on thread stack
MOV.L R15, [-R1] ; save R15 on thread stack
MOV.L R14, [-R1] ; save R14 on thread stack
MVFC FPSW, R3
MOV.L R3, [-R1] ; save FPSW on thread stack
POP R2 ; pick up return address from interrupt stack
ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom
MVTC R1, USP ; set user/thread stack pointer
JMP R2 ; return to ISR
; }
; else
; {
;
__tx_thread_idle_system_save:
;
; /* Interrupt occurred in the scheduling loop. */
;
POP R1 ; pick up return address
ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
JMP R1 ; return to caller
;
; }
;}
END

View File

@@ -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 RXv2/IAR */
;/* 6.x */
;/* 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 */
;/* */
;/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
;/* */
;/**************************************************************************/
;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

View File

@@ -0,0 +1,387 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the 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
IMPORT __txm_module_manager_kernel_dispatch
IMPORT __tx_thread_system_state
EXTERN __txm_module_manager_memory_fault_info
EXTERN __txm_module_manager_memory_fault_handler
section .text:CODE:ROOT
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule RXv2/IAR */
/* 6.x */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function waits for a thread control block pointer to appear in */
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
/* in the variable, the corresponding thread is resumed. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-xxxx Scott Larson Initial Version 6.x */
/* */
/**************************************************************************/
// 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],SP // Pickup stack pointer
/* Set up MPU. */
// Disable MPU
MOV.L #0x00086500,R1 // Pickup MPEN
MOV #0,R3 // Build disable value
MOV.L R3,[R1] // Disable MPU
// Determine if protection for this thread is required
MOV.L 156[R2],R1 // Pickup user_mode
CMP #0,R1 // Is protection required for this thread?
BEQ skip_mpu_setup // No, skip MPU setup
MOV.L #0x00086408,R1 // Region 1 Start Page Register address
MOV.L 144[R2],R2 // Address of module instance ptr at offset 144 in TCB
ADD #100,R2,R2 // Get address of MPU table in module struct, starting at region 1
// Region 0 (Trampoline from User mode to ThreadX) set up in txm_module_manager_setup_mpu_registers.c
// Build region 1 (User code)
MOV.L [R2+],R4 // Pickup region 1 start page, increment to region 1 end page
MOV.L R4,[R1+] // Setup region 1 start page reg, increment to region 1 end page reg.
MOV.L [R2+],R4 // Pickup region 1 end page, increment to region 2 start page
MOV.L R4,[R1+] // Setup region 1 end page reg, increment to region 2 start page reg.
// Build region 2 (User data)
MOV.L [R2+],R4 // Pickup region 2 start page, increment to region 2 end page
MOV.L R4,[R1+] // Setup region 2 start page reg, increment to region 2 end page reg.
MOV.L [R2+],R4 // Pickup region 2 end page, increment to region 3 start page
MOV.L R4,[R1+] // Setup region 2 end page reg, increment to region 3 start page reg.
// Build region 3 (Shared memory)
MOV.L [R2+],R4 // Pickup region 3 start page, increment to region 3 end page
MOV.L R4,[R1+] // Setup region 3 start page reg, increment to region 3 end page reg.
MOV.L [R2+],R4 // Pickup region 3 end page, increment to region 4 start page
MOV.L R4,[R1+] // Setup region 3 end page reg, increment to region 4 start page reg.
// Region 4-7 unused
// Setup background region
MOV.L #0x00086504,R1 // Pickup MPBAC
MOV #0,[R1] // Read/Write/Execute prohibited.
// Enable MPU
MOV.L #0x00086500,R1 // Pickup MPEN
MOV #1,[R1] // Enable MPU
skip_mpu_setup
/* Determine if an interrupt frame or a synchronous task suspension frame is present. */
POP R1 // Pickup stack type
CMP #1, R1 // Is it an interrupt stack?
BNE __tx_thread_synch_return // No, a synchronous return frame is present.
POPM R1-R3 // Restore accumulators.
MVTACLO R3, A0
MVTACHI R2, A0
MVTACGU R1, A0
POPM R1-R3
MVTACLO R3, A1
MVTACHI R2, A1
MVTACGU R1, A1
POPM R6-R13 // Recover interrupt stack frame
POPC FPSW
POPM R14-R15
POPM R3-R5
POPM R1-R2
RTE // return to point of interrupt, this restores PC and PSW
__tx_thread_synch_return
POPC PSW
POPM R6-R13 // Recover solicited stack frame
RTS
// }
extern __tx_thread_context_save
extern __tx_thread_context_restore
/* Software triggered interrupt used to perform context switches.
The priority of this interrupt is set to the lowest priority within
tx_initialize_low_level() and triggered by ThreadX when calling
_tx_thread_system_return(). */
public ___interrupt_27
___interrupt_27:
PUSHM R1-R2
BSR __tx_thread_context_save
BRA __tx_thread_context_restore
/* You may have to modify BSP to use this handler.
// MPU Memory access violation
PUBLIC ___excep_access_inst
PUBLIC ___violation_handler
___excep_access_inst
___violation_handler
// Disable interrupts
CLRPSW I // disable interrupts
// Save contents of R1 and R2
PUSH R1
PUSH R2
// Increment and save system state
MOV.L #__tx_thread_system_state, R1 // Pickup address of system state
MOV.L [R1], R2 // Pickup system state
ADD #1, R2 // Increment
MOV.L R2, [R1] // Store new system state
// Now pickup and store all the fault related information.
MOV.L #__txm_module_manager_memory_fault_info, R1
MOV.L #__tx_thread_current_ptr, R2 // Build current thread pointer address
MOV.L [R2], R2 // Pickup the current thread pointer
MOV.L R2, 0[R1] // Save current thread pointer in fault info structure
MOV.L 8[SP], R2 // Pickup instruction address at point of fault
MOV.L R2, 4[R1] // Save point of fault
MOV.L #0x0008650C, R2 // Pickup Memory-Protection Error Status Register
MOV.L [R2], 8[R1] // Save MPESTS
MOV.L #0x00086514, R2 // Pickup Data Memory-Protection Error Address Register
MOV.L [R2], 12[R1] // Save MPDEA
MOV.L #0x00086528, R2 // Pickup Instruction Hit Region Register
MOV.L [R2], 16[R1] // Save MHITI
MOV.L #0x0008652C, R2 // Pickup Data Hit Region Register
MOV.L [R2], 20[R1] // Save MHITD
MOV.L 12[SP], R2 // Pickup PSW
MOV.L R2, 24[R1] // Save PSW
MVFC USP, R2 // Pickup user stack pointer
MOV.L R2, 28[R1] // Save user stack pointer
MOV.L R3, 40[R1] // Save R3
MOV.L R4, 44[R1] // Save R4
MOV.L R5, 48[R1] // Save R5
MOV.L R6, 52[R1] // Save R6
MOV.L R7, 56[R1] // Save R7
MOV.L R8, 60[R1] // Save R8
MOV.L R9, 64[R1] // Save R9
MOV.L R10, 68[R1] // Save R10
MOV.L R11, 72[R1] // Save R11
MOV.L R12, 76[R1] // Save R12
MOV.L R13, 80[R1] // Save R13
MOV.L R14, 84[R1] // Save R14
MOV.L R15, 84[R1] // Save R15
POP R3 // Recall R1
MOV.L R3, 32[R1] // Save R1
POP R3 // Recall R2
MOV.L R3, 36[R1] // Save R2
BSR __txm_module_manager_memory_fault_handler // Call memory manager fault handler
// Decrement and save system state
MOV.L #__tx_thread_system_state, R1 // Pickup address of system state
MOV.L [R1], R2 // Pickup system state
SUB #1, R2 // Decrement
MOV.L R2, [R1] // Store new system state
MOV.L #__tx_thread_current_ptr, R2 // Pickup address of current thread pointer
MOV.L #0, [R2] // Clear current thread pointer
BRA __tx_thread_schedule // Attempt to schedule the next thread
*/
public ___interrupt_26
___interrupt_26:
PUBLIC __txm_module_manager_kernel
__txm_module_manager_kernel
MOV.L [SP], R5 // Get return address
CMP #__txm_module_manager_user_mode_entry+3, R5 // Did we come from user_mode_entry?
BEQ __txm_module_manager_entry // If so, continue.
RTE // If not, then return from where we came.
__txm_module_manager_entry
// We are entering the kernel from a module thread with user mode selected.
// At this point, we are out of user mode!
// Clear current user mode.
MOV.L #__tx_thread_current_ptr, R5
MOV [R5],R5
MOV #0,152[R5]
// Switch to kernel stack
PUSHM R1-R2
MVFC USP, R1 // Pickup module thread stack pointer
MOV.L R1, 172[R5] // Save module thread stack pointer
MOV.L 164[R5], R1 // Pickup kernel stack end
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
MOV.L R1, 16[R5] // Set stack end
MOV.L 160[R5], R2 // Pickup kernel stack start
MOV.L R2, 12[R5] // Set stack start
MOV.L 168[R5], R2 // Pickup kernel stack size
MOV.L R2, 20[R5] // Set stack size
#endif
MVTC R1, USP // Set stack pointer
POPM R1-R2
// Modify PSW in ISP to return in supervisor mode and user stack
MOV.L 4[SP], R5
BCLR #20, R5
MOV.L R5, 4[SP]
// Return to user_mode_entry where kernel_dispatch will be called.
RTE
SECTION CODE:CODE (4) // Align 4, smallest page size for MPU is 16 bytes.
ALIGN 4
PUBLIC __txm_module_manager_user_mode_entry
__txm_module_manager_user_mode_entry
INT #26 // Enter ThreadX kernel (exit User mode).
// At this point, we are out of user mode.
// Simply call the kernel dispatch function.
MOV.L #__txm_module_manager_kernel_dispatch,R5
JSR R5
// Restore user mode while inside of ThreadX.
MOV.L #__tx_thread_current_ptr, R5
MOV [R5],R5
MOV #1,152[R5]
// Switch to module thread stack
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
PUSH R1
MOV.L 176[R5], R1 // Pickup module thread stack start
MOV.L R1, 12[R5] // Set stack start
MOV.L 180[R5], R1 // Pickup module thread stack end
MOV.L R1, 16[R5] // Set stack end
MOV.L 184[R5], R1 // Pickup kernel stack size
MOV.L R1, 20[R5] // Set stack size
POP R1
#endif
MOV.L 172[R5], R5 // Pickup module thread stack pointer
MVTC R5, USP // Set stack pointer
// USP is set for an RTS, need to set for RTE to set User mode in PSW.
// Push return address on SP
MOV.L [SP],R5
PUSH R5
// Set user mode and place PSW in prev position in SP
MVFC PSW,R5
BSET #20,R5
MOV.L R5,4[SP]
RTE
// Fill rest of page with NOPs.
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
END

View File

@@ -0,0 +1,147 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
section .text:CODE:ROOT
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_stack_build RXv2/IAR */
;/* 6.x */
;/* 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 */
;/* */
;/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
;/* */
;/**************************************************************************/
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
; ACC1
; R6
; R7
; R8
; R9
; R10
; R11
; R12
; R13
; FPSW
; R14
; R15
; R3
; R4
; R5
; R1
; R2
; PC
; PSW
;
; Stack Bottom: (higher memory address) */
;
MOV.L 16[R1],R3 ; Pickup end of stack area
BCLR #0, R3 ; mask for 4-byte alignment
BCLR #1, R3
;
; /* Build the stack frame. */
;
MOV.L #30000h, R4
MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set)
MOV.L R2, [-R3] ; initial PC
MOV.L #0, R4
MOV.L R4,[-R3] ; initial R2 ...
MOV.L R4,[-R3] ; initial R1 ...
MOV.L R4,[-R3] ; initial R5 ...
MOV.L R4,[-R3] ; initial R4 ...
MOV.L R4,[-R3] ; initial R3 ...
MOV.L R4,[-R3] ; initial R15 ...
MOV.L R4,[-R3] ; initial R14 ...
MVFC FPSW, r4
MOV.L R4, [-R3] ; initial FPSW
MOV.L #0, R4
MOV.L R4,[-R3] ; initial R13 ...
MOV.L R4,[-R3] ; initial R12 ...
MOV.L R4,[-R3] ; initial R11 ...
MOV.L R4,[-R3] ; initial R10 ...
MOV.L R4,[-R3] ; initial R9 ...
MOV.L R4,[-R3] ; initial R8 ...
MOV.L R4,[-R3] ; initial R7 ...
MOV.L R4,[-R3] ; initial R6 ...
MOV.L R4,[-R3] ; Accumulator 1
MOV.L R4,[-R3]
MOV.L R4,[-R3]
MOV.L R4,[-R3] ; Accumulator 0
MOV.L R4,[-R3]
MOV.L R4,[-R3]
MOV.L #1, R4
MOV.L R4,[-R3] ; indicate interrupt stack frame
; /* Setup stack pointer. */
; thread_ptr -> tx_thread_stack_ptr = R1;
MOV.L R3, 8[R1]
; store initial SP in thread control block
RTS
;}
END

View File

@@ -0,0 +1,74 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
section .text:CODE:ROOT
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_system_return RXv2/IAR */
;/* 6.x */
;/* 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 */
;/* */
;/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
;/* */
;/**************************************************************************/
public __tx_thread_system_return
__tx_thread_system_return:
BRA __tx_thread_system_return
RTS
END

View File

@@ -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 RXv2/IAR */
;/* 6.x */
;/* 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 */
;/* */
;/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
;/* */
;/**************************************************************************/
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

View File

@@ -0,0 +1,79 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_alignment_adjust RXv2/IAR */
/* 6.1.9 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function adjusts the alignment and size of the code and data */
/* section for a given module implementation. */
/* */
/* INPUT */
/* */
/* module_preamble Pointer to module preamble */
/* code_size Size of the code area (updated) */
/* code_alignment Code area alignment (updated) */
/* data_size Size of data area (updated) */
/* data_alignment Data area alignment (updated) */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* */
/**************************************************************************/
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble,
ULONG *code_size,
ULONG *code_alignment,
ULONG *data_size,
ULONG *data_alignment)
{
}

View File

@@ -0,0 +1,175 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_mutex.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_external_memory_enable RXv2/IAR */
/* 6.1.9 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates an entry in the MPU table for a shared */
/* memory space. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* start_address Start address of memory */
/* length Length of external memory */
/* attributes Memory attributes (r/w) */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* _txm_power_of_two_block_size Round length to power of two */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* */
/**************************************************************************/
UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance,
VOID *start_address,
ULONG length,
UINT attributes)
{
ULONG address;
UINT attributes_check = 0;
TXM_MODULE_PREAMBLE *module_preamble;
/* Determine if the module manager has not been initialized yet. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module instance is valid. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Determine if the module instance is in the loaded state. */
if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_START_ERROR);
}
/* Check if preamble ext/shared mem property bit set. */
module_preamble = module_instance -> txm_module_instance_preamble_ptr;
if(!(module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if bit not set. */
return(TXM_MODULE_INVALID_PROPERTIES);
}
/* Start address must be 16-byte aligned. */
address = (ULONG) start_address;
if(address != (address & 0xFFFFFFF0))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return alignment error. */
return(TXM_MODULE_ALIGNMENT_ERROR);
}
/* Check length. */
/* At this point, we have a valid address and length. */
/* Build region start page register. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] = address & 0xFFFFFFF0;
/* Check for valid attributes. */
if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_EXECUTE)
{
attributes_check |= TXM_MODULE_MANAGER_ATTRIBUTE_EXECUTE_MPU_BIT;
}
if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE)
{
attributes_check |= TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT;
}
if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_READ)
{
attributes_check |= TXM_MODULE_MANAGER_ATTRIBUTE_READ_MPU_BIT;
}
/* Build region end page register with attributes, OR in the Valid bit. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX+1] = ((address + length - 1) & 0xFFFFFFF0) | attributes_check | 0x01;
/* Save address and length in module. */
module_instance -> txm_module_instance_shared_memory_address = address;
module_instance -> txm_module_instance_shared_memory_length = length;
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,110 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/* Define a macro that can be used to allocate global variables useful to
store information about the last fault. This macro is defined in
txm_module_port.h and is usually populated in the assembly language
fault handling prior to the code calling _txm_module_manager_memory_fault_handler. */
TXM_MODULE_MANAGER_FAULT_INFO
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_handler RXv2/IAR */
/* 6.1.9 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles a fault associated with a memory protected */
/* module. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_terminate Terminate thread */
/* */
/* CALLED BY */
/* */
/* Fault handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* */
/**************************************************************************/
VOID _txm_module_manager_memory_fault_handler(VOID)
{
TXM_MODULE_INSTANCE *module_instance_ptr;
TX_THREAD *thread_ptr;
/* Pickup the current thread. */
thread_ptr = _tx_thread_current_ptr;
/* Initialize the module instance pointer to NULL. */
module_instance_ptr = TX_NULL;
/* Is there a thread? */
if (thread_ptr)
{
/* Pickup the module instance. */
module_instance_ptr = thread_ptr -> tx_thread_module_instance_ptr;
/* Terminate the current thread. */
_tx_thread_terminate(_tx_thread_current_ptr);
}
/* Determine if there is a user memory fault notification callback. */
if (_txm_module_manager_fault_notify)
{
/* Yes, call the user's notification memory fault callback. */
(_txm_module_manager_fault_notify)(thread_ptr, module_instance_ptr);
}
}

View File

@@ -0,0 +1,84 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the external user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
extern VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_notify RXv2/IAR */
/* 6.1.9 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers an application callback when/if a memory */
/* fault occurs. The supplied thread is automatically terminated, but */
/* any other threads in the same module may still execute. */
/* */
/* INPUT */
/* */
/* notify_function Memory fault notification */
/* function, NULL disables. */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* */
/**************************************************************************/
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *))
{
/* Setup notification function. */
_txm_module_manager_fault_notify = notify_function;
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,107 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_setup_mpu_registers RXv2/IAR */
/* 6.1.9 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets up the RX MPU register definitions based */
/* on the module's memory characteristics. */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* */
/* OUTPUT */
/* */
/* MPU specifications for module */
/* */
/* CALLS */
/* */
/* none */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_thread_create */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
/* */
/**************************************************************************/
VOID _txm_module_manager_setup_mpu_registers(TXM_MODULE_INSTANCE *module_instance)
{
ULONG region_size;
ULONG region_start_page_register;
ULONG region_end_page_register;
/* Setup region 0 for the ThreadX trampoline code. */
region_start_page_register = (ULONG) _txm_module_manager_user_mode_entry;
region_start_page_register = region_start_page_register & 0xFFFFFFF0;
module_instance -> txm_module_instance_mpu_registers[0] = region_start_page_register;
/* Region 0 End page is 2 pages away (for a total of 3 pages).
* Set reading permitted, writing prohibited, execution permitted, enable region. */
module_instance -> txm_module_instance_mpu_registers[1] = (region_start_page_register + 0x20) | 0x0B;
/* Place the trampoline protection in the MPU registers */
RSPAGE0 = module_instance -> txm_module_instance_mpu_registers[0];
REPAGE0 = module_instance -> txm_module_instance_mpu_registers[1];
/* Setup region 1 for code area. */
/* Set reading permitted, writing prohibited, execution permitted, enable region. */
region_start_page_register = (ULONG) module_instance -> txm_module_instance_code_start;
region_size = (ULONG) module_instance -> txm_module_instance_code_size;
region_end_page_register = (region_start_page_register + region_size - 1) & 0xFFFFFFF0;
region_start_page_register = region_start_page_register & 0xFFFFFFF0;
module_instance -> txm_module_instance_mpu_registers[2] = region_start_page_register;
module_instance -> txm_module_instance_mpu_registers[3] = region_end_page_register | 0x0B;
/* Setup region 2 for data area. */
/* Set reading permitted, writing permitted, execution prohibited, enable region. */
region_start_page_register = (ULONG) module_instance -> txm_module_instance_data_start;
region_size = (ULONG) module_instance -> txm_module_instance_data_size;
region_end_page_register = (region_start_page_register + region_size - 1) & 0xFFFFFFF0;
region_start_page_register = region_start_page_register & 0xFFFFFFF0;
module_instance -> txm_module_instance_mpu_registers[4] = region_start_page_register;
module_instance -> txm_module_instance_mpu_registers[5] = region_end_page_register | 0x0D;
}

View File

@@ -0,0 +1,147 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
SECTION CODE:CODE
ALIGN 2
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_thread_stack_build RXv2/IAR */
/* 6.x */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds a stack frame on the supplied thread's stack. */
/* The stack frame results in a fake interrupt return to the supplied */
/* function pointer. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to thread control blk */
/* function_ptr Pointer to shell function */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_thread_create Create thread service */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-xxxx Scott Larson Initial Version 6.x */
/* */
/**************************************************************************/
// VOID _txm_module_manager_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(TX_THREAD *, TXM_MODULE_INSTANCE *))
// {
PUBLIC __txm_module_manager_thread_stack_build
__txm_module_manager_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 // make initial PSW (user stack, enable interrupts)
BTST #0,152[R1] // in user mode?
BMC #20,R4 // if user mode, set mode bit of initial PSW
MOV.L R4, [-R3] // initial PSW
MOV.L R2, [-R3] // initial PC
MOV.L 8[R1], R4 // Pickup thread entry info pointer, which is in the stack pointer position of the thread control block.
// It was setup in the txm_module_manager_thread_create function. It will be overwritten later in this
// function with the actual, initial stack pointer.
MOV.L R4,[-R3] // initial R2, which is the module entry information.
MOV.L R1,[-R3] // initial R1, which is the thread control block.
MOV.L #0, R2 // Clear following registers to 0
MOV.L R2,[-R3] // initial R5
MOV.L R2,[-R3] // initial R4
MOV.L R2,[-R3] // initial R3
MOV.L R2,[-R3] // initial R15
MOV.L R2,[-R3] // initial R14
MVFC FPSW, R2 // pickup FPSW
MOV.L R2, [-R3] // initial FPSW
MOV.L 12[R4], R2 // Pickup code base register from the module information
MOV.L R2,[-R3] // initial R13
MOV.L 8[R4], R2 // Pickup data base register from the module information
MOV.L R2,[-R3] // initial R12
MOV.L #0, R4 // Clear following registers to 0
MOV.L R4,[-R3] // initial R11
MOV.L R4,[-R3] // initial R10
MOV.L R4,[-R3] // initial R9
MOV.L R4,[-R3] // initial R8
MOV.L R4,[-R3] // initial R7
MOV.L R4,[-R3] // initial R6
MOV.L R4,[-R3] // Accumulator 1
MOV.L R4,[-R3]
MOV.L R4,[-R3]
MOV.L R4,[-R3] // Accumulator 0
MOV.L R4,[-R3]
MOV.L R4,[-R3]
MOV.L #1, R4 // Make this an interrupt stack frame
MOV.L R4,[-R3]
/* Save stack pointer. */
// thread_ptr -> tx_thread_stack_ptr = R3;
MOV.L R3, 8[R1] // store initial SP in thread control block
RTS
// }
END