Release 6.1.9
This commit is contained in:
189
ports_module/rxv2/iar/example_build/hwsetup.c
Normal file
189
ports_module/rxv2/iar/example_build/hwsetup.c
Normal 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();
|
||||
}
|
||||
49
ports_module/rxv2/iar/example_build/hwsetup.h
Normal file
49
ports_module/rxv2/iar/example_build/hwsetup.h
Normal 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
|
||||
43
ports_module/rxv2/iar/example_build/low_level_init.c
Normal file
43
ports_module/rxv2/iar/example_build/low_level_init.c
Normal 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
|
||||
@@ -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 };
|
||||
78
ports_module/rxv2/iar/example_build/sample_module_linker.icf
Normal file
78
ports_module/rxv2/iar/example_build/sample_module_linker.icf
Normal 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 };
|
||||
425
ports_module/rxv2/iar/example_build/sample_threadx_module.c
Normal file
425
ports_module/rxv2/iar/example_build/sample_threadx_module.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
69
ports_module/rxv2/iar/example_build/txm_module_preamble.s
Normal file
69
ports_module/rxv2/iar/example_build/txm_module_preamble.s
Normal 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
|
||||
|
||||
|
||||
292
ports_module/rxv2/iar/inc/tx_port.h
Normal file
292
ports_module/rxv2/iar/inc/tx_port.h
Normal 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
|
||||
|
||||
401
ports_module/rxv2/iar/inc/txm_module_port.h
Normal file
401
ports_module/rxv2/iar/inc/txm_module_port.h
Normal 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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
387
ports_module/rxv2/iar/module_manager/src/tx_thread_schedule.s
Normal file
387
ports_module/rxv2/iar/module_manager/src/tx_thread_schedule.s
Normal 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
|
||||
147
ports_module/rxv2/iar/module_manager/src/tx_thread_stack_build.s
Normal file
147
ports_module/rxv2/iar/module_manager/src/tx_thread_stack_build.s
Normal 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
|
||||
@@ -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
|
||||
235
ports_module/rxv2/iar/module_manager/src/tx_timer_interrupt.s
Normal file
235
ports_module/rxv2/iar/module_manager/src/tx_timer_interrupt.s
Normal 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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user