mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2025-11-16 04:24:48 +00:00
add SMP, Modules, and more processor/tools releases
This commit is contained in:
Binary file not shown.
19
ports_module/cortex-m3/iar/example_build/azure_rtos.eww
Normal file
19
ports_module/cortex-m3/iar/example_build/azure_rtos.eww
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\sample_threadx_module_manager.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\sample_threadx_module.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\sample_threadx.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\tx.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\txm.ewp</path>
|
||||
</project>
|
||||
<batchBuild />
|
||||
</workspace>
|
||||
73
ports_module/cortex-m3/iar/example_build/cstartup_M.s
Normal file
73
ports_module/cortex-m3/iar/example_build/cstartup_M.s
Normal file
@@ -0,0 +1,73 @@
|
||||
EXTERN __iar_program_start
|
||||
PUBLIC __vector_table
|
||||
|
||||
SECTION .text:CODE:REORDER(1)
|
||||
|
||||
;; Keep vector table even if it's not referenced
|
||||
REQUIRE __vector_table
|
||||
|
||||
THUMB
|
||||
|
||||
;; Forward declaration of sections.
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
SECTION .intvec:CODE:NOROOT(2)
|
||||
|
||||
DATA
|
||||
|
||||
__vector_table
|
||||
DCD sfe(CSTACK)
|
||||
DCD __Reset_Vector
|
||||
|
||||
DCD NMI_Handler
|
||||
DCD HardFault_Handler
|
||||
DCD MemManage_Handler
|
||||
DCD BusFault_Handler
|
||||
DCD UsageFault_Handler
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD SVC_Handler
|
||||
DCD DebugMon_Handler
|
||||
DCD 0
|
||||
DCD PendSV_Handler
|
||||
DCD SysTick_Handler
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Default interrupt handlers.
|
||||
;;
|
||||
|
||||
PUBWEAK NMI_Handler
|
||||
PUBWEAK HardFault_Handler
|
||||
PUBWEAK MemManage_Handler
|
||||
PUBWEAK BusFault_Handler
|
||||
PUBWEAK UsageFault_Handler
|
||||
PUBWEAK SVC_Handler
|
||||
PUBWEAK DebugMon_Handler
|
||||
PUBWEAK PendSV_Handler
|
||||
PUBWEAK SysTick_Handler
|
||||
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
THUMB
|
||||
__Reset_Vector:
|
||||
CPSID i ; Disable interrupts
|
||||
B __iar_program_start
|
||||
|
||||
|
||||
NMI_Handler
|
||||
HardFault_Handler
|
||||
MemManage_Handler
|
||||
BusFault_Handler
|
||||
UsageFault_Handler
|
||||
SVC_Handler
|
||||
DebugMon_Handler
|
||||
PendSV_Handler
|
||||
SysTick_Handler
|
||||
Default_Handler
|
||||
__default_handler
|
||||
CALL_GRAPH_ROOT __default_handler, "interrupt"
|
||||
NOCALL __default_handler
|
||||
B __default_handler
|
||||
|
||||
END
|
||||
385
ports_module/cortex-m3/iar/example_build/sample_threadx.c
Normal file
385
ports_module/cortex-m3/iar/example_build/sample_threadx.c
Normal file
@@ -0,0 +1,385 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
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 byte pool memory. */
|
||||
|
||||
UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE];
|
||||
|
||||
|
||||
/* Define event buffer. */
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
UCHAR trace_buffer[0x10000];
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
CHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
tx_trace_enable(trace_buffer, sizeof(trace_buffer), 32);
|
||||
#endif
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", byte_pool_memory, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create the main thread. */
|
||||
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
|
||||
/* Allocate the stack for thread 1. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
message queue. It is also interesting to note that these threads have a time
|
||||
slice. */
|
||||
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 2. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 3. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
An interesting thing here is that both threads share the same instruction area. */
|
||||
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 4. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create thread 5. This thread simply pends on an event flag which will be set
|
||||
by thread_0. */
|
||||
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 6. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
|
||||
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 7. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
2974
ports_module/cortex-m3/iar/example_build/sample_threadx.ewd
Normal file
2974
ports_module/cortex-m3/iar/example_build/sample_threadx.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2140
ports_module/cortex-m3/iar/example_build/sample_threadx.ewp
Normal file
2140
ports_module/cortex-m3/iar/example_build/sample_threadx.ewp
Normal file
File diff suppressed because it is too large
Load Diff
2788
ports_module/cortex-m3/iar/example_build/sample_threadx.ewt
Normal file
2788
ports_module/cortex-m3/iar/example_build/sample_threadx.ewt
Normal file
File diff suppressed because it is too large
Load Diff
34
ports_module/cortex-m3/iar/example_build/sample_threadx.icf
Normal file
34
ports_module/cortex-m3/iar/example_build/sample_threadx.icf
Normal file
@@ -0,0 +1,34 @@
|
||||
define symbol __ICFEDIT_intvec_start__ = 0x0;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x80;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x1FFFF;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x100000;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x1FFFFF;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 0x2000;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x8000;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol __ICFEDIT_size_freemem__ = 0x100000;
|
||||
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
define region RAM_freemem = mem:[from 0x200000 to 0x300000];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
|
||||
initialize by copy { readwrite };
|
||||
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
|
||||
do not initialize { section .noinit };
|
||||
|
||||
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
|
||||
place in ROM_region { readonly };
|
||||
place in RAM_region { readwrite,
|
||||
block CSTACK, block HEAP};
|
||||
|
||||
place in RAM_region { last section FREE_MEM};
|
||||
428
ports_module/cortex-m3/iar/example_build/sample_threadx_module.c
Normal file
428
ports_module/cortex-m3/iar/example_build/sample_threadx_module.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/* 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)
|
||||
{
|
||||
/* Test memory handler. */
|
||||
*(ULONG *)0x64005000 = 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2974
ports_module/cortex-m3/iar/example_build/sample_threadx_module.ewd
Normal file
2974
ports_module/cortex-m3/iar/example_build/sample_threadx_module.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2135
ports_module/cortex-m3/iar/example_build/sample_threadx_module.ewp
Normal file
2135
ports_module/cortex-m3/iar/example_build/sample_threadx_module.ewp
Normal file
File diff suppressed because it is too large
Load Diff
2785
ports_module/cortex-m3/iar/example_build/sample_threadx_module.ewt
Normal file
2785
ports_module/cortex-m3/iar/example_build/sample_threadx_module.ewt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = 0x0;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x080f0000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x080fffff;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x64002800;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x64100000;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 0;
|
||||
define symbol __ICFEDIT_size_svcstack__ = 0;
|
||||
define symbol __ICFEDIT_size_irqstack__ = 0;
|
||||
define symbol __ICFEDIT_size_fiqstack__ = 0;
|
||||
define symbol __ICFEDIT_size_undstack__ = 0;
|
||||
define symbol __ICFEDIT_size_abtstack__ = 0;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x1000;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
|
||||
//define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
//define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { };
|
||||
//define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
|
||||
//define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
|
||||
//define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
|
||||
//define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
initialize by copy { readwrite };
|
||||
do not initialize { section .noinit };
|
||||
|
||||
//place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
|
||||
define movable block ROPI with alignment = 4, fixed order
|
||||
{
|
||||
ro object txm_module_preamble.o,
|
||||
ro,
|
||||
ro data
|
||||
};
|
||||
|
||||
define movable block RWPI with alignment = 8, fixed order, static base
|
||||
{
|
||||
rw,
|
||||
block HEAP
|
||||
};
|
||||
|
||||
place in ROM_region { block ROPI };
|
||||
place in RAM_region { block RWPI };
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/* 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 *) 0x64000000, 0x1000000);
|
||||
|
||||
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 *) 0x080F0000);
|
||||
|
||||
/* Enable 128 byte read/write shared memory region at 0x64005000. */
|
||||
txm_module_manager_external_memory_enable(&my_module, (void *) 0x64005000, 128, 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 *) 0x080F0000);
|
||||
|
||||
/* Start the module again. */
|
||||
txm_module_manager_start(&my_module);
|
||||
|
||||
/* Now just spin... */
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_sleep(100);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x64000000;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x640FFFFF;
|
||||
define symbol __ICFEDIT_region_IRAM_start__ = 0x20000000;
|
||||
define symbol __ICFEDIT_region_IRAM_end__ = 0x2001FFFF;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 0x400;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x200;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
define region IRAM_region = mem:[from __ICFEDIT_region_IRAM_start__ to __ICFEDIT_region_IRAM_end__];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
initialize by copy { readwrite };
|
||||
do not initialize { section .noinit };
|
||||
|
||||
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
|
||||
place in ROM_region { readonly };
|
||||
place in IRAM_region { block HEAP };
|
||||
place in IRAM_region { readwrite, block CSTACK };
|
||||
|
||||
place in IRAM_region { last section FREE_MEM};
|
||||
@@ -0,0 +1,561 @@
|
||||
<?xml version="1.0"?>
|
||||
<Workspace>
|
||||
<ConfigDictionary>
|
||||
<CurrentConfigs>
|
||||
<Project>sample_threadx_module_manager/Debug</Project>
|
||||
<Project>sample_threadx_module/Debug</Project>
|
||||
<Project>sample_threadx/Debug</Project>
|
||||
<Project>tx/Debug</Project>
|
||||
<Project>txm/Debug</Project>
|
||||
</CurrentConfigs>
|
||||
<CurrentProj>sample_threadx_module_manager</CurrentProj>
|
||||
<OverviewSelected>1</OverviewSelected>
|
||||
</ConfigDictionary>
|
||||
<WindowStorage>
|
||||
<Desktop>
|
||||
<IarPane-34048>
|
||||
<ColumnWidth0>21</ColumnWidth0>
|
||||
<ColumnWidth1>2518</ColumnWidth1>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile></LiveFile>
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34048>
|
||||
<IarPane-34049>
|
||||
<ToolBarCmdIds>
|
||||
<item>34001</item>
|
||||
<item>0</item>
|
||||
</ToolBarCmdIds>
|
||||
</IarPane-34049>
|
||||
<IarPane-34050>
|
||||
<ToolBarCmdIds>
|
||||
<item>57600</item>
|
||||
<item>57601</item>
|
||||
<item>57603</item>
|
||||
<item>33024</item>
|
||||
<item>0</item>
|
||||
<item>57607</item>
|
||||
<item>0</item>
|
||||
<item>57635</item>
|
||||
<item>57634</item>
|
||||
<item>57637</item>
|
||||
<item>0</item>
|
||||
<item>57643</item>
|
||||
<item>57644</item>
|
||||
<item>0</item>
|
||||
<item>33090</item>
|
||||
<item>33057</item>
|
||||
<item>57636</item>
|
||||
<item>57640</item>
|
||||
<item>57641</item>
|
||||
<item>33026</item>
|
||||
<item>33065</item>
|
||||
<item>33063</item>
|
||||
<item>33064</item>
|
||||
<item>33053</item>
|
||||
<item>33054</item>
|
||||
<item>0</item>
|
||||
<item>33035</item>
|
||||
<item>33036</item>
|
||||
<item>34399</item>
|
||||
<item>0</item>
|
||||
<item>33038</item>
|
||||
<item>33039</item>
|
||||
<item>0</item>
|
||||
</ToolBarCmdIds>
|
||||
</IarPane-34050>
|
||||
<IarPane-34065>
|
||||
<ColumnWidths>
|
||||
<Column0>439</Column0>
|
||||
<Column1>30</Column1>
|
||||
<Column2>30</Column2>
|
||||
<Column3>30</Column3>
|
||||
</ColumnWidths>
|
||||
<NodeDict>
|
||||
<ExpandedNode><ws></ExpandedNode>
|
||||
</NodeDict>
|
||||
</IarPane-34065>
|
||||
<ControlBarVersion>
|
||||
<Major>14</Major>
|
||||
<Minor>26</Minor>
|
||||
</ControlBarVersion>
|
||||
<MFCToolBarParameters>
|
||||
<Tooltips>1</Tooltips>
|
||||
<ShortcutKeys>1</ShortcutKeys>
|
||||
<LargeIcons>0</LargeIcons>
|
||||
<MenuAnimation>0</MenuAnimation>
|
||||
<RecentlyUsedMenus>1</RecentlyUsedMenus>
|
||||
<MenuShadows>1</MenuShadows>
|
||||
<ShowAllMenusAfterDelay>1</ShowAllMenusAfterDelay>
|
||||
<CommandsUsage>2600000031002596000001000000138600000800000029810000020000005786000001000000108600002B00000001840000010000005992000001000000268100000100000000DA00000100000029E1000002000000ED8000000100000020810000010000000F810000010000000C810000060000000D8000000100000001E10000010000001D81000002000000EA8000000100000008DA000001000000048600000100000003DC0000010000002496000001000000178100000400000056860000010000000384000008000000148100000100000007B000000100000000810000020000000C8600000100000003E10000020000001A86000001000000EC800000010000000E81000014000000E9800000020000000B8100000200000014860000020000002396000008000000118600002A00000002840000010000000086000001000000F48000000100000055860000010000002481000001000000468100000200000008860000010000000D81000008000000EB80000002000000E88000000100000006DA000001000000</CommandsUsage>
|
||||
</MFCToolBarParameters>
|
||||
<CommandManager>
|
||||
<CommandsWithoutImages>30000D8400000F84000008840000FFFFFFFF54840000328100001C810000098400000088000001880000028800000388000004880000058800007784000007840000808C000044D500003284000002840000038400001084000005840000318400000A840000518400000C8400003384000078840000118400001E92000028920000299200002592000024960000259600001F9600001D92000008800000098000000A8000000B8000000C800000158000000A81000001E800000484000006840000</CommandsWithoutImages>
|
||||
<MenuUserImages>22005992000012000000048100001C000000158100002100000007E100003700000020810000270000000F8100001F00000004E10000350000000C8100001C0000000D8000001300000001E1000032000000098100001E00000017810000230000001481000020000000449200001000000000810000150000000E8400005000000030840000520000001F9200000D0000001F810000260000000E8100001E00000003E10000340000002D9200000F0000000B8100001F00000000E1000031000000D18400000C00000041E10000410000002396000058000000058100001D000000168100002200000005E100003600000035E10000440000000D8100002100000002E10000370000002C9200000E000000</MenuUserImages>
|
||||
</CommandManager>
|
||||
<Pane-59393>
|
||||
<ID>0</ID>
|
||||
<RectRecentFloat>0A0000000A0000006E0000006E000000</RectRecentFloat>
|
||||
<RectRecentDocked>000000004E050000000A000061050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-59393>
|
||||
<BasePane-59393>
|
||||
<IsVisible>1</IsVisible>
|
||||
</BasePane-59393>
|
||||
<Pane-34051>
|
||||
<ID>34051</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34051>
|
||||
<BasePane-34051>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34051>
|
||||
<IarPane-34051 />
|
||||
<Pane--1>
|
||||
<ID>4294967295</ID>
|
||||
<RectRecentFloat>0000000007040000000A000065050000</RectRecentFloat>
|
||||
<RectRecentDocked>00000000F0030000000A00004E050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane--1>
|
||||
<BasePane--1>
|
||||
<IsVisible>1</IsVisible>
|
||||
</BasePane--1>
|
||||
<Pane-34052>
|
||||
<ID>34052</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>0400000008040000FC09000034050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34052>
|
||||
<BasePane-34052>
|
||||
<IsVisible>1</IsVisible>
|
||||
</BasePane-34052>
|
||||
<IarPane-34052>
|
||||
<ColumnWidth0>24</ColumnWidth0>
|
||||
<ColumnWidth1>1880</ColumnWidth1>
|
||||
<ColumnWidth2>501</ColumnWidth2>
|
||||
<ColumnWidth3>125</ColumnWidth3>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile>C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_m3\iar\example_build\BuildLog.log</LiveFile>
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34052>
|
||||
<Pane-34048>
|
||||
<ID>34048</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>0400000008040000FC09000034050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34048>
|
||||
<BasePane-34048>
|
||||
<IsVisible>1</IsVisible>
|
||||
</BasePane-34048>
|
||||
<Pane-34056>
|
||||
<ID>34056</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>0400000008040000FC09000034050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34056>
|
||||
<BasePane-34056>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34056>
|
||||
<IarPane-34056>
|
||||
<ColumnWidth0>891</ColumnWidth0>
|
||||
<ColumnWidth1>127</ColumnWidth1>
|
||||
<ColumnWidth2>1528</ColumnWidth2>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile />
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34056>
|
||||
<Pane-34057>
|
||||
<ID>34057</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>0400000008040000FC09000034050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34057>
|
||||
<BasePane-34057>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34057>
|
||||
<IarPane-34057>
|
||||
<ColumnWidth0>891</ColumnWidth0>
|
||||
<ColumnWidth1>127</ColumnWidth1>
|
||||
<ColumnWidth2>1528</ColumnWidth2>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile />
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34057>
|
||||
<Pane-34058>
|
||||
<ID>34058</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>0400000008040000FC09000034050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34058>
|
||||
<BasePane-34058>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34058>
|
||||
<IarPane-34058>
|
||||
<ColumnWidth0>764</ColumnWidth0>
|
||||
<ColumnWidth1>127</ColumnWidth1>
|
||||
<ColumnWidth2>1146</ColumnWidth2>
|
||||
<ColumnWidth3>509</ColumnWidth3>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile />
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34058>
|
||||
<Pane-34059>
|
||||
<ID>34059</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>0400000008040000FC09000034050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34059>
|
||||
<BasePane-34059>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34059>
|
||||
<IarPane-34059>
|
||||
<ColumnWidth0>891</ColumnWidth0>
|
||||
<ColumnWidth1>127</ColumnWidth1>
|
||||
<ColumnWidth2>1528</ColumnWidth2>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile />
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34059>
|
||||
<Pane-34062>
|
||||
<ID>34062</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>0400000008040000FC09000034050000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34062>
|
||||
<BasePane-34062>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34062>
|
||||
<IarPane-34062>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile />
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34062>
|
||||
<Pane-34053>
|
||||
<ID>34053</ID>
|
||||
<RectRecentFloat>000000001700000080020000A8000000</RectRecentFloat>
|
||||
<RectRecentDocked>00000000000000008002000091000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34053>
|
||||
<BasePane-34053>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34053>
|
||||
<IarPane-34053>
|
||||
<cg_type>
|
||||
<item>2</item>
|
||||
</cg_type>
|
||||
<cg_symbol>
|
||||
<item />
|
||||
</cg_symbol>
|
||||
<cg_user>
|
||||
<item />
|
||||
</cg_user>
|
||||
<cg_display>
|
||||
<item><Right-click on a symbol in the editor to show a call graph></item>
|
||||
</cg_display>
|
||||
<cg_def_file>
|
||||
<item />
|
||||
</cg_def_file>
|
||||
<cg_def_line>
|
||||
<item>0</item>
|
||||
</cg_def_line>
|
||||
<cg_def_col>
|
||||
<item>0</item>
|
||||
</cg_def_col>
|
||||
<cg_call_file>
|
||||
<item />
|
||||
</cg_call_file>
|
||||
<cg_call_line>
|
||||
<item>0</item>
|
||||
</cg_call_line>
|
||||
<cg_call_col>
|
||||
<item>0</item>
|
||||
</cg_call_col>
|
||||
<col-names>
|
||||
<item>File</item>
|
||||
<item>Function</item>
|
||||
<item>Line</item>
|
||||
</col-names>
|
||||
<col-widths>
|
||||
<item>200</item>
|
||||
<item>700</item>
|
||||
<item>100</item>
|
||||
</col-widths>
|
||||
</IarPane-34053>
|
||||
<Pane-34054>
|
||||
<ID>34054</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34054>
|
||||
<BasePane-34054>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34054>
|
||||
<IarPane-34054 />
|
||||
<Pane-34055>
|
||||
<ID>34055</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34055>
|
||||
<BasePane-34055>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34055>
|
||||
<IarPane-34055>
|
||||
<col-names>
|
||||
<item>Check</item>
|
||||
<item>File</item>
|
||||
<item>Line</item>
|
||||
<item>Message</item>
|
||||
<item>Severity</item>
|
||||
</col-names>
|
||||
<col-widths>
|
||||
<item>200</item>
|
||||
<item>200</item>
|
||||
<item>100</item>
|
||||
<item>500</item>
|
||||
<item>100</item>
|
||||
</col-widths>
|
||||
</IarPane-34055>
|
||||
<Pane-34060>
|
||||
<ID>34060</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34060>
|
||||
<BasePane-34060>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34060>
|
||||
<IarPane-34060>
|
||||
<FilterLevel>2</FilterLevel>
|
||||
<LiveFile>$WS_DIR/SourceBrowseLog.log</LiveFile>
|
||||
<LiveLogEnabled>0</LiveLogEnabled>
|
||||
<LiveFilterLevel>-1</LiveFilterLevel>
|
||||
</IarPane-34060>
|
||||
<Pane-34061>
|
||||
<ID>34061</ID>
|
||||
<RectRecentFloat>000000001700000080020000A8000000</RectRecentFloat>
|
||||
<RectRecentDocked>00000000000000008002000091000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34061>
|
||||
<BasePane-34061>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34061>
|
||||
<IarPane-34061>
|
||||
<SB_FileFilter>
|
||||
<item>2</item>
|
||||
</SB_FileFilter>
|
||||
<SB_TypeFilter>
|
||||
<item>0</item>
|
||||
</SB_TypeFilter>
|
||||
<SB_SBW_File>
|
||||
<item>C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\Debug\Obj\sample_threadx_module_manager.pbw</item>
|
||||
</SB_SBW_File>
|
||||
<col-names>
|
||||
<item>File</item>
|
||||
<item>Name</item>
|
||||
<item>Scope</item>
|
||||
<item>Symbol type</item>
|
||||
</col-names>
|
||||
<col-widths>
|
||||
<item>300</item>
|
||||
<item>300</item>
|
||||
<item>300</item>
|
||||
<item>300</item>
|
||||
</col-widths>
|
||||
</IarPane-34061>
|
||||
<Pane-34063>
|
||||
<ID>34063</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>1</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34063>
|
||||
<BasePane-34063>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34063>
|
||||
<IarPane-34063 />
|
||||
<Pane-34064>
|
||||
<ID>34064</ID>
|
||||
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
|
||||
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>32768</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>1</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34064>
|
||||
<BasePane-34064>
|
||||
<IsVisible>0</IsVisible>
|
||||
</BasePane-34064>
|
||||
<IarPane-34064>
|
||||
<col-names>
|
||||
<item>Description</item>
|
||||
<item>First Activation</item>
|
||||
<item>Hold Time</item>
|
||||
<item>Id</item>
|
||||
<item>Interrupt</item>
|
||||
<item>Probability (%)</item>
|
||||
<item>Repeat Interval</item>
|
||||
<item>Type</item>
|
||||
<item>Variance (%)</item>
|
||||
</col-names>
|
||||
<col-widths>
|
||||
<item>150</item>
|
||||
<item>70</item>
|
||||
<item>70</item>
|
||||
<item>40</item>
|
||||
<item>100</item>
|
||||
<item>70</item>
|
||||
<item>70</item>
|
||||
<item>100</item>
|
||||
<item>70</item>
|
||||
</col-widths>
|
||||
</IarPane-34064>
|
||||
<Pane-34065>
|
||||
<ID>34065</ID>
|
||||
<RectRecentFloat>00000000170000000601000078010000</RectRecentFloat>
|
||||
<RectRecentDocked>0000000032000000FF010000EC030000</RectRecentDocked>
|
||||
<RecentFrameAlignment>4096</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>32767</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34065>
|
||||
<BasePane-34065>
|
||||
<IsVisible>1</IsVisible>
|
||||
</BasePane-34065>
|
||||
<DockingManager-256>
|
||||
<DockingPaneAndPaneDividers>0000000010000000000000000010000001000000FFFFFFFFFFFFFFFFFF0100003200000003020000EC03000001000000020000100400000001000000A3FEFFFF03080000118500000000000000000000000000000000000001000000118500000100000011850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000001000000FFFFFFFFFFFFFFFF00000000EC030000000A0000F0030000010000000100001004000000010000009EFBFFFF6F000000FFFFFFFF07000000048500000085000008850000098500000A8500000B8500000E850000FFFF02000B004354616262656450616E6500800000010000000000000007040000000A00006505000000000000F0030000000A00004E050000000000004080005607000000FFFEFF054200750069006C006400010000000485000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000085000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0485000001000000FFFFFFFF04850000000000000080000000000000FFFFFFFFFFFFFFFF0000000000000000040000000400000000000000010000000400000001000000000000000000000003850000000000000000000000000000000000000100000003850000010000000385000002000000FFFF02001200434D756C746950616E654672616D65576E6400010084000000001700000022010000C8000000000000000000000002000000000000000F85000000000000000000000000000000000000010000000F850000038000010084000000001700000022010000C800000000000000000000000200000000000000108500000000000000000000000000000000000001000000108500000000000000000000</DockingPaneAndPaneDividers>
|
||||
</DockingManager-256>
|
||||
<MFCToolBar-34049>
|
||||
<Name>CMSIS-Pack</Name>
|
||||
<Buttons>00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED1840000000000000C000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000</Buttons>
|
||||
</MFCToolBar-34049>
|
||||
<Pane-34049>
|
||||
<ID>34049</ID>
|
||||
<RectRecentFloat>0A0000000A0000006E0000006E000000</RectRecentFloat>
|
||||
<RectRecentDocked>FE020000000000002C0300001A000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>8192</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>24</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34049>
|
||||
<BasePane-34049>
|
||||
<IsVisible>1</IsVisible>
|
||||
</BasePane-34049>
|
||||
<MFCToolBar-34050>
|
||||
<Name>Main</Name>
|
||||
<Buttons>00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000035000000FFFEFF000000000000000000000000000100000001000000018001E100000000000036000000FFFEFF000000000000000000000000000100000001000000018003E100000000040038000000FFFEFF0000000000000000000000000001000000010000000180008100000000000019000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000004003B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004003D000000FFFEFF000000000000000000000000000100000001000000018022E10000000004003C000000FFFEFF000000000000000000000000000100000001000000018025E10000000004003F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040042000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040043000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000400FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000100FFFEFF0D520065007300650074005F00480061006E0064006C006500720000000000018021810000000004002C000000FFFEFF000000000000000000000000000100000001000000018024E10000000004003E000000FFFEFF000000000000000000000000000100000001000000018028E100000000040040000000FFFEFF000000000000000000000000000100000001000000018029E100000000040041000000FFFEFF000000000000000000000000000100000001000000018002810000000004001B000000FFFEFF0000000000000000000000000001000000010000000180298100000000040030000000FFFEFF000000000000000000000000000100000001000000018027810000000004002E000000FFFEFF000000000000000000000000000100000001000000018028810000000004002F000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040028000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040029000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000004001F000000FFFEFF00000000000000000000000000010000000100000001800C8100000000000020000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000034000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000000000022000000FFFEFF00000000000000000000000000010000000100000001800F8100000000000023000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00E8020000</Buttons>
|
||||
</MFCToolBar-34050>
|
||||
<Pane-34050>
|
||||
<ID>34050</ID>
|
||||
<RectRecentFloat>0A0000000A0000006E0000006E000000</RectRecentFloat>
|
||||
<RectRecentDocked>0000000000000000FE0200001A000000</RectRecentDocked>
|
||||
<RecentFrameAlignment>8192</RecentFrameAlignment>
|
||||
<RecentRowIndex>0</RecentRowIndex>
|
||||
<IsFloating>0</IsFloating>
|
||||
<MRUWidth>744</MRUWidth>
|
||||
<PinState>0</PinState>
|
||||
</Pane-34050>
|
||||
<BasePane-34050>
|
||||
<IsVisible>1</IsVisible>
|
||||
</BasePane-34050>
|
||||
</Desktop>
|
||||
<ChildIdMap>
|
||||
<WIN_DEBUG_LOG>34048</WIN_DEBUG_LOG>
|
||||
<TB_CMSISPACK>34049</TB_CMSISPACK>
|
||||
<TB_MAIN2>34050</TB_MAIN2>
|
||||
<WIN_BREAKPOINTS>34051</WIN_BREAKPOINTS>
|
||||
<WIN_BUILD>34052</WIN_BUILD>
|
||||
<WIN_CALL_GRAPH>34053</WIN_CALL_GRAPH>
|
||||
<WIN_CUSTOM_SFR>34054</WIN_CUSTOM_SFR>
|
||||
<WIN_C_STAT>34055</WIN_C_STAT>
|
||||
<WIN_FIND_ALL_DECLARATIONS>34056</WIN_FIND_ALL_DECLARATIONS>
|
||||
<WIN_FIND_ALL_REFERENCES>34057</WIN_FIND_ALL_REFERENCES>
|
||||
<WIN_FIND_IN_FILES>34058</WIN_FIND_IN_FILES>
|
||||
<WIN_SELECT_AMBIGUOUS_DEFINITIONS>34059</WIN_SELECT_AMBIGUOUS_DEFINITIONS>
|
||||
<WIN_SOURCEBROWSE_LOG>34060</WIN_SOURCEBROWSE_LOG>
|
||||
<WIN_SOURCE_BROWSE2>34061</WIN_SOURCE_BROWSE2>
|
||||
<WIN_TOOL_OUTPUT>34062</WIN_TOOL_OUTPUT>
|
||||
<WIN_TS_INTERRUPT_AVAILABLE>34063</WIN_TS_INTERRUPT_AVAILABLE>
|
||||
<WIN_TS_INTERRUPT_CONFIG>34064</WIN_TS_INTERRUPT_CONFIG>
|
||||
<WIN_WORKSPACE>34065</WIN_WORKSPACE>
|
||||
</ChildIdMap>
|
||||
<MDIWindows>
|
||||
<MDIClientArea-0>
|
||||
<MDITabsState>010000000300000001000000000000000000000001000000010000000200000000000000010000000100000000000000280000002800000000000000</MDITabsState>
|
||||
</MDIClientArea-0>
|
||||
</MDIWindows>
|
||||
</WindowStorage>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,40 @@
|
||||
@REM This batch file has been generated by the IAR Embedded Workbench
|
||||
@REM C-SPY Debugger, as an aid to preparing a command line for running
|
||||
@REM the cspybat command line utility using the appropriate settings.
|
||||
@REM
|
||||
@REM Note that this file is generated every time a new debug session
|
||||
@REM is initialized, so you may want to move or rename the file before
|
||||
@REM making changes.
|
||||
@REM
|
||||
@REM You can launch cspybat by typing the name of this batch file followed
|
||||
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
|
||||
@REM
|
||||
@REM Read about available command line parameters in the C-SPY Debugging
|
||||
@REM Guide. Hints about additional command line parameters that may be
|
||||
@REM useful in specific cases:
|
||||
@REM --download_only Downloads a code image without starting a debug
|
||||
@REM session afterwards.
|
||||
@REM --silent Omits the sign-on message.
|
||||
@REM --timeout Limits the maximum allowed execution time.
|
||||
@REM
|
||||
|
||||
|
||||
@echo off
|
||||
|
||||
if not "%~1" == "" goto debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
goto end
|
||||
|
||||
:debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
:end
|
||||
@@ -0,0 +1,31 @@
|
||||
param([String]$debugfile = "");
|
||||
|
||||
# This powershell file has been generated by the IAR Embedded Workbench
|
||||
# C - SPY Debugger, as an aid to preparing a command line for running
|
||||
# the cspybat command line utility using the appropriate settings.
|
||||
#
|
||||
# Note that this file is generated every time a new debug session
|
||||
# is initialized, so you may want to move or rename the file before
|
||||
# making changes.
|
||||
#
|
||||
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
|
||||
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
|
||||
#
|
||||
# Read about available command line parameters in the C - SPY Debugging
|
||||
# Guide. Hints about additional command line parameters that may be
|
||||
# useful in specific cases :
|
||||
# --download_only Downloads a code image without starting a debug
|
||||
# session afterwards.
|
||||
# --silent Omits the sign - on message.
|
||||
# --timeout Limits the maximum allowed execution time.
|
||||
#
|
||||
|
||||
|
||||
if ($debugfile -eq "")
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
|
||||
}
|
||||
else
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
"--endian=little"
|
||||
|
||||
"--cpu=Cortex-M3"
|
||||
|
||||
"--fpu=None"
|
||||
|
||||
"--semihosting"
|
||||
|
||||
"--multicore_nr_of_cores=1"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armproc.dll"
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armsim2.dll"
|
||||
|
||||
"C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\Debug\Exe\sample_threadx.out"
|
||||
|
||||
--plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armbat.dll"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<crun>
|
||||
<version>1</version>
|
||||
<filter_entries>
|
||||
<filter index="0" type="default">
|
||||
<type>*</type>
|
||||
<start_file>*</start_file>
|
||||
<end_file>*</end_file>
|
||||
<action_debugger>0</action_debugger>
|
||||
<action_log>1</action_log>
|
||||
</filter>
|
||||
</filter_entries>
|
||||
</crun>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
<Stack>
|
||||
<FillEnabled>0</FillEnabled>
|
||||
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
|
||||
<WarningThreshold>90</WarningThreshold>
|
||||
<SpWarningsEnabled>1</SpWarningsEnabled>
|
||||
<WarnLogOnly>1</WarnLogOnly>
|
||||
<UseTrigger>1</UseTrigger>
|
||||
<TriggerName>main</TriggerName>
|
||||
<LimitSize>0</LimitSize>
|
||||
<ByteLimit>50</ByteLimit>
|
||||
</Stack>
|
||||
<Trace1>
|
||||
<Enabled>0</Enabled>
|
||||
<ShowSource>1</ShowSource>
|
||||
</Trace1>
|
||||
<DebugChecksum>
|
||||
<Checksum>1618778298</Checksum>
|
||||
</DebugChecksum>
|
||||
<CodeCoverage>
|
||||
<Enabled>0</Enabled>
|
||||
<ShowSource>0</ShowSource>
|
||||
<HideCovered>0</HideCovered>
|
||||
</CodeCoverage>
|
||||
<Disassembly>
|
||||
<InstrCount>0</InstrCount>
|
||||
</Disassembly>
|
||||
<Exceptions>
|
||||
<StopOnUncaught>_ 0</StopOnUncaught>
|
||||
<StopOnThrow>_ 0</StopOnThrow>
|
||||
</Exceptions>
|
||||
<CallStack>
|
||||
<ShowArgs>0</ShowArgs>
|
||||
</CallStack>
|
||||
<DriverProfiling>
|
||||
<Enabled>0</Enabled>
|
||||
<Mode>1</Mode>
|
||||
<Graph>0</Graph>
|
||||
<Symbiont>0</Symbiont>
|
||||
</DriverProfiling>
|
||||
<CallStackLog>
|
||||
<Enabled>0</Enabled>
|
||||
</CallStackLog>
|
||||
<CallStackStripe>
|
||||
<ShowTiming>1</ShowTiming>
|
||||
</CallStackStripe>
|
||||
<TermIOLog>
|
||||
<LoggingEnabled>_ 0</LoggingEnabled>
|
||||
<LogFile>_ ""</LogFile>
|
||||
</TermIOLog>
|
||||
<LogFile>
|
||||
<LoggingEnabled>_ 0</LoggingEnabled>
|
||||
<LogFile>_ ""</LogFile>
|
||||
<Category>_ 0</Category>
|
||||
</LogFile>
|
||||
<InterruptLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
<SumSortOrder>0</SumSortOrder>
|
||||
</InterruptLog>
|
||||
<DataLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
</DataLog>
|
||||
<DisassembleMode>
|
||||
<mode>0</mode>
|
||||
</DisassembleMode>
|
||||
<Breakpoints2>
|
||||
<Count>0</Count>
|
||||
</Breakpoints2>
|
||||
<Interrupts>
|
||||
<Enabled>1</Enabled>
|
||||
<Irq0>_ 0 9999 0 9999 1 0 0 100 0 1 "SysTick 1 0x3C"</Irq0>
|
||||
<Count>1</Count>
|
||||
</Interrupts>
|
||||
<MemConfig>
|
||||
<Base>1</Base>
|
||||
<Manual>0</Manual>
|
||||
<Ddf>1</Ddf>
|
||||
<TypeViol>0</TypeViol>
|
||||
<Stop>1</Stop>
|
||||
</MemConfig>
|
||||
<Aliases>
|
||||
<Count>0</Count>
|
||||
<SuppressDialog>0</SuppressDialog>
|
||||
</Aliases>
|
||||
<Simulator>
|
||||
<Freq>10000000</Freq>
|
||||
<FreqHi>0</FreqHi>
|
||||
<MultiCoreRunAll>1</MultiCoreRunAll>
|
||||
</Simulator>
|
||||
</settings>
|
||||
@@ -0,0 +1,40 @@
|
||||
@REM This batch file has been generated by the IAR Embedded Workbench
|
||||
@REM C-SPY Debugger, as an aid to preparing a command line for running
|
||||
@REM the cspybat command line utility using the appropriate settings.
|
||||
@REM
|
||||
@REM Note that this file is generated every time a new debug session
|
||||
@REM is initialized, so you may want to move or rename the file before
|
||||
@REM making changes.
|
||||
@REM
|
||||
@REM You can launch cspybat by typing the name of this batch file followed
|
||||
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
|
||||
@REM
|
||||
@REM Read about available command line parameters in the C-SPY Debugging
|
||||
@REM Guide. Hints about additional command line parameters that may be
|
||||
@REM useful in specific cases:
|
||||
@REM --download_only Downloads a code image without starting a debug
|
||||
@REM session afterwards.
|
||||
@REM --silent Omits the sign-on message.
|
||||
@REM --timeout Limits the maximum allowed execution time.
|
||||
@REM
|
||||
|
||||
|
||||
@echo off
|
||||
|
||||
if not "%~1" == "" goto debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
goto end
|
||||
|
||||
:debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
:end
|
||||
@@ -0,0 +1,31 @@
|
||||
param([String]$debugfile = "");
|
||||
|
||||
# This powershell file has been generated by the IAR Embedded Workbench
|
||||
# C - SPY Debugger, as an aid to preparing a command line for running
|
||||
# the cspybat command line utility using the appropriate settings.
|
||||
#
|
||||
# Note that this file is generated every time a new debug session
|
||||
# is initialized, so you may want to move or rename the file before
|
||||
# making changes.
|
||||
#
|
||||
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
|
||||
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
|
||||
#
|
||||
# Read about available command line parameters in the C - SPY Debugging
|
||||
# Guide. Hints about additional command line parameters that may be
|
||||
# useful in specific cases :
|
||||
# --download_only Downloads a code image without starting a debug
|
||||
# session afterwards.
|
||||
# --silent Omits the sign - on message.
|
||||
# --timeout Limits the maximum allowed execution time.
|
||||
#
|
||||
|
||||
|
||||
if ($debugfile -eq "")
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.driver.xcl"
|
||||
}
|
||||
else
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module.Debug.driver.xcl"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
"--endian=little"
|
||||
|
||||
"--cpu=Cortex-M3"
|
||||
|
||||
"--fpu=None"
|
||||
|
||||
"--semihosting"
|
||||
|
||||
"--multicore_nr_of_cores=1"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armproc.dll"
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armsim2.dll"
|
||||
|
||||
"C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\Debug\Exe\sample_threadx_module_stm32f4xx.out"
|
||||
|
||||
--plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armbat.dll"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<crun>
|
||||
<version>1</version>
|
||||
<filter_entries>
|
||||
<filter index="0" type="default">
|
||||
<type>*</type>
|
||||
<start_file>*</start_file>
|
||||
<end_file>*</end_file>
|
||||
<action_debugger>0</action_debugger>
|
||||
<action_log>1</action_log>
|
||||
</filter>
|
||||
</filter_entries>
|
||||
</crun>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Project>
|
||||
<WindowStorage />
|
||||
</Project>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
<InterruptLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
<SumSortOrder>0</SumSortOrder>
|
||||
</InterruptLog>
|
||||
<DataLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
</DataLog>
|
||||
<Stack>
|
||||
<FillEnabled>0</FillEnabled>
|
||||
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
|
||||
<WarningThreshold>90</WarningThreshold>
|
||||
<SpWarningsEnabled>1</SpWarningsEnabled>
|
||||
<WarnLogOnly>1</WarnLogOnly>
|
||||
<UseTrigger>1</UseTrigger>
|
||||
<TriggerName>main</TriggerName>
|
||||
<LimitSize>0</LimitSize>
|
||||
<ByteLimit>50</ByteLimit>
|
||||
</Stack>
|
||||
<DisassembleMode>
|
||||
<mode>0</mode>
|
||||
</DisassembleMode>
|
||||
<Breakpoints2>
|
||||
<Count>0</Count>
|
||||
</Breakpoints2>
|
||||
<Interrupts>
|
||||
<Enabled>1</Enabled>
|
||||
</Interrupts>
|
||||
<MemConfig>
|
||||
<Base>1</Base>
|
||||
<Manual>0</Manual>
|
||||
<Ddf>1</Ddf>
|
||||
<TypeViol>0</TypeViol>
|
||||
<Stop>1</Stop>
|
||||
</MemConfig>
|
||||
<Trace1>
|
||||
<Enabled>0</Enabled>
|
||||
<ShowSource>1</ShowSource>
|
||||
</Trace1>
|
||||
<Aliases>
|
||||
<Count>0</Count>
|
||||
<SuppressDialog>0</SuppressDialog>
|
||||
</Aliases>
|
||||
<Simulator>
|
||||
<Freq>10000000</Freq>
|
||||
<FreqHi>0</FreqHi>
|
||||
<MultiCoreRunAll>1</MultiCoreRunAll>
|
||||
</Simulator>
|
||||
</settings>
|
||||
@@ -0,0 +1,40 @@
|
||||
@REM This batch file has been generated by the IAR Embedded Workbench
|
||||
@REM C-SPY Debugger, as an aid to preparing a command line for running
|
||||
@REM the cspybat command line utility using the appropriate settings.
|
||||
@REM
|
||||
@REM Note that this file is generated every time a new debug session
|
||||
@REM is initialized, so you may want to move or rename the file before
|
||||
@REM making changes.
|
||||
@REM
|
||||
@REM You can launch cspybat by typing the name of this batch file followed
|
||||
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
|
||||
@REM
|
||||
@REM Read about available command line parameters in the C-SPY Debugging
|
||||
@REM Guide. Hints about additional command line parameters that may be
|
||||
@REM useful in specific cases:
|
||||
@REM --download_only Downloads a code image without starting a debug
|
||||
@REM session afterwards.
|
||||
@REM --silent Omits the sign-on message.
|
||||
@REM --timeout Limits the maximum allowed execution time.
|
||||
@REM
|
||||
|
||||
|
||||
@echo off
|
||||
|
||||
if not "%~1" == "" goto debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
goto end
|
||||
|
||||
:debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
:end
|
||||
@@ -0,0 +1,31 @@
|
||||
param([String]$debugfile = "");
|
||||
|
||||
# This powershell file has been generated by the IAR Embedded Workbench
|
||||
# C - SPY Debugger, as an aid to preparing a command line for running
|
||||
# the cspybat command line utility using the appropriate settings.
|
||||
#
|
||||
# Note that this file is generated every time a new debug session
|
||||
# is initialized, so you may want to move or rename the file before
|
||||
# making changes.
|
||||
#
|
||||
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
|
||||
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
|
||||
#
|
||||
# Read about available command line parameters in the C - SPY Debugging
|
||||
# Guide. Hints about additional command line parameters that may be
|
||||
# useful in specific cases :
|
||||
# --download_only Downloads a code image without starting a debug
|
||||
# session afterwards.
|
||||
# --silent Omits the sign - on message.
|
||||
# --timeout Limits the maximum allowed execution time.
|
||||
#
|
||||
|
||||
|
||||
if ($debugfile -eq "")
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.driver.xcl"
|
||||
}
|
||||
else
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\sample_threadx_module_manager.Debug.driver.xcl"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
"--endian=little"
|
||||
|
||||
"--cpu=Cortex-M3"
|
||||
|
||||
"--fpu=None"
|
||||
|
||||
"-p"
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\CONFIG\debugger\ST\STM32F217IG.ddf"
|
||||
|
||||
"--semihosting"
|
||||
|
||||
"--device=STM32F217IG"
|
||||
|
||||
"--multicore_nr_of_cores=1"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armproc.dll"
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armsim2.dll"
|
||||
|
||||
"C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\Debug\Exe\sample_threadx_module_manager_stm32f4xx.out"
|
||||
|
||||
--plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armbat.dll"
|
||||
|
||||
--device_macro="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\config\debugger\ST\STM32F2xx.dmac"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<crun>
|
||||
<version>1</version>
|
||||
<filter_entries>
|
||||
<filter index="0" type="default">
|
||||
<type>*</type>
|
||||
<start_file>*</start_file>
|
||||
<end_file>*</end_file>
|
||||
<action_debugger>0</action_debugger>
|
||||
<action_log>1</action_log>
|
||||
</filter>
|
||||
</filter_entries>
|
||||
</crun>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
<Stack>
|
||||
<FillEnabled>0</FillEnabled>
|
||||
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
|
||||
<WarningThreshold>90</WarningThreshold>
|
||||
<SpWarningsEnabled>1</SpWarningsEnabled>
|
||||
<WarnLogOnly>1</WarnLogOnly>
|
||||
<UseTrigger>1</UseTrigger>
|
||||
<TriggerName>main</TriggerName>
|
||||
<LimitSize>0</LimitSize>
|
||||
<ByteLimit>50</ByteLimit>
|
||||
</Stack>
|
||||
<JLinkDriver>
|
||||
<CStepIntDis>_ 0</CStepIntDis>
|
||||
<LeaveTargetRunning>_ 0</LeaveTargetRunning>
|
||||
</JLinkDriver>
|
||||
<DebugChecksum>
|
||||
<Checksum>3269948375</Checksum>
|
||||
</DebugChecksum>
|
||||
<Disassembly>
|
||||
<InstrCount>0</InstrCount>
|
||||
<MixedMode>1</MixedMode>
|
||||
</Disassembly>
|
||||
<CodeCoverage>
|
||||
<Enabled>0</Enabled>
|
||||
<ShowSource>0</ShowSource>
|
||||
<HideCovered>0</HideCovered>
|
||||
</CodeCoverage>
|
||||
<Trace1>
|
||||
<Enabled>0</Enabled>
|
||||
<ShowSource>1</ShowSource>
|
||||
</Trace1>
|
||||
<Exceptions>
|
||||
<StopOnUncaught>_ 0</StopOnUncaught>
|
||||
<StopOnThrow>_ 0</StopOnThrow>
|
||||
</Exceptions>
|
||||
<CallStack>
|
||||
<ShowArgs>0</ShowArgs>
|
||||
</CallStack>
|
||||
<DriverProfiling>
|
||||
<Enabled>0</Enabled>
|
||||
<Mode>1</Mode>
|
||||
<Graph>0</Graph>
|
||||
<Symbiont>0</Symbiont>
|
||||
</DriverProfiling>
|
||||
<CallStackLog>
|
||||
<Enabled>0</Enabled>
|
||||
</CallStackLog>
|
||||
<CallStackStripe>
|
||||
<ShowTiming>1</ShowTiming>
|
||||
</CallStackStripe>
|
||||
<TermIOLog>
|
||||
<LoggingEnabled>_ 0</LoggingEnabled>
|
||||
<LogFile>_ ""</LogFile>
|
||||
</TermIOLog>
|
||||
<LogFile>
|
||||
<LoggingEnabled>_ 0</LoggingEnabled>
|
||||
<LogFile>_ ""</LogFile>
|
||||
<Category>_ 0</Category>
|
||||
</LogFile>
|
||||
<InterruptLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
<SumSortOrder>0</SumSortOrder>
|
||||
</InterruptLog>
|
||||
<DataLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
</DataLog>
|
||||
<DisassembleMode>
|
||||
<mode>0</mode>
|
||||
</DisassembleMode>
|
||||
<Breakpoints2>
|
||||
<Count>0</Count>
|
||||
</Breakpoints2>
|
||||
<Interrupts>
|
||||
<Enabled>1</Enabled>
|
||||
<Irq0>_ 0 10000 0 10000 1 0 0 100 0 1 "SysTick 1 0x3C"</Irq0>
|
||||
<Count>1</Count>
|
||||
</Interrupts>
|
||||
<MemConfig>
|
||||
<Base>1</Base>
|
||||
<Manual>0</Manual>
|
||||
<Ddf>1</Ddf>
|
||||
<TypeViol>0</TypeViol>
|
||||
<Stop>1</Stop>
|
||||
</MemConfig>
|
||||
<Aliases>
|
||||
<A0>_ "C:\Users\nisohack\Documents\work\tasks\st_work\threadx_07242020_rc2\ports_module\cortex-m3\iar\example_build\sample_threadx_module_stm32f2xx.c" ""</A0>
|
||||
<Count>1</Count>
|
||||
<SuppressDialog>0</SuppressDialog>
|
||||
</Aliases>
|
||||
<Simulator>
|
||||
<Freq>10000000</Freq>
|
||||
<FreqHi>0</FreqHi>
|
||||
<MultiCoreRunAll>1</MultiCoreRunAll>
|
||||
</Simulator>
|
||||
</settings>
|
||||
@@ -0,0 +1,40 @@
|
||||
@REM This batch file has been generated by the IAR Embedded Workbench
|
||||
@REM C-SPY Debugger, as an aid to preparing a command line for running
|
||||
@REM the cspybat command line utility using the appropriate settings.
|
||||
@REM
|
||||
@REM Note that this file is generated every time a new debug session
|
||||
@REM is initialized, so you may want to move or rename the file before
|
||||
@REM making changes.
|
||||
@REM
|
||||
@REM You can launch cspybat by typing the name of this batch file followed
|
||||
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
|
||||
@REM
|
||||
@REM Read about available command line parameters in the C-SPY Debugging
|
||||
@REM Guide. Hints about additional command line parameters that may be
|
||||
@REM useful in specific cases:
|
||||
@REM --download_only Downloads a code image without starting a debug
|
||||
@REM session afterwards.
|
||||
@REM --silent Omits the sign-on message.
|
||||
@REM --timeout Limits the maximum allowed execution time.
|
||||
@REM
|
||||
|
||||
|
||||
@echo off
|
||||
|
||||
if not "%~1" == "" goto debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
goto end
|
||||
|
||||
:debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
:end
|
||||
@@ -0,0 +1,31 @@
|
||||
param([String]$debugfile = "");
|
||||
|
||||
# This powershell file has been generated by the IAR Embedded Workbench
|
||||
# C - SPY Debugger, as an aid to preparing a command line for running
|
||||
# the cspybat command line utility using the appropriate settings.
|
||||
#
|
||||
# Note that this file is generated every time a new debug session
|
||||
# is initialized, so you may want to move or rename the file before
|
||||
# making changes.
|
||||
#
|
||||
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
|
||||
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
|
||||
#
|
||||
# Read about available command line parameters in the C - SPY Debugging
|
||||
# Guide. Hints about additional command line parameters that may be
|
||||
# useful in specific cases :
|
||||
# --download_only Downloads a code image without starting a debug
|
||||
# session afterwards.
|
||||
# --silent Omits the sign - on message.
|
||||
# --timeout Limits the maximum allowed execution time.
|
||||
#
|
||||
|
||||
|
||||
if ($debugfile -eq "")
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
|
||||
}
|
||||
else
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
"--endian=little"
|
||||
|
||||
"--cpu=Cortex-M3"
|
||||
|
||||
"--fpu=None"
|
||||
|
||||
"--semihosting"
|
||||
|
||||
"--multicore_nr_of_cores=1"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\bin\armproc.dll"
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\bin\armsim2.dll"
|
||||
|
||||
"C:\release\threadx\Debug\Exe\tx.out"
|
||||
|
||||
--plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\bin\armbat.dll"
|
||||
|
||||
|
||||
|
||||
|
||||
13
ports_module/cortex-m3/iar/example_build/settings/tx.crun
Normal file
13
ports_module/cortex-m3/iar/example_build/settings/tx.crun
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<crun>
|
||||
<version>1</version>
|
||||
<filter_entries>
|
||||
<filter index="0" type="default">
|
||||
<type>*</type>
|
||||
<start_file>*</start_file>
|
||||
<end_file>*</end_file>
|
||||
<action_debugger>0</action_debugger>
|
||||
<action_log>1</action_log>
|
||||
</filter>
|
||||
</filter_entries>
|
||||
</crun>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<Project>
|
||||
<WindowStorage />
|
||||
</Project>
|
||||
58
ports_module/cortex-m3/iar/example_build/settings/tx.dnx
Normal file
58
ports_module/cortex-m3/iar/example_build/settings/tx.dnx
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
<Stack>
|
||||
<FillEnabled>0</FillEnabled>
|
||||
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
|
||||
<WarningThreshold>90</WarningThreshold>
|
||||
<SpWarningsEnabled>1</SpWarningsEnabled>
|
||||
<WarnLogOnly>1</WarnLogOnly>
|
||||
<UseTrigger>1</UseTrigger>
|
||||
<TriggerName>main</TriggerName>
|
||||
<LimitSize>0</LimitSize>
|
||||
<ByteLimit>50</ByteLimit>
|
||||
</Stack>
|
||||
<Trace1>
|
||||
<Enabled>0</Enabled>
|
||||
<ShowSource>1</ShowSource>
|
||||
</Trace1>
|
||||
<InterruptLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
<SumSortOrder>0</SumSortOrder>
|
||||
</InterruptLog>
|
||||
<DataLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
</DataLog>
|
||||
<DisassembleMode>
|
||||
<mode>0</mode>
|
||||
</DisassembleMode>
|
||||
<Breakpoints2>
|
||||
<Count>0</Count>
|
||||
</Breakpoints2>
|
||||
<Interrupts>
|
||||
<Enabled>1</Enabled>
|
||||
</Interrupts>
|
||||
<MemConfig>
|
||||
<Base>1</Base>
|
||||
<Manual>0</Manual>
|
||||
<Ddf>1</Ddf>
|
||||
<TypeViol>0</TypeViol>
|
||||
<Stop>1</Stop>
|
||||
</MemConfig>
|
||||
<Aliases>
|
||||
<Count>0</Count>
|
||||
<SuppressDialog>0</SuppressDialog>
|
||||
</Aliases>
|
||||
<Simulator>
|
||||
<Freq>10000000</Freq>
|
||||
<FreqHi>0</FreqHi>
|
||||
<MultiCoreRunAll>1</MultiCoreRunAll>
|
||||
</Simulator>
|
||||
</settings>
|
||||
@@ -0,0 +1,40 @@
|
||||
@REM This batch file has been generated by the IAR Embedded Workbench
|
||||
@REM C-SPY Debugger, as an aid to preparing a command line for running
|
||||
@REM the cspybat command line utility using the appropriate settings.
|
||||
@REM
|
||||
@REM Note that this file is generated every time a new debug session
|
||||
@REM is initialized, so you may want to move or rename the file before
|
||||
@REM making changes.
|
||||
@REM
|
||||
@REM You can launch cspybat by typing the name of this batch file followed
|
||||
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
|
||||
@REM
|
||||
@REM Read about available command line parameters in the C-SPY Debugging
|
||||
@REM Guide. Hints about additional command line parameters that may be
|
||||
@REM useful in specific cases:
|
||||
@REM --download_only Downloads a code image without starting a debug
|
||||
@REM session afterwards.
|
||||
@REM --silent Omits the sign-on message.
|
||||
@REM --timeout Limits the maximum allowed execution time.
|
||||
@REM
|
||||
|
||||
|
||||
@echo off
|
||||
|
||||
if not "%~1" == "" goto debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
goto end
|
||||
|
||||
:debugFile
|
||||
|
||||
@echo on
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.driver.xcl"
|
||||
|
||||
@echo off
|
||||
:end
|
||||
@@ -0,0 +1,31 @@
|
||||
param([String]$debugfile = "");
|
||||
|
||||
# This powershell file has been generated by the IAR Embedded Workbench
|
||||
# C - SPY Debugger, as an aid to preparing a command line for running
|
||||
# the cspybat command line utility using the appropriate settings.
|
||||
#
|
||||
# Note that this file is generated every time a new debug session
|
||||
# is initialized, so you may want to move or rename the file before
|
||||
# making changes.
|
||||
#
|
||||
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
|
||||
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
|
||||
#
|
||||
# Read about available command line parameters in the C - SPY Debugging
|
||||
# Guide. Hints about additional command line parameters that may be
|
||||
# useful in specific cases :
|
||||
# --download_only Downloads a code image without starting a debug
|
||||
# session afterwards.
|
||||
# --silent Omits the sign - on message.
|
||||
# --timeout Limits the maximum allowed execution time.
|
||||
#
|
||||
|
||||
|
||||
if ($debugfile -eq "")
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.driver.xcl"
|
||||
}
|
||||
else
|
||||
{
|
||||
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\settings\txm.Debug.driver.xcl"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
"--endian=little"
|
||||
|
||||
"--cpu=Cortex-M3"
|
||||
|
||||
"--fpu=None"
|
||||
|
||||
"--semihosting"
|
||||
|
||||
"--multicore_nr_of_cores=1"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armproc.dll"
|
||||
|
||||
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armsim2.dll"
|
||||
|
||||
"C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_module\cortex-m3\iar\example_build\Debug\Exe\txm.out"
|
||||
|
||||
--plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armbat.dll"
|
||||
|
||||
|
||||
|
||||
|
||||
13
ports_module/cortex-m3/iar/example_build/settings/txm.crun
Normal file
13
ports_module/cortex-m3/iar/example_build/settings/txm.crun
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<crun>
|
||||
<version>1</version>
|
||||
<filter_entries>
|
||||
<filter index="0" type="default">
|
||||
<type>*</type>
|
||||
<start_file>*</start_file>
|
||||
<end_file>*</end_file>
|
||||
<action_debugger>0</action_debugger>
|
||||
<action_log>1</action_log>
|
||||
</filter>
|
||||
</filter_entries>
|
||||
</crun>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Project>
|
||||
<WindowStorage />
|
||||
</Project>
|
||||
58
ports_module/cortex-m3/iar/example_build/settings/txm.dnx
Normal file
58
ports_module/cortex-m3/iar/example_build/settings/txm.dnx
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
<InterruptLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
<SumSortOrder>0</SumSortOrder>
|
||||
</InterruptLog>
|
||||
<DataLog>
|
||||
<LogEnabled>0</LogEnabled>
|
||||
<GraphEnabled>0</GraphEnabled>
|
||||
<ShowTimeLog>1</ShowTimeLog>
|
||||
<SumEnabled>0</SumEnabled>
|
||||
<ShowTimeSum>1</ShowTimeSum>
|
||||
</DataLog>
|
||||
<Stack>
|
||||
<FillEnabled>0</FillEnabled>
|
||||
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
|
||||
<WarningThreshold>90</WarningThreshold>
|
||||
<SpWarningsEnabled>1</SpWarningsEnabled>
|
||||
<WarnLogOnly>1</WarnLogOnly>
|
||||
<UseTrigger>1</UseTrigger>
|
||||
<TriggerName>main</TriggerName>
|
||||
<LimitSize>0</LimitSize>
|
||||
<ByteLimit>50</ByteLimit>
|
||||
</Stack>
|
||||
<DisassembleMode>
|
||||
<mode>0</mode>
|
||||
</DisassembleMode>
|
||||
<Breakpoints2>
|
||||
<Count>0</Count>
|
||||
</Breakpoints2>
|
||||
<Interrupts>
|
||||
<Enabled>1</Enabled>
|
||||
</Interrupts>
|
||||
<MemConfig>
|
||||
<Base>1</Base>
|
||||
<Manual>0</Manual>
|
||||
<Ddf>1</Ddf>
|
||||
<TypeViol>0</TypeViol>
|
||||
<Stop>1</Stop>
|
||||
</MemConfig>
|
||||
<Trace1>
|
||||
<Enabled>0</Enabled>
|
||||
<ShowSource>1</ShowSource>
|
||||
</Trace1>
|
||||
<Aliases>
|
||||
<Count>0</Count>
|
||||
<SuppressDialog>0</SuppressDialog>
|
||||
</Aliases>
|
||||
<Simulator>
|
||||
<Freq>10000000</Freq>
|
||||
<FreqHi>0</FreqHi>
|
||||
<MultiCoreRunAll>1</MultiCoreRunAll>
|
||||
</Simulator>
|
||||
</settings>
|
||||
622
ports_module/cortex-m3/iar/example_build/startup.s
Normal file
622
ports_module/cortex-m3/iar/example_build/startup.s
Normal file
@@ -0,0 +1,622 @@
|
||||
;/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
|
||||
;* File Name : startup.s
|
||||
;* Author : MCD Application Team
|
||||
;* Version : V1.0.0
|
||||
;* Date : 18-April-2011
|
||||
;* Description : STM32F2xx devices vector table for EWARM toolchain.
|
||||
;* This module performs:
|
||||
;* - Set the initial SP
|
||||
;* - Configure he external SRAM mounted on STM322xG-EVAL board
|
||||
;* to be used as data memory (optional, to be enabled by user)
|
||||
;* - Set the initial PC == __iar_program_start,
|
||||
;* - Set the vector table entries with the exceptions ISR
|
||||
;* address.
|
||||
;* After Reset the Cortex-M3 processor is in Thread mode,
|
||||
;* priority is Privileged, and the Stack is set to Main.
|
||||
;********************************************************************************
|
||||
;* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
;* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
;* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
;* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
;* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
;* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
;*******************************************************************************/
|
||||
;
|
||||
;
|
||||
; The modules in this file are included in the libraries, and may be replaced
|
||||
; by any user-defined modules that define the PUBLIC symbol _program_start or
|
||||
; a user defined start symbol.
|
||||
; To override the cstartup defined in the library, simply add your modified
|
||||
; version to the workbench project.
|
||||
;
|
||||
; The vector table is normally located at address 0.
|
||||
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
|
||||
; The name "__vector_table" has special meaning for C-SPY:
|
||||
; it is where the SP start value is found, and the NVIC vector
|
||||
; table register (VTOR) is initialized to this address if != 0.
|
||||
;
|
||||
; Cortex-M version
|
||||
;
|
||||
|
||||
__initial_spTop EQU 0x20000400 ; stack used for SystemInit & SystemInit_ExtMemCtl
|
||||
|
||||
MODULE ?cstartup
|
||||
|
||||
;; Forward declaration of sections.
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
|
||||
SECTION .intvec:CODE:NOROOT(2)
|
||||
|
||||
EXTERN __iar_program_start
|
||||
EXTERN SystemInit
|
||||
PUBLIC __vector_table
|
||||
|
||||
DATA
|
||||
__vector_table
|
||||
DCD __initial_spTop ; Use internal RAM for stack for calling SystemInit
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
|
||||
DC32 NMI_Handler ; NMI
|
||||
DC32 HardFault_Handler ; HardFault
|
||||
DC32 MemManage_Handler ; MemManage
|
||||
DC32 0 ; BusFault
|
||||
DC32 0 ; UsageFault
|
||||
DC32 0 ; 7
|
||||
DC32 0 ; 8
|
||||
DC32 0 ; 9
|
||||
DC32 0 ; 10
|
||||
DC32 SVC_Handler ; SVCall
|
||||
DC32 DebugMon_Handler ; Monitor
|
||||
DC32 0 ; 13
|
||||
DC32 PendSV_Handler ; PendSV
|
||||
DC32 SysTick_Handler ; SysTick
|
||||
|
||||
; External Interrupts
|
||||
DCD WWDG_IRQHandler ; Window WatchDog
|
||||
DCD PVD_IRQHandler ; PVD through EXTI Line detection
|
||||
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line
|
||||
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line
|
||||
DCD FLASH_IRQHandler ; FLASH
|
||||
DCD RCC_IRQHandler ; RCC
|
||||
DCD EXTI0_IRQHandler ; EXTI Line0
|
||||
DCD EXTI1_IRQHandler ; EXTI Line1
|
||||
DCD EXTI2_IRQHandler ; EXTI Line2
|
||||
DCD EXTI3_IRQHandler ; EXTI Line3
|
||||
DCD EXTI4_IRQHandler ; EXTI Line4
|
||||
DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0
|
||||
DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1
|
||||
DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2
|
||||
DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3
|
||||
DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4
|
||||
DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5
|
||||
DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6
|
||||
DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s
|
||||
DCD CAN1_TX_IRQHandler ; CAN1 TX
|
||||
DCD CAN1_RX0_IRQHandler ; CAN1 RX0
|
||||
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
|
||||
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
|
||||
DCD EXTI9_5_IRQHandler ; External Line[9:5]s
|
||||
DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
|
||||
DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
|
||||
DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
|
||||
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
|
||||
DCD TIM2_IRQHandler ; TIM2
|
||||
DCD TIM3_IRQHandler ; TIM3
|
||||
DCD TIM4_IRQHandler ; TIM4
|
||||
DCD I2C1_EV_IRQHandler ; I2C1 Event
|
||||
DCD I2C1_ER_IRQHandler ; I2C1 Error
|
||||
DCD I2C2_EV_IRQHandler ; I2C2 Event
|
||||
DCD I2C2_ER_IRQHandler ; I2C2 Error
|
||||
DCD SPI1_IRQHandler ; SPI1
|
||||
DCD SPI2_IRQHandler ; SPI2
|
||||
DCD USART1_IRQHandler ; USART1
|
||||
DCD USART2_IRQHandler ; USART2
|
||||
DCD USART3_IRQHandler ; USART3
|
||||
DCD EXTI15_10_IRQHandler ; External Line[15:10]s
|
||||
DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line
|
||||
DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
|
||||
DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12
|
||||
DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13
|
||||
DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14
|
||||
DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
|
||||
DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7
|
||||
DCD FSMC_IRQHandler ; FSMC
|
||||
DCD SDIO_IRQHandler ; SDIO
|
||||
DCD TIM5_IRQHandler ; TIM5
|
||||
DCD SPI3_IRQHandler ; SPI3
|
||||
DCD UART4_IRQHandler ; UART4
|
||||
DCD UART5_IRQHandler ; UART5
|
||||
DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors
|
||||
DCD TIM7_IRQHandler ; TIM7
|
||||
DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0
|
||||
DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1
|
||||
DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2
|
||||
DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3
|
||||
DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4
|
||||
DCD ETH_IRQHandler ; Ethernet
|
||||
DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line
|
||||
DCD CAN2_TX_IRQHandler ; CAN2 TX
|
||||
DCD CAN2_RX0_IRQHandler ; CAN2 RX0
|
||||
DCD CAN2_RX1_IRQHandler ; CAN2 RX1
|
||||
DCD CAN2_SCE_IRQHandler ; CAN2 SCE
|
||||
DCD OTG_FS_IRQHandler ; USB OTG FS
|
||||
DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5
|
||||
DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6
|
||||
DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7
|
||||
DCD USART6_IRQHandler ; USART6
|
||||
DCD I2C3_EV_IRQHandler ; I2C3 event
|
||||
DCD I2C3_ER_IRQHandler ; I2C3 error
|
||||
DCD OTG_HS_EP1_OUT_IRQHandler ; USB OTG HS End Point 1 Out
|
||||
DCD OTG_HS_EP1_IN_IRQHandler ; USB OTG HS End Point 1 In
|
||||
DCD OTG_HS_WKUP_IRQHandler ; USB OTG HS Wakeup through EXTI
|
||||
DCD OTG_HS_IRQHandler ; USB OTG HS
|
||||
DCD DCMI_IRQHandler ; DCMI
|
||||
DCD CRYP_IRQHandler ; CRYP crypto
|
||||
DCD HASH_RNG_IRQHandler ; Hash and Rng
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Default interrupt handlers.
|
||||
;;
|
||||
THUMB
|
||||
PUBWEAK Reset_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
Reset_Handler
|
||||
CPSID i ; Disable interrupts
|
||||
LDR R0, =sfe(CSTACK) ; restore original stack pointer
|
||||
MSR MSP, R0
|
||||
LDR R0, =__iar_program_start ; Jump to ThreadX start, which will call IAR startup code
|
||||
BX R0
|
||||
|
||||
PUBWEAK NMI_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
NMI_Handler
|
||||
B NMI_Handler
|
||||
|
||||
PUBWEAK HardFault_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
HardFault_Handler
|
||||
B HardFault_Handler
|
||||
|
||||
PUBWEAK MemManage_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
MemManage_Handler
|
||||
B MemManage_Handler
|
||||
|
||||
PUBWEAK BusFault_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
BusFault_Handler
|
||||
B BusFault_Handler
|
||||
|
||||
PUBWEAK UsageFault_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
UsageFault_Handler
|
||||
B UsageFault_Handler
|
||||
|
||||
PUBWEAK SVC_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
SVC_Handler
|
||||
B SVC_Handler
|
||||
|
||||
PUBWEAK DebugMon_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DebugMon_Handler
|
||||
B DebugMon_Handler
|
||||
|
||||
PUBWEAK PendSV_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
PendSV_Handler
|
||||
B PendSV_Handler
|
||||
|
||||
PUBWEAK SysTick_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
SysTick_Handler
|
||||
B SysTick_Handler
|
||||
|
||||
PUBWEAK WWDG_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
WWDG_IRQHandler
|
||||
B WWDG_IRQHandler
|
||||
|
||||
PUBWEAK PVD_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
PVD_IRQHandler
|
||||
B PVD_IRQHandler
|
||||
|
||||
PUBWEAK TAMP_STAMP_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TAMP_STAMP_IRQHandler
|
||||
B TAMP_STAMP_IRQHandler
|
||||
|
||||
PUBWEAK RTC_WKUP_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
RTC_WKUP_IRQHandler
|
||||
B RTC_WKUP_IRQHandler
|
||||
|
||||
PUBWEAK FLASH_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
FLASH_IRQHandler
|
||||
B FLASH_IRQHandler
|
||||
|
||||
PUBWEAK RCC_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
RCC_IRQHandler
|
||||
B RCC_IRQHandler
|
||||
|
||||
PUBWEAK EXTI0_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
EXTI0_IRQHandler
|
||||
B EXTI0_IRQHandler
|
||||
|
||||
PUBWEAK EXTI1_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
EXTI1_IRQHandler
|
||||
B EXTI1_IRQHandler
|
||||
|
||||
PUBWEAK EXTI2_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
EXTI2_IRQHandler
|
||||
B EXTI2_IRQHandler
|
||||
|
||||
PUBWEAK EXTI3_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
EXTI3_IRQHandler
|
||||
B EXTI3_IRQHandler
|
||||
|
||||
PUBWEAK EXTI4_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
EXTI4_IRQHandler
|
||||
B EXTI4_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream0_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream0_IRQHandler
|
||||
B DMA1_Stream0_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream1_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream1_IRQHandler
|
||||
B DMA1_Stream1_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream2_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream2_IRQHandler
|
||||
B DMA1_Stream2_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream3_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream3_IRQHandler
|
||||
B DMA1_Stream3_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream4_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream4_IRQHandler
|
||||
B DMA1_Stream4_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream5_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream5_IRQHandler
|
||||
B DMA1_Stream5_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream6_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream6_IRQHandler
|
||||
B DMA1_Stream6_IRQHandler
|
||||
|
||||
PUBWEAK ADC_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
ADC_IRQHandler
|
||||
B ADC_IRQHandler
|
||||
|
||||
PUBWEAK CAN1_TX_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN1_TX_IRQHandler
|
||||
B CAN1_TX_IRQHandler
|
||||
|
||||
PUBWEAK CAN1_RX0_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN1_RX0_IRQHandler
|
||||
B CAN1_RX0_IRQHandler
|
||||
|
||||
PUBWEAK CAN1_RX1_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN1_RX1_IRQHandler
|
||||
B CAN1_RX1_IRQHandler
|
||||
|
||||
PUBWEAK CAN1_SCE_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN1_SCE_IRQHandler
|
||||
B CAN1_SCE_IRQHandler
|
||||
|
||||
PUBWEAK EXTI9_5_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
EXTI9_5_IRQHandler
|
||||
B EXTI9_5_IRQHandler
|
||||
|
||||
PUBWEAK TIM1_BRK_TIM9_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM1_BRK_TIM9_IRQHandler
|
||||
B TIM1_BRK_TIM9_IRQHandler
|
||||
|
||||
PUBWEAK TIM1_UP_TIM10_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM1_UP_TIM10_IRQHandler
|
||||
B TIM1_UP_TIM10_IRQHandler
|
||||
|
||||
PUBWEAK TIM1_TRG_COM_TIM11_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM1_TRG_COM_TIM11_IRQHandler
|
||||
B TIM1_TRG_COM_TIM11_IRQHandler
|
||||
|
||||
PUBWEAK TIM1_CC_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM1_CC_IRQHandler
|
||||
B TIM1_CC_IRQHandler
|
||||
|
||||
PUBWEAK TIM2_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM2_IRQHandler
|
||||
B TIM2_IRQHandler
|
||||
|
||||
PUBWEAK TIM3_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM3_IRQHandler
|
||||
B TIM3_IRQHandler
|
||||
|
||||
PUBWEAK TIM4_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM4_IRQHandler
|
||||
B TIM4_IRQHandler
|
||||
|
||||
PUBWEAK I2C1_EV_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
I2C1_EV_IRQHandler
|
||||
B I2C1_EV_IRQHandler
|
||||
|
||||
PUBWEAK I2C1_ER_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
I2C1_ER_IRQHandler
|
||||
B I2C1_ER_IRQHandler
|
||||
|
||||
PUBWEAK I2C2_EV_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
I2C2_EV_IRQHandler
|
||||
B I2C2_EV_IRQHandler
|
||||
|
||||
PUBWEAK I2C2_ER_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
I2C2_ER_IRQHandler
|
||||
B I2C2_ER_IRQHandler
|
||||
|
||||
PUBWEAK SPI1_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
SPI1_IRQHandler
|
||||
B SPI1_IRQHandler
|
||||
|
||||
PUBWEAK SPI2_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
SPI2_IRQHandler
|
||||
B SPI2_IRQHandler
|
||||
|
||||
PUBWEAK USART1_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
USART1_IRQHandler
|
||||
B USART1_IRQHandler
|
||||
|
||||
PUBWEAK USART2_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
USART2_IRQHandler
|
||||
B USART2_IRQHandler
|
||||
|
||||
PUBWEAK USART3_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
USART3_IRQHandler
|
||||
B USART3_IRQHandler
|
||||
|
||||
PUBWEAK EXTI15_10_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
EXTI15_10_IRQHandler
|
||||
B EXTI15_10_IRQHandler
|
||||
|
||||
PUBWEAK RTC_Alarm_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
RTC_Alarm_IRQHandler
|
||||
B RTC_Alarm_IRQHandler
|
||||
|
||||
PUBWEAK OTG_FS_WKUP_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
OTG_FS_WKUP_IRQHandler
|
||||
B OTG_FS_WKUP_IRQHandler
|
||||
|
||||
PUBWEAK TIM8_BRK_TIM12_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM8_BRK_TIM12_IRQHandler
|
||||
B TIM8_BRK_TIM12_IRQHandler
|
||||
|
||||
PUBWEAK TIM8_UP_TIM13_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM8_UP_TIM13_IRQHandler
|
||||
B TIM8_UP_TIM13_IRQHandler
|
||||
|
||||
PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM8_TRG_COM_TIM14_IRQHandler
|
||||
B TIM8_TRG_COM_TIM14_IRQHandler
|
||||
|
||||
PUBWEAK TIM8_CC_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM8_CC_IRQHandler
|
||||
B TIM8_CC_IRQHandler
|
||||
|
||||
PUBWEAK DMA1_Stream7_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA1_Stream7_IRQHandler
|
||||
B DMA1_Stream7_IRQHandler
|
||||
|
||||
PUBWEAK FSMC_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
FSMC_IRQHandler
|
||||
B FSMC_IRQHandler
|
||||
|
||||
PUBWEAK SDIO_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
SDIO_IRQHandler
|
||||
B SDIO_IRQHandler
|
||||
|
||||
PUBWEAK TIM5_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM5_IRQHandler
|
||||
B TIM5_IRQHandler
|
||||
|
||||
PUBWEAK SPI3_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
SPI3_IRQHandler
|
||||
B SPI3_IRQHandler
|
||||
|
||||
PUBWEAK UART4_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
UART4_IRQHandler
|
||||
B UART4_IRQHandler
|
||||
|
||||
PUBWEAK UART5_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
UART5_IRQHandler
|
||||
B UART5_IRQHandler
|
||||
|
||||
PUBWEAK TIM6_DAC_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM6_DAC_IRQHandler
|
||||
B TIM6_DAC_IRQHandler
|
||||
|
||||
PUBWEAK TIM7_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
TIM7_IRQHandler
|
||||
B TIM7_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream0_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream0_IRQHandler
|
||||
B DMA2_Stream0_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream1_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream1_IRQHandler
|
||||
B DMA2_Stream1_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream2_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream2_IRQHandler
|
||||
B DMA2_Stream2_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream3_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream3_IRQHandler
|
||||
B DMA2_Stream3_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream4_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream4_IRQHandler
|
||||
B DMA2_Stream4_IRQHandler
|
||||
|
||||
PUBWEAK ETH_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
ETH_IRQHandler
|
||||
B ETH_IRQHandler
|
||||
|
||||
PUBWEAK ETH_WKUP_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
ETH_WKUP_IRQHandler
|
||||
B ETH_WKUP_IRQHandler
|
||||
|
||||
PUBWEAK CAN2_TX_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN2_TX_IRQHandler
|
||||
B CAN2_TX_IRQHandler
|
||||
|
||||
PUBWEAK CAN2_RX0_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN2_RX0_IRQHandler
|
||||
B CAN2_RX0_IRQHandler
|
||||
|
||||
PUBWEAK CAN2_RX1_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN2_RX1_IRQHandler
|
||||
B CAN2_RX1_IRQHandler
|
||||
|
||||
PUBWEAK CAN2_SCE_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CAN2_SCE_IRQHandler
|
||||
B CAN2_SCE_IRQHandler
|
||||
|
||||
PUBWEAK OTG_FS_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
OTG_FS_IRQHandler
|
||||
B OTG_FS_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream5_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream5_IRQHandler
|
||||
B DMA2_Stream5_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream6_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream6_IRQHandler
|
||||
B DMA2_Stream6_IRQHandler
|
||||
|
||||
PUBWEAK DMA2_Stream7_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DMA2_Stream7_IRQHandler
|
||||
B DMA2_Stream7_IRQHandler
|
||||
|
||||
PUBWEAK USART6_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
USART6_IRQHandler
|
||||
B USART6_IRQHandler
|
||||
|
||||
PUBWEAK I2C3_EV_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
I2C3_EV_IRQHandler
|
||||
B I2C3_EV_IRQHandler
|
||||
|
||||
PUBWEAK I2C3_ER_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
I2C3_ER_IRQHandler
|
||||
B I2C3_ER_IRQHandler
|
||||
|
||||
PUBWEAK OTG_HS_EP1_OUT_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
OTG_HS_EP1_OUT_IRQHandler
|
||||
B OTG_HS_EP1_OUT_IRQHandler
|
||||
|
||||
PUBWEAK OTG_HS_EP1_IN_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
OTG_HS_EP1_IN_IRQHandler
|
||||
B OTG_HS_EP1_IN_IRQHandler
|
||||
|
||||
PUBWEAK OTG_HS_WKUP_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
OTG_HS_WKUP_IRQHandler
|
||||
B OTG_HS_WKUP_IRQHandler
|
||||
|
||||
PUBWEAK OTG_HS_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
OTG_HS_IRQHandler
|
||||
B OTG_HS_IRQHandler
|
||||
|
||||
PUBWEAK DCMI_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
DCMI_IRQHandler
|
||||
B DCMI_IRQHandler
|
||||
|
||||
PUBWEAK CRYP_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
CRYP_IRQHandler
|
||||
B CRYP_IRQHandler
|
||||
|
||||
PUBWEAK HASH_RNG_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
HASH_RNG_IRQHandler
|
||||
B HASH_RNG_IRQHandler
|
||||
|
||||
END
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
BIN
ports_module/cortex-m3/iar/example_build/stm32f2xx_library.a
Normal file
BIN
ports_module/cortex-m3/iar/example_build/stm32f2xx_library.a
Normal file
Binary file not shown.
2974
ports_module/cortex-m3/iar/example_build/tx.ewd
Normal file
2974
ports_module/cortex-m3/iar/example_build/tx.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2867
ports_module/cortex-m3/iar/example_build/tx.ewp
Normal file
2867
ports_module/cortex-m3/iar/example_build/tx.ewp
Normal file
File diff suppressed because it is too large
Load Diff
3514
ports_module/cortex-m3/iar/example_build/tx.ewt
Normal file
3514
ports_module/cortex-m3/iar/example_build/tx.ewt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the 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 */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_initialize.h"
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
;
|
||||
EXTERN _tx_thread_system_stack_ptr
|
||||
EXTERN _tx_initialize_unused_memory
|
||||
EXTERN _tx_timer_interrupt
|
||||
EXTERN __vector_table
|
||||
EXTERN _tx_execution_isr_enter
|
||||
EXTERN _tx_execution_isr_exit
|
||||
;
|
||||
;
|
||||
SYSTEM_CLOCK EQU 7200000
|
||||
SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 100) -1)
|
||||
|
||||
RSEG FREE_MEM:DATA
|
||||
PUBLIC __tx_free_memory_start
|
||||
__tx_free_memory_start
|
||||
DS32 4
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_initialize_low_level Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* William E. Lamie, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function is responsible for any low-level processor */
|
||||
;/* initialization, including setting up interrupt vectors, setting */
|
||||
;/* up a periodic timer interrupt source, saving the system stack */
|
||||
;/* pointer for use in ISR processing later, and finding the first */
|
||||
;/* available RAM memory address for tx_application_define. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_initialize_low_level(VOID)
|
||||
;{
|
||||
PUBLIC _tx_initialize_low_level
|
||||
_tx_initialize_low_level:
|
||||
;
|
||||
; /* Ensure that interrupts are disabled. */
|
||||
;
|
||||
CPSID i ; Disable interrupts
|
||||
;
|
||||
;
|
||||
; /* Set base of available memory to end of non-initialised RAM area. */
|
||||
;
|
||||
LDR r0, =__tx_free_memory_start ; Get end of non-initialized RAM area
|
||||
LDR r2, =_tx_initialize_unused_memory ; Build address of unused memory pointer
|
||||
STR r0, [r2, #0] ; Save first free memory address
|
||||
;
|
||||
; /* Enable the cycle count register. */
|
||||
;
|
||||
LDR r0, =0xE0001000 ; Build address of DWT register
|
||||
LDR r1, [r0] ; Pickup the current value
|
||||
ORR r1, r1, #1 ; Set the CYCCNTENA bit
|
||||
STR r1, [r0] ; Enable the cycle count register
|
||||
;
|
||||
; /* Setup Vector Table Offset Register. */
|
||||
;
|
||||
MOV r0, #0xE000E000 ; Build address of NVIC registers
|
||||
LDR r1, =__vector_table ; Pickup address of vector table
|
||||
STR r1, [r0, #0xD08] ; Set vector table address
|
||||
;
|
||||
; /* Set system stack pointer from vector value. */
|
||||
;
|
||||
LDR r0, =_tx_thread_system_stack_ptr ; Build address of system stack pointer
|
||||
LDR r1, =__vector_table ; Pickup address of vector table
|
||||
LDR r1, [r1] ; Pickup reset stack pointer
|
||||
STR r1, [r0] ; Save system stack pointer
|
||||
;
|
||||
; /* Configure SysTick. */
|
||||
;
|
||||
MOV r0, #0xE000E000 ; Build address of NVIC registers
|
||||
LDR r1, =SYSTICK_CYCLES
|
||||
STR r1, [r0, #0x14] ; Setup SysTick Reload Value
|
||||
MOV r1, #0x7 ; Build SysTick Control Enable Value
|
||||
STR r1, [r0, #0x10] ; Setup SysTick Control
|
||||
;
|
||||
; /* Configure handler priorities. */
|
||||
;
|
||||
LDR r1, =0x00000000 ; Rsrv, UsgF, BusF, MemM
|
||||
STR r1, [r0, #0xD18] ; Setup System Handlers 4-7 Priority Registers
|
||||
|
||||
LDR r1, =0xFF000000 ; SVCl, Rsrv, Rsrv, Rsrv
|
||||
STR r1, [r0, #0xD1C] ; Setup System Handlers 8-11 Priority Registers
|
||||
; Note: SVC must be lowest priority, which is 0xFF
|
||||
|
||||
LDR r1, =0x40FF0000 ; SysT, PnSV, Rsrv, DbgM
|
||||
STR r1, [r0, #0xD20] ; Setup System Handlers 12-15 Priority Registers
|
||||
; Note: PnSV must be lowest priority, which is 0xFF
|
||||
;
|
||||
; /* Return to caller. */
|
||||
;
|
||||
BX lr
|
||||
;}
|
||||
;
|
||||
;
|
||||
;/* Define SystTick Handler. */
|
||||
;
|
||||
|
||||
PUBLIC SysTick_Handler
|
||||
PUBLIC __tx_SysTickHandler
|
||||
SysTick_Handler:
|
||||
__tx_SysTickHandler:
|
||||
; VOID SysTickHandler (VOID)
|
||||
; {
|
||||
;
|
||||
PUSH {r0, lr}
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
BL _tx_execution_isr_enter ; Call the ISR enter function
|
||||
#endif
|
||||
BL _tx_timer_interrupt
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
BL _tx_execution_isr_exit ; Call the ISR exit function
|
||||
#endif
|
||||
POP {r0, lr}
|
||||
BX LR
|
||||
; }
|
||||
|
||||
END
|
||||
|
||||
|
||||
2974
ports_module/cortex-m3/iar/example_build/txm.ewd
Normal file
2974
ports_module/cortex-m3/iar/example_build/txm.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2477
ports_module/cortex-m3/iar/example_build/txm.ewp
Normal file
2477
ports_module/cortex-m3/iar/example_build/txm.ewp
Normal file
File diff suppressed because it is too large
Load Diff
3127
ports_module/cortex-m3/iar/example_build/txm.ewt
Normal file
3127
ports_module/cortex-m3/iar/example_build/txm.ewt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
SECTION .text:CODE
|
||||
|
||||
AAPCS INTERWORK, ROPI, RWPI_COMPATIBLE, VFP_COMPATIBLE
|
||||
PRESERVE8
|
||||
|
||||
/* 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
|
||||
; Bits 23-3: Reserved
|
||||
; Bit 2: 0 -> Disable shared/external memory access
|
||||
; 1 -> Enable shared/external memory access
|
||||
; Bit 1: 0 -> No MPU protection
|
||||
; 1 -> MPU protection (must have user mode selected - bit 0 set)
|
||||
; Bit 0: 0 -> Privileged mode execution
|
||||
; 1 -> User mode execution
|
||||
|
||||
|
||||
DC32 _txm_module_thread_shell_entry - . - 0 ; Module Shell Entry Point
|
||||
DC32 demo_module_start - . - 0 ; Module Start Thread Entry Point
|
||||
DC32 0 ; Module Stop Thread Entry Point
|
||||
DC32 1 ; Module Start/Stop Thread Priority
|
||||
DC32 1022 ; Module Start/Stop Thread Stack Size
|
||||
DC32 _txm_module_callback_request_thread_entry - . - 0 ; Module Callback Thread Entry
|
||||
DC32 1 ; Module Callback Thread Priority
|
||||
DC32 1022 ; 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
|
||||
|
||||
|
||||
404
ports_module/cortex-m3/iar/inc/tx_port.h
Normal file
404
ports_module/cortex-m3/iar/inc/tx_port.h
Normal file
@@ -0,0 +1,404 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h Cortex-M3/IAR */
|
||||
/* 6.0.1 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains data type definitions that make the ThreadX */
|
||||
/* real-time kernel function identically on a variety of different */
|
||||
/* processor architectures. For example, the size or number of bits */
|
||||
/* in an "int" data type vary between microprocessor architectures and */
|
||||
/* even C compilers for the same microprocessor. ThreadX does not */
|
||||
/* directly use native C data types. Instead, ThreadX creates its */
|
||||
/* own special types that can be mapped to actual data types by this */
|
||||
/* file to guarantee consistency in the interface and functionality. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_PORT_H
|
||||
#define TX_PORT_H
|
||||
|
||||
|
||||
/* Determine if the optional ThreadX user define file should be used. */
|
||||
|
||||
#ifdef TX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
/* Yes, include the user defines in tx_user.h. The defines in this file may
|
||||
alternately be defined on the command line. */
|
||||
|
||||
#include "tx_user.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler library include files. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <intrinsics.h>
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#include <yvals.h>
|
||||
#endif
|
||||
|
||||
/* Define ThreadX basic types for this port. */
|
||||
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef signed int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef signed long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef signed 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 200 /* Minimum stack size for this port */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the system timer thread's default stack size and priority. These are only applicable
|
||||
if TX_TIMER_PROCESS_IN_ISR is not defined. */
|
||||
|
||||
#ifndef TX_TIMER_THREAD_STACK_SIZE
|
||||
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
|
||||
#endif
|
||||
|
||||
#ifndef TX_TIMER_THREAD_PRIORITY
|
||||
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define various constants for the ThreadX Cortex-M3 port. */
|
||||
|
||||
#define TX_INT_DISABLE 1 /* Disable interrupts */
|
||||
#define TX_INT_ENABLE 0 /* Enable interrupts */
|
||||
|
||||
|
||||
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
|
||||
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
|
||||
source constants would be:
|
||||
|
||||
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024UL)
|
||||
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TX_MISRA_ENABLE
|
||||
#ifndef TX_TRACE_TIME_SOURCE
|
||||
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
|
||||
#endif
|
||||
#else
|
||||
ULONG _tx_misra_time_stamp_get(VOID);
|
||||
#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get()
|
||||
#endif
|
||||
|
||||
#ifndef TX_TRACE_TIME_MASK
|
||||
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the port specific options for the _tx_build_options variable. This variable indicates
|
||||
how the ThreadX library was built. */
|
||||
|
||||
#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0)
|
||||
|
||||
|
||||
/* Define the in-line initialization constant so that modules with in-line
|
||||
initialization capabilities can prevent their initialization from being
|
||||
a function call. */
|
||||
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
#define TX_DISABLE_INLINE
|
||||
#else
|
||||
#define TX_INLINE_INITIALIZATION
|
||||
#endif
|
||||
|
||||
|
||||
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
|
||||
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
|
||||
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
|
||||
define is negated, thereby forcing the stack fill which is necessary for the stack checking
|
||||
logic. */
|
||||
|
||||
#ifndef TX_MISRA_ENABLE
|
||||
#ifdef TX_ENABLE_STACK_CHECKING
|
||||
#undef TX_DISABLE_STACK_FILLING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the TX_THREAD control block extensions for this port. The main reason
|
||||
for the multiple macros is so that backward compatibility can be maintained with
|
||||
existing ThreadX kernel awareness modules. */
|
||||
|
||||
#define TX_THREAD_EXTENSION_0
|
||||
#define TX_THREAD_EXTENSION_1
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
|
||||
VOID *tx_thread_module_entry_info_ptr; \
|
||||
ULONG tx_thread_module_current_user_mode; \
|
||||
ULONG tx_thread_module_user_mode; \
|
||||
ULONG tx_thread_module_saved_lr; \
|
||||
VOID *tx_thread_module_kernel_stack_start; \
|
||||
VOID *tx_thread_module_kernel_stack_end; \
|
||||
ULONG tx_thread_module_kernel_stack_size; \
|
||||
VOID *tx_thread_module_stack_ptr; \
|
||||
VOID *tx_thread_module_stack_start; \
|
||||
VOID *tx_thread_module_stack_end; \
|
||||
ULONG tx_thread_module_stack_size; \
|
||||
VOID *tx_thread_module_reserved; \
|
||||
VOID *tx_thread_iar_tls_pointer;
|
||||
#else
|
||||
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
|
||||
VOID *tx_thread_module_entry_info_ptr; \
|
||||
ULONG tx_thread_module_current_user_mode; \
|
||||
ULONG tx_thread_module_user_mode; \
|
||||
ULONG tx_thread_module_saved_lr; \
|
||||
VOID *tx_thread_module_kernel_stack_start; \
|
||||
VOID *tx_thread_module_kernel_stack_end; \
|
||||
ULONG tx_thread_module_kernel_stack_size; \
|
||||
VOID *tx_thread_module_stack_ptr; \
|
||||
VOID *tx_thread_module_stack_start; \
|
||||
VOID *tx_thread_module_stack_end; \
|
||||
ULONG tx_thread_module_stack_size; \
|
||||
VOID *tx_thread_module_reserved;
|
||||
#endif
|
||||
#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
#define TX_THREAD_EXTENSION_3
|
||||
#else
|
||||
#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \
|
||||
unsigned long long tx_thread_execution_time_last_start;
|
||||
#endif
|
||||
|
||||
/* Define the port extensions of the remaining ThreadX objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_EXTENSION
|
||||
#define TX_BYTE_POOL_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_MUTEX_EXTENSION
|
||||
#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. */
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#if (__VER__ < 8000000)
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
|
||||
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL;
|
||||
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
|
||||
#else
|
||||
void *_tx_iar_create_per_thread_tls_area(void);
|
||||
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
|
||||
void __iar_Initlocks(void);
|
||||
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area();
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \
|
||||
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0);
|
||||
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
|
||||
#endif
|
||||
#else
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#endif
|
||||
#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 the get system state macro. */
|
||||
|
||||
#ifndef TX_THREAD_GET_SYSTEM_STATE
|
||||
#ifndef TX_MISRA_ENABLE
|
||||
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR())
|
||||
#else
|
||||
ULONG _tx_misra_ipsr_get(VOID);
|
||||
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get())
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value
|
||||
indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h
|
||||
for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always
|
||||
zero after initialization for Cortex-M ports. */
|
||||
|
||||
#ifndef TX_THREAD_SYSTEM_RETURN_CHECK
|
||||
#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
|
||||
prevent early scheduling on Cortex-M parts. */
|
||||
|
||||
#define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++;
|
||||
|
||||
|
||||
/* Determine if the ARM architecture has the CLZ instruction. This is available on
|
||||
architectures v5 and above. If available, redefine the macro for calculating the
|
||||
lowest bit set. */
|
||||
|
||||
#ifndef TX_DISABLE_INLINE
|
||||
|
||||
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m)));
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define ThreadX interrupt lockout and restore macros for protection on
|
||||
access of critical kernel information. The restore interrupt macro must
|
||||
restore the interrupt posture of the running thread prior to the value
|
||||
present prior to the disable macro. In most cases, the save area macro
|
||||
is used to define a local function save area for the disable and restore
|
||||
macros. */
|
||||
|
||||
#ifdef TX_DISABLE_INLINE
|
||||
|
||||
UINT _tx_thread_interrupt_disable(VOID);
|
||||
VOID _tx_thread_interrupt_restore(UINT previous_posture);
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
|
||||
|
||||
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
|
||||
|
||||
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
|
||||
|
||||
#else
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save;
|
||||
#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();};
|
||||
#define TX_RESTORE {__set_interrupt_state(interrupt_save);};
|
||||
|
||||
#define _tx_thread_system_return _tx_thread_system_return_inline
|
||||
|
||||
static void _tx_thread_system_return_inline(void)
|
||||
{
|
||||
__istate_t interrupt_save;
|
||||
|
||||
/* Set PendSV to invoke ThreadX scheduler. */
|
||||
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
|
||||
if (__get_IPSR() == 0)
|
||||
{
|
||||
interrupt_save = __get_interrupt_state();
|
||||
__enable_interrupt();
|
||||
__set_interrupt_state(interrupt_save);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the interrupt lockout macros for each ThreadX object. */
|
||||
|
||||
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
|
||||
#define TX_BYTE_POOL_DISABLE TX_DISABLE
|
||||
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
|
||||
#define TX_MUTEX_DISABLE TX_DISABLE
|
||||
#define TX_QUEUE_DISABLE TX_DISABLE
|
||||
#define TX_SEMAPHORE_DISABLE TX_DISABLE
|
||||
|
||||
|
||||
/* Define the version ID of ThreadX. This may be utilized by the application. */
|
||||
|
||||
#ifdef TX_THREAD_INIT
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3/IAR Version 6.0.1 *";
|
||||
#else
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
extern CHAR _tx_version_id[100];
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
346
ports_module/cortex-m3/iar/inc/txm_module_port.h
Normal file
346
ports_module/cortex-m3/iar/inc/txm_module_port.h
Normal file
@@ -0,0 +1,346 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the 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 Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the basic module constants, interface structures, */
|
||||
/* and function prototypes. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TXM_MODULE_PORT_H
|
||||
#define TXM_MODULE_PORT_H
|
||||
|
||||
/* 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; \
|
||||
ULONG tx_thread_module_saved_lr; \
|
||||
VOID *tx_thread_module_kernel_stack_start; \
|
||||
VOID *tx_thread_module_kernel_stack_end; \
|
||||
ULONG tx_thread_module_kernel_stack_size; \
|
||||
VOID *tx_thread_module_stack_ptr; \
|
||||
VOID *tx_thread_module_stack_start; \
|
||||
VOID *tx_thread_module_stack_end; \
|
||||
ULONG tx_thread_module_stack_size; \
|
||||
VOID *tx_thread_module_reserved; \
|
||||
VOID *tx_thread_iar_tls_pointer;
|
||||
|
||||
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
|
||||
|
||||
/**************************************************************************/
|
||||
/* User-adjustable constants */
|
||||
/**************************************************************************/
|
||||
|
||||
/* Define the kernel stack size for a module thread. */
|
||||
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
|
||||
#define TXM_MODULE_KERNEL_STACK_SIZE 512
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/* End of user-adjustable constants */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* 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 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 number of MPU entries assigned to the code and data sections. On Cortex-M parts, there can only be 7 total
|
||||
entries, since ThreadX uses one for access to the kernel dispatch function. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_CODE_MPU_ENTRIES 4
|
||||
#define TXM_MODULE_MANAGER_DATA_MPU_ENTRIES 3
|
||||
#define TXM_MODULE_MANAGER_SHARED_MPU_INDEX 8
|
||||
#define TXM_MODULE_MANAGER_SHARED_MPU_REGION 4
|
||||
|
||||
/* Shared memory region attributes. */
|
||||
#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1
|
||||
#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT 0x01000000
|
||||
|
||||
/* Define the port-extensions to the module manager instance structure. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_PORT_EXTENSION \
|
||||
ULONG txm_module_instance_mpu_registers[16]; \
|
||||
ULONG txm_module_instance_shared_memory_address; \
|
||||
ULONG txm_module_instance_shared_memory_length;
|
||||
|
||||
|
||||
/* 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_shcsr;
|
||||
ULONG txm_module_manager_memory_fault_info_mmfsr;
|
||||
ULONG txm_module_manager_memory_fault_info_mmfar;
|
||||
ULONG txm_module_manager_memory_fault_info_control;
|
||||
ULONG txm_module_manager_memory_fault_info_sp;
|
||||
ULONG txm_module_manager_memory_fault_info_r0;
|
||||
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_lr;
|
||||
ULONG txm_module_manager_memory_fault_info_xpsr;
|
||||
} 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
|
||||
|
||||
|
||||
/* 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; \
|
||||
stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST; \
|
||||
callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST; \
|
||||
} \
|
||||
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) \
|
||||
{ \
|
||||
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_user_mode_entry; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_kernel_dispatch; \
|
||||
}
|
||||
|
||||
|
||||
/* 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_mm_register_setup(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) + (ULONG) module_instance -> txm_module_instance_code_start) || \
|
||||
((pointer+sizeof(pointer)) > (ULONG) module_instance -> txm_module_instance_code_end)) \
|
||||
&& (pointer != (ULONG) TX_NULL)) \
|
||||
{ \
|
||||
return(TX_PTR_ERROR); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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_mm_register_setup(TXM_MODULE_INSTANCE *module_instance); \
|
||||
ULONG _txm_power_of_two_block_size(ULONG size); \
|
||||
ULONG _txm_module_manager_calculate_srd_bits(ULONG block_size, ULONG length); \
|
||||
ULONG _txm_module_manager_region_size_get(ULONG block_size); \
|
||||
UCHAR _txm_module_manager_shared_memory_check_outside(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size); \
|
||||
UCHAR _txm_module_manager_shared_memory_check_inside(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size); \
|
||||
UCHAR _txm_module_manager_shared_memory_check_inside_byte(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr);
|
||||
|
||||
#define TXM_MODULE_MANAGER_VERSION_ID \
|
||||
CHAR _txm_module_manager_version_id[] = \
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M3/MPU/IAR Version 6.0.1 *";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the 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_init3(VOID);
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_thread_shell_entry Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* 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_init3 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 */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
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_init3();
|
||||
|
||||
/* 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
|
||||
}
|
||||
|
||||
804
ports_module/cortex-m3/iar/module_manager/src/tx_iar.c
Normal file
804
ports_module/cortex-m3/iar/module_manager/src/tx_iar.c
Normal file
@@ -0,0 +1,804 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** IAR Multithreaded Library Support */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Define IAR library for tools prior to version 8. */
|
||||
|
||||
#if (__VER__ < 8000000)
|
||||
|
||||
|
||||
/* IAR version 7 and below. */
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_mutex.h"
|
||||
|
||||
|
||||
/* This implementation requires that the following macros are defined in the
|
||||
tx_port.h file and <yvals.h> is included with the following code segments:
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#include <yvals.h>
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
|
||||
#else
|
||||
#define TX_THREAD_EXTENSION_2
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
|
||||
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL;
|
||||
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
|
||||
#else
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#endif
|
||||
|
||||
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
|
||||
application.
|
||||
|
||||
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
|
||||
*/
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
|
||||
#include <yvals.h>
|
||||
|
||||
|
||||
#if _MULTI_THREAD
|
||||
|
||||
TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK];
|
||||
UINT __tx_iar_system_lock_next_free_mutex = 0;
|
||||
|
||||
|
||||
/* Define error counters, just for debug purposes. */
|
||||
|
||||
UINT __tx_iar_system_lock_no_mutexes;
|
||||
UINT __tx_iar_system_lock_internal_errors;
|
||||
UINT __tx_iar_system_lock_isr_caller;
|
||||
|
||||
|
||||
/* Define the TLS access function for the IAR library. */
|
||||
|
||||
void _DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
|
||||
{
|
||||
|
||||
char _DLIB_TLS_MEMORY *p = 0;
|
||||
|
||||
/* Is there a current thread? */
|
||||
if (_tx_thread_current_ptr)
|
||||
p = (char _DLIB_TLS_MEMORY *) _tx_thread_current_ptr -> tx_thread_iar_tls_pointer;
|
||||
else
|
||||
p = (void _DLIB_TLS_MEMORY *) __segment_begin("__DLIB_PERTHREAD");
|
||||
p += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
|
||||
return (void _DLIB_TLS_MEMORY *) p;
|
||||
}
|
||||
|
||||
|
||||
/* Define mutexes for IAR library. */
|
||||
|
||||
void __iar_system_Mtxinit(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT i;
|
||||
UINT status;
|
||||
TX_MUTEX *mutex_ptr;
|
||||
|
||||
|
||||
/* First, find a free mutex in the list. */
|
||||
for (i = 0; i < _MAX_LOCK; i++)
|
||||
{
|
||||
|
||||
/* Setup a pointer to the start of the next free mutex. */
|
||||
mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
|
||||
|
||||
/* Check for wrap-around on the next free mutex. */
|
||||
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Yes, set the free index back to 0. */
|
||||
__tx_iar_system_lock_next_free_mutex = 0;
|
||||
}
|
||||
|
||||
/* Is this mutex free? */
|
||||
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
|
||||
{
|
||||
|
||||
/* Yes, this mutex is free, get out of the loop! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if a free mutex was found. */
|
||||
if (i >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Error! No more free mutexes! */
|
||||
|
||||
/* Increment the no mutexes error counter. */
|
||||
__tx_iar_system_lock_no_mutexes++;
|
||||
|
||||
/* Set return pointer to NULL. */
|
||||
*m = TX_NULL;
|
||||
|
||||
/* Return. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now create the ThreadX mutex for the IAR library. */
|
||||
status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
|
||||
|
||||
/* Determine if the creation was successful. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Yes, successful creation, return mutex pointer. */
|
||||
*m = (VOID *) mutex_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the internal error counter. */
|
||||
__tx_iar_system_lock_internal_errors++;
|
||||
|
||||
/* Return a NULL pointer to indicate an error. */
|
||||
*m = TX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_system_Mtxdst(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
/* Simply delete the mutex. */
|
||||
_tx_mutex_delete((TX_MUTEX *) *m);
|
||||
}
|
||||
|
||||
void __iar_system_Mtxlock(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine the caller's context. Mutex locks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Get the mutex. */
|
||||
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_system_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_system_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_system_Mtxunlock(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine the caller's context. Mutex unlocks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Release the mutex. */
|
||||
status = _tx_mutex_put((TX_MUTEX *) *m);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_system_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_system_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if _DLIB_FILE_DESCRIPTOR
|
||||
|
||||
TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK];
|
||||
UINT __tx_iar_file_lock_next_free_mutex = 0;
|
||||
|
||||
|
||||
/* Define error counters, just for debug purposes. */
|
||||
|
||||
UINT __tx_iar_file_lock_no_mutexes;
|
||||
UINT __tx_iar_file_lock_internal_errors;
|
||||
UINT __tx_iar_file_lock_isr_caller;
|
||||
|
||||
|
||||
void __iar_file_Mtxinit(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT i;
|
||||
UINT status;
|
||||
TX_MUTEX *mutex_ptr;
|
||||
|
||||
|
||||
/* First, find a free mutex in the list. */
|
||||
for (i = 0; i < _MAX_FLOCK; i++)
|
||||
{
|
||||
|
||||
/* Setup a pointer to the start of the next free mutex. */
|
||||
mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
|
||||
|
||||
/* Check for wrap-around on the next free mutex. */
|
||||
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Yes, set the free index back to 0. */
|
||||
__tx_iar_file_lock_next_free_mutex = 0;
|
||||
}
|
||||
|
||||
/* Is this mutex free? */
|
||||
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
|
||||
{
|
||||
|
||||
/* Yes, this mutex is free, get out of the loop! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if a free mutex was found. */
|
||||
if (i >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Error! No more free mutexes! */
|
||||
|
||||
/* Increment the no mutexes error counter. */
|
||||
__tx_iar_file_lock_no_mutexes++;
|
||||
|
||||
/* Set return pointer to NULL. */
|
||||
*m = TX_NULL;
|
||||
|
||||
/* Return. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now create the ThreadX mutex for the IAR library. */
|
||||
status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
|
||||
|
||||
/* Determine if the creation was successful. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Yes, successful creation, return mutex pointer. */
|
||||
*m = (VOID *) mutex_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the internal error counter. */
|
||||
__tx_iar_file_lock_internal_errors++;
|
||||
|
||||
/* Return a NULL pointer to indicate an error. */
|
||||
*m = TX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_file_Mtxdst(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
/* Simply delete the mutex. */
|
||||
_tx_mutex_delete((TX_MUTEX *) *m);
|
||||
}
|
||||
|
||||
void __iar_file_Mtxlock(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine the caller's context. Mutex locks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Get the mutex. */
|
||||
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_file_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_file_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_file_Mtxunlock(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine the caller's context. Mutex unlocks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Release the mutex. */
|
||||
status = _tx_mutex_put((TX_MUTEX *) *m);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_file_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_file_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
#endif /* _DLIB_FILE_DESCRIPTOR */
|
||||
|
||||
#endif /* _MULTI_THREAD */
|
||||
|
||||
#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
|
||||
|
||||
#else /* IAR version 8 and above. */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_mutex.h"
|
||||
|
||||
/* This implementation requires that the following macros are defined in the
|
||||
tx_port.h file and <yvals.h> is included with the following code segments:
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#include <yvals.h>
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
|
||||
#else
|
||||
#define TX_THREAD_EXTENSION_2
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
void *_tx_iar_create_per_thread_tls_area(void);
|
||||
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
|
||||
void __iar_Initlocks(void);
|
||||
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {__iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
|
||||
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0);
|
||||
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
|
||||
#else
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#endif
|
||||
|
||||
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
|
||||
application.
|
||||
|
||||
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
|
||||
*/
|
||||
|
||||
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
|
||||
|
||||
#include <DLib_threads.h>
|
||||
|
||||
|
||||
void * __aeabi_read_tp();
|
||||
|
||||
void* _tx_iar_create_per_thread_tls_area();
|
||||
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
|
||||
|
||||
#pragma section="__iar_tls$$DATA"
|
||||
|
||||
/* Define the TLS access function for the IAR library. */
|
||||
void * __aeabi_read_tp(void)
|
||||
{
|
||||
void *p = 0;
|
||||
TX_THREAD *thread_ptr = _tx_thread_current_ptr;
|
||||
if (thread_ptr)
|
||||
{
|
||||
p = thread_ptr->tx_thread_iar_tls_pointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = __section_begin("__iar_tls$$DATA");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Define the TLS creation and destruction to use malloc/free. */
|
||||
|
||||
void* _tx_iar_create_per_thread_tls_area()
|
||||
{
|
||||
UINT tls_size = __iar_tls_size();
|
||||
|
||||
/* Get memory for TLS. */
|
||||
void *p = malloc(tls_size);
|
||||
|
||||
/* Initialize TLS-area and run constructors for objects in TLS */
|
||||
__iar_tls_init(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr)
|
||||
{
|
||||
/* Destroy objects living in TLS */
|
||||
__call_thread_dtors();
|
||||
free(tls_ptr);
|
||||
}
|
||||
|
||||
#ifndef _MAX_LOCK
|
||||
#define _MAX_LOCK 4
|
||||
#endif
|
||||
|
||||
static TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK];
|
||||
static UINT __tx_iar_system_lock_next_free_mutex = 0;
|
||||
|
||||
|
||||
/* Define error counters, just for debug purposes. */
|
||||
|
||||
UINT __tx_iar_system_lock_no_mutexes;
|
||||
UINT __tx_iar_system_lock_internal_errors;
|
||||
UINT __tx_iar_system_lock_isr_caller;
|
||||
|
||||
|
||||
/* Define mutexes for IAR library. */
|
||||
|
||||
void __iar_system_Mtxinit(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT i;
|
||||
UINT status;
|
||||
TX_MUTEX *mutex_ptr;
|
||||
|
||||
|
||||
/* First, find a free mutex in the list. */
|
||||
for (i = 0; i < _MAX_LOCK; i++)
|
||||
{
|
||||
|
||||
/* Setup a pointer to the start of the next free mutex. */
|
||||
mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
|
||||
|
||||
/* Check for wrap-around on the next free mutex. */
|
||||
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Yes, set the free index back to 0. */
|
||||
__tx_iar_system_lock_next_free_mutex = 0;
|
||||
}
|
||||
|
||||
/* Is this mutex free? */
|
||||
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
|
||||
{
|
||||
|
||||
/* Yes, this mutex is free, get out of the loop! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if a free mutex was found. */
|
||||
if (i >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Error! No more free mutexes! */
|
||||
|
||||
/* Increment the no mutexes error counter. */
|
||||
__tx_iar_system_lock_no_mutexes++;
|
||||
|
||||
/* Set return pointer to NULL. */
|
||||
*m = TX_NULL;
|
||||
|
||||
/* Return. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now create the ThreadX mutex for the IAR library. */
|
||||
status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
|
||||
|
||||
/* Determine if the creation was successful. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Yes, successful creation, return mutex pointer. */
|
||||
*m = (VOID *) mutex_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the internal error counter. */
|
||||
__tx_iar_system_lock_internal_errors++;
|
||||
|
||||
/* Return a NULL pointer to indicate an error. */
|
||||
*m = TX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_system_Mtxdst(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
/* Simply delete the mutex. */
|
||||
_tx_mutex_delete((TX_MUTEX *) *m);
|
||||
}
|
||||
|
||||
void __iar_system_Mtxlock(__iar_Rmtx *m)
|
||||
{
|
||||
if (*m)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
/* Determine the caller's context. Mutex locks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Get the mutex. */
|
||||
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_system_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_system_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_system_Mtxunlock(__iar_Rmtx *m)
|
||||
{
|
||||
if (*m)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
/* Determine the caller's context. Mutex unlocks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Release the mutex. */
|
||||
status = _tx_mutex_put((TX_MUTEX *) *m);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_system_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_system_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if _DLIB_FILE_DESCRIPTOR
|
||||
|
||||
#include <stdio.h> /* Added to get access to FOPEN_MAX */
|
||||
#ifndef _MAX_FLOCK
|
||||
#define _MAX_FLOCK FOPEN_MAX /* Define _MAX_FLOCK as the maximum number of open files */
|
||||
#endif
|
||||
|
||||
|
||||
TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK];
|
||||
UINT __tx_iar_file_lock_next_free_mutex = 0;
|
||||
|
||||
|
||||
/* Define error counters, just for debug purposes. */
|
||||
|
||||
UINT __tx_iar_file_lock_no_mutexes;
|
||||
UINT __tx_iar_file_lock_internal_errors;
|
||||
UINT __tx_iar_file_lock_isr_caller;
|
||||
|
||||
|
||||
void __iar_file_Mtxinit(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT i;
|
||||
UINT status;
|
||||
TX_MUTEX *mutex_ptr;
|
||||
|
||||
|
||||
/* First, find a free mutex in the list. */
|
||||
for (i = 0; i < _MAX_FLOCK; i++)
|
||||
{
|
||||
|
||||
/* Setup a pointer to the start of the next free mutex. */
|
||||
mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
|
||||
|
||||
/* Check for wrap-around on the next free mutex. */
|
||||
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Yes, set the free index back to 0. */
|
||||
__tx_iar_file_lock_next_free_mutex = 0;
|
||||
}
|
||||
|
||||
/* Is this mutex free? */
|
||||
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
|
||||
{
|
||||
|
||||
/* Yes, this mutex is free, get out of the loop! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if a free mutex was found. */
|
||||
if (i >= _MAX_LOCK)
|
||||
{
|
||||
|
||||
/* Error! No more free mutexes! */
|
||||
|
||||
/* Increment the no mutexes error counter. */
|
||||
__tx_iar_file_lock_no_mutexes++;
|
||||
|
||||
/* Set return pointer to NULL. */
|
||||
*m = TX_NULL;
|
||||
|
||||
/* Return. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now create the ThreadX mutex for the IAR library. */
|
||||
status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
|
||||
|
||||
/* Determine if the creation was successful. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Yes, successful creation, return mutex pointer. */
|
||||
*m = (VOID *) mutex_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the internal error counter. */
|
||||
__tx_iar_file_lock_internal_errors++;
|
||||
|
||||
/* Return a NULL pointer to indicate an error. */
|
||||
*m = TX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_file_Mtxdst(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
/* Simply delete the mutex. */
|
||||
_tx_mutex_delete((TX_MUTEX *) *m);
|
||||
}
|
||||
|
||||
void __iar_file_Mtxlock(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine the caller's context. Mutex locks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Get the mutex. */
|
||||
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_file_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_file_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
|
||||
void __iar_file_Mtxunlock(__iar_Rmtx *m)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine the caller's context. Mutex unlocks are only available from initialization and
|
||||
threads. */
|
||||
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
|
||||
{
|
||||
|
||||
/* Release the mutex. */
|
||||
status = _tx_mutex_put((TX_MUTEX *) *m);
|
||||
|
||||
/* Check the status of the mutex release. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Internal error, increment the counter. */
|
||||
__tx_iar_file_lock_internal_errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Increment the ISR caller error. */
|
||||
__tx_iar_file_lock_isr_caller++;
|
||||
}
|
||||
}
|
||||
#endif /* _DLIB_FILE_DESCRIPTOR */
|
||||
|
||||
#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
|
||||
|
||||
#endif /* IAR version 8 and above. */
|
||||
1003
ports_module/cortex-m3/iar/module_manager/src/tx_misra.s
Normal file
1003
ports_module/cortex-m3/iar/module_manager/src/tx_misra.s
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,97 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
;
|
||||
EXTERN _tx_execution_isr_exit
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_context_restore Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* 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_execution_isr_exit] Execution profiling ISR exit */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* ISRs Interrupt Service Routines */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_context_restore(VOID)
|
||||
;{
|
||||
PUBLIC _tx_thread_context_restore
|
||||
_tx_thread_context_restore:
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
;
|
||||
; /* Call the ISR exit function to indicate an ISR is complete. */
|
||||
;
|
||||
PUSH {r0,lr} ; Save ISR lr
|
||||
BL _tx_execution_isr_exit ; Call the ISR exit function
|
||||
POP {r0,lr} ; Restore ISR lr
|
||||
#endif
|
||||
;
|
||||
POP {lr}
|
||||
BX lr
|
||||
;
|
||||
;}
|
||||
END
|
||||
@@ -0,0 +1,96 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
;
|
||||
EXTERN _tx_execution_isr_enter
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_context_save Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* 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 */
|
||||
;/* */
|
||||
;/* [_tx_execution_isr_enter] Execution profiling ISR enter */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* ISRs */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_context_save(VOID)
|
||||
;{
|
||||
PUBLIC _tx_thread_context_save
|
||||
_tx_thread_context_save:
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
;
|
||||
; /* Call the ISR enter function to indicate an ISR is starting. */
|
||||
;
|
||||
PUSH {r0, lr} ; Save return address
|
||||
BL _tx_execution_isr_enter ; Call the ISR enter function
|
||||
POP {r0, lr} ; Recover return address
|
||||
#endif
|
||||
;
|
||||
; /* Context is already saved - just return! */
|
||||
;
|
||||
BX lr
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_interrupt_control Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* William E. Lamie, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function is responsible for changing the interrupt lockout */
|
||||
;/* posture of the system. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* new_posture New interrupt lockout posture */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* old_posture Old interrupt lockout posture */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* Application Code */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;UINT _tx_thread_interrupt_control(UINT new_posture)
|
||||
;{
|
||||
PUBLIC _tx_thread_interrupt_control
|
||||
_tx_thread_interrupt_control:
|
||||
;
|
||||
; /* Pickup current interrupt lockout posture. */
|
||||
;
|
||||
MRS r1, PRIMASK
|
||||
MSR PRIMASK, r0
|
||||
MOV r0, r1
|
||||
BX lr
|
||||
;
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -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 */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_interrupt_restore Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* William E. Lamie, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function is responsible for disabling interrupts and returning */
|
||||
;/* the previous interrupt lockout posture. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* old_posture Old interrupt lockout posture */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* Application Code */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;UINT _tx_thread_interrupt_disable(UINT new_posture)
|
||||
;{
|
||||
PUBLIC _tx_thread_interrupt_disable
|
||||
_tx_thread_interrupt_disable:
|
||||
;
|
||||
; /* Return current interrupt lockout posture. */
|
||||
;
|
||||
MRS r0, PRIMASK
|
||||
CPSID i
|
||||
BX lr
|
||||
;
|
||||
;}
|
||||
END
|
||||
@@ -0,0 +1,83 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_interrupt_restore Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* William E. Lamie, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function is responsible for restoring the previous */
|
||||
;/* interrupt lockout posture. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* previous_posture Previous interrupt posture */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* Application Code */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_interrupt_restore(UINT new_posture)
|
||||
;{
|
||||
PUBLIC _tx_thread_interrupt_restore
|
||||
_tx_thread_interrupt_restore:
|
||||
;
|
||||
; /* Restore previous interrupt lockout posture. */
|
||||
;
|
||||
MSR PRIMASK, r0
|
||||
BX lr
|
||||
;
|
||||
;}
|
||||
END
|
||||
@@ -0,0 +1,526 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_thread_execute_ptr
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_thread_system_stack_ptr
|
||||
EXTERN _tx_execution_thread_enter
|
||||
EXTERN _tx_execution_thread_exit
|
||||
EXTERN _tx_thread_preempt_disable
|
||||
EXTERN _txm_module_manager_memory_fault_handler
|
||||
EXTERN _txm_module_manager_memory_fault_info
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_schedule Cortex-M3/MPU/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function waits for a thread control block pointer to appear in */
|
||||
;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
|
||||
;/* in the variable, the corresponding thread is resumed. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
;/* _tx_thread_system_return Return to system from thread */
|
||||
;/* _tx_thread_context_restore Restore thread's context */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_schedule(VOID)
|
||||
;{
|
||||
PUBLIC _tx_thread_schedule
|
||||
_tx_thread_schedule:
|
||||
;
|
||||
; /* This function should only ever be called on Cortex-M
|
||||
; from the first schedule request. Subsequent scheduling occurs
|
||||
; from the PendSV handling routines below. */
|
||||
;
|
||||
; /* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */
|
||||
;
|
||||
MOV r0, #0 ; Build value for TX_FALSE
|
||||
LDR r2, =_tx_thread_preempt_disable ; Build address of preempt disable flag
|
||||
STR r0, [r2, #0] ; Clear preempt disable flag
|
||||
;
|
||||
; /* Enable memory fault registers. */
|
||||
;
|
||||
LDR r0, =0xE000ED24 ; Build SHCSR address
|
||||
LDR r1, =0x70000 ; Enable Usage, Bus, and MemManage faults
|
||||
STR r1, [r0] ;
|
||||
;
|
||||
; /* Enable interrupts */
|
||||
;
|
||||
CPSIE i
|
||||
;
|
||||
; /* Enter the scheduler for the first time. */
|
||||
;
|
||||
MOV r0, #0x10000000 ; Load PENDSVSET bit
|
||||
MOV r1, #0xE000E000 ; Load NVIC base
|
||||
STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR
|
||||
NOP ;
|
||||
NOP ;
|
||||
NOP ;
|
||||
NOP ;
|
||||
;
|
||||
; /* We should never get here - ever! */
|
||||
;
|
||||
BKPT 0xEF ; Setup error conditions
|
||||
BX lr ;
|
||||
;}
|
||||
;
|
||||
|
||||
;
|
||||
; /* Memory Exception Handler. */
|
||||
;
|
||||
PUBLIC MemManage_Handler
|
||||
MemManage_Handler:
|
||||
;{
|
||||
CPSID i ; Disable interrupts
|
||||
;
|
||||
; /* Now pickup and store all the fault related information. */
|
||||
;
|
||||
LDR r12,=_txm_module_manager_memory_fault_info ; Pickup fault info struct
|
||||
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r1, [r0] ; Pickup the current thread pointer
|
||||
STR r1, [r12, #0] ; Save current thread pointer in fault info structure
|
||||
LDR r0, =0xE000ED24 ; Build SHCSR address
|
||||
LDR r1, [r0] ; Pickup SHCSR
|
||||
STR r1, [r12, #8] ; Save SHCSR
|
||||
LDR r0, =0xE000ED28 ; Build MMFSR address
|
||||
LDR r1, [r0] ; Pickup MMFSR (and other fault status too!)
|
||||
STR r1, [r12, #12] ; Save MMFSR
|
||||
LDR r0, =0xE000ED34 ; Build MMFAR address
|
||||
LDR r1, [r0] ; Pickup MMFAR
|
||||
STR r1, [r12, #16] ; Save MMFAR
|
||||
MRS r0, CONTROL ; Pickup current CONTROL register
|
||||
STR r0, [r12, #20] ; Save CONTROL
|
||||
MRS r1, PSP ; Pickup thread stack pointer
|
||||
STR r1, [r12, #24] ; Save thread stack pointer
|
||||
LDR r0, [r1] ; Pickup saved r0
|
||||
STR r0, [r12, #28] ; Save r0
|
||||
LDR r0, [r1, #4] ; Pickup saved r1
|
||||
STR r0, [r12, #32] ; Save r1
|
||||
STR r2, [r12, #36] ; Save r2
|
||||
STR r3, [r12, #40] ; Save r3
|
||||
STR r4, [r12, #44] ; Save r4
|
||||
STR r5, [r12, #48] ; Save r5
|
||||
STR r6, [r12, #52] ; Save r6
|
||||
STR r7, [r12, #56] ; Save r7
|
||||
STR r8, [r12, #60] ; Save r8
|
||||
STR r9, [r12, #64] ; Save r9
|
||||
STR r10,[r12, #68] ; Save r10
|
||||
STR r11,[r12, #72] ; Save r11
|
||||
LDR r0, [r1, #16] ; Pickup saved r12
|
||||
STR r0, [r12, #76] ; Save r12
|
||||
LDR r0, [r1, #20] ; Pickup saved lr
|
||||
STR r0, [r12, #80] ; Save lr
|
||||
LDR r0, [r1, #24] ; Pickup instruction address at point of fault
|
||||
STR r0, [r12, #4] ; Save point of fault
|
||||
LDR r0, [r1, #28] ; Pickup xPSR
|
||||
STR r0, [r12, #84] ; Save xPSR
|
||||
|
||||
MRS r0, CONTROL ; Pickup current CONTROL register
|
||||
BIC r0, r0, #1 ; Clear the UNPRIV bit
|
||||
MSR CONTROL, r0 ; Setup new CONTROL register
|
||||
|
||||
LDR r0, =0xE000ED28 ; Build the Memory Management Fault Status Register (MMFSR)
|
||||
LDRB r1, [r0] ; Pickup the MMFSR, with the following bit definitions:
|
||||
; Bit 0 = 1 -> Instruction address violation
|
||||
; Bit 1 = 1 -> Load/store address violation
|
||||
; Bit 7 = 1 -> MMFAR is valid
|
||||
STRB r1, [r0] ; Clear the MMFSR
|
||||
|
||||
BL _txm_module_manager_memory_fault_handler ; Call memory manager fault handler
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
;
|
||||
; /* Call the thread exit function to indicate the thread is no longer executing. */
|
||||
;
|
||||
CPSID i ; Disable interrupts
|
||||
BL _tx_execution_thread_exit ; Call the thread exit function
|
||||
CPSIE i ; Enable interrupts
|
||||
#endif
|
||||
|
||||
MOV r1, #0 ; Build NULL value
|
||||
LDR r0, =_tx_thread_current_ptr ; Pickup address of current thread pointer
|
||||
STR r1, [r0] ; Clear current thread pointer
|
||||
|
||||
; Return from MemManage_Handler exception
|
||||
LDR r0, =0xE000ED04 ; Load ICSR
|
||||
LDR r1, =0x10000000 ; Set PENDSVSET bit
|
||||
STR r1, [r0] ; Store ICSR
|
||||
DSB ; Wait for memory access to complete
|
||||
CPSIE i ; Enable interrupts
|
||||
MOV lr, #0xFFFFFFFD ; Load exception return code
|
||||
BX lr ; Return from exception
|
||||
;}
|
||||
|
||||
;
|
||||
; /* Generic context PendSV handler. */
|
||||
;
|
||||
PUBLIC PendSV_Handler
|
||||
PUBLIC __tx_PendSVHandler
|
||||
PendSV_Handler:
|
||||
__tx_PendSVHandler:
|
||||
;
|
||||
; /* Get current thread value and new thread pointer. */
|
||||
;
|
||||
__tx_ts_handler:
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
;
|
||||
; /* Call the thread exit function to indicate the thread is no longer executing. */
|
||||
;
|
||||
CPSID i ; Disable interrupts
|
||||
PUSH {r0, lr} ; Save LR (and r0 just for alignment)
|
||||
BL _tx_execution_thread_exit ; Call the thread exit function
|
||||
POP {r0, lr} ; Recover LR
|
||||
CPSIE i ; Enable interrupts
|
||||
#endif
|
||||
MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address
|
||||
MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address
|
||||
MOV r3, #0 ; Build NULL value
|
||||
LDR r1, [r0] ; Pickup current thread pointer
|
||||
;
|
||||
; /* Determine if there is a current thread to finish preserving. */
|
||||
;
|
||||
CBZ r1, __tx_ts_new ; If NULL, skip preservation
|
||||
;
|
||||
; /* Recover PSP and preserve current thread context. */
|
||||
;
|
||||
STR r3, [r0] ; Set _tx_thread_current_ptr to NULL
|
||||
MRS r12, PSP ; Pickup PSP pointer (thread's stack pointer)
|
||||
STMDB r12!, {r4-r11} ; Save its remaining registers
|
||||
MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable
|
||||
STMDB r12!, {LR} ; Save LR on the stack
|
||||
;
|
||||
; /* Determine if time-slice is active. If it isn't, skip time handling processing. */
|
||||
;
|
||||
LDR r5, [r4] ; Pickup current time-slice
|
||||
STR r12, [r1, #8] ; Save the thread stack pointer
|
||||
CBZ r5, __tx_ts_new ; If not active, skip processing
|
||||
;
|
||||
; /* Time-slice is active, save the current thread's time-slice and clear the global time-slice variable. */
|
||||
;
|
||||
STR r5, [r1, #24] ; Save current time-slice
|
||||
;
|
||||
; /* Clear the global time-slice. */
|
||||
;
|
||||
STR r3, [r4] ; Clear time-slice
|
||||
;
|
||||
;
|
||||
; /* Executing thread is now completely preserved!!! */
|
||||
;
|
||||
__tx_ts_new:
|
||||
;
|
||||
; /* Now we are looking for a new thread to execute! */
|
||||
;
|
||||
CPSID i ; Disable interrupts
|
||||
LDR r1, [r2] ; Is there another thread ready to execute?
|
||||
CBZ r1, __tx_ts_wait ; No, skip to the wait processing
|
||||
;
|
||||
; /* Yes, another thread is ready for else, make the current thread the new thread. */
|
||||
;
|
||||
STR r1, [r0] ; Setup the current thread pointer to the new thread
|
||||
CPSIE i ; Enable interrupts
|
||||
;
|
||||
; /* Increment the thread run count. */
|
||||
;
|
||||
__tx_ts_restore:
|
||||
LDR r7, [r1, #4] ; Pickup the current thread run count
|
||||
MOV32 r4, _tx_timer_time_slice ; Build address of time-slice variable
|
||||
LDR r5, [r1, #24] ; Pickup thread's current time-slice
|
||||
ADD r7, r7, #1 ; Increment the thread run count
|
||||
STR r7, [r1, #4] ; Store the new run count
|
||||
;
|
||||
; /* Setup global time-slice with thread's current time-slice. */
|
||||
;
|
||||
STR r5, [r4] ; Setup global time-slice
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
;
|
||||
; /* Call the thread entry function to indicate the thread is executing. */
|
||||
;
|
||||
PUSH {r0, r1} ; Save r0 and r1
|
||||
BL _tx_execution_thread_enter ; Call the thread execution enter function
|
||||
POP {r0, r1} ; Recover r0 and r1
|
||||
#endif
|
||||
;
|
||||
; /* Restore the thread context and PSP. */
|
||||
;
|
||||
LDR r12, [r1, #8] ; Pickup thread's stack pointer
|
||||
|
||||
MRS r5, CONTROL ; Pickup current CONTROL register
|
||||
LDR r4, [r1, #0x98] ; Pickup current user mode flag
|
||||
BIC r5, r5, #1 ; Clear the UNPRIV bit
|
||||
ORR r4, r4, r5 ; Build new CONTROL register
|
||||
MSR CONTROL, r4 ; Setup new CONTROL register
|
||||
|
||||
LDR r0, =0xE000ED94 ; Build MPU control reg address
|
||||
MOV r3, #0 ; Build disable value
|
||||
STR r3, [r0] ; Disable MPU
|
||||
LDR r0, [r1, #0x90] ; Pickup the module instance pointer
|
||||
CBZ r0, skip_mpu_setup ; Is this thread owned by a module? No, skip MPU setup
|
||||
LDR r1, [r0, #0x64] ; Pickup MPU register[0]
|
||||
CBZ r1, skip_mpu_setup ; Is protection required for this module? No, skip MPU setup
|
||||
LDR r1, =0xE000ED9C ; Build address of MPU base register
|
||||
|
||||
; Use alias registers to quickly load MPU
|
||||
ADD r0, r0, #100 ; Build address of MPU register start in thread control block
|
||||
LDM r0!,{r2-r9} ; Load first four MPU regions
|
||||
STM r1,{r2-r9} ; Store first four MPU regions
|
||||
LDM r0,{r2-r9} ; Load second four MPU regions
|
||||
STM r1,{r2-r9} ; Store second four MPU regions
|
||||
LDR r0, =0xE000ED94 ; Build MPU control reg address
|
||||
MOV r1, #5 ; Build enable value
|
||||
STR r1, [r0] ; Enable MPU
|
||||
skip_mpu_setup:
|
||||
LDMIA r12!, {LR} ; Pickup LR
|
||||
LDMIA r12!, {r4-r11} ; Recover thread's registers
|
||||
MSR PSP, r12 ; Setup the thread's stack pointer
|
||||
;
|
||||
; /* Return to thread. */
|
||||
;
|
||||
BX lr ; Return to thread!
|
||||
;
|
||||
; /* The following is the idle wait processing... in this case, no threads are ready for execution and the
|
||||
; system will simply be idle until an interrupt occurs that makes a thread ready. Note that interrupts
|
||||
; are disabled to allow use of WFI for waiting for a thread to arrive. */
|
||||
;
|
||||
__tx_ts_wait:
|
||||
CPSID i ; Disable interrupts
|
||||
LDR r1, [r2] ; Pickup the next thread to execute pointer
|
||||
STR r1, [r0] ; Store it in the current pointer
|
||||
CBNZ r1, __tx_ts_ready ; If non-NULL, a new thread is ready!
|
||||
#ifdef TX_ENABLE_WFI
|
||||
DSB ; Ensure no outstanding memory transactions
|
||||
WFI ; Wait for interrupt
|
||||
ISB ; Ensure pipeline is flushed
|
||||
#endif
|
||||
CPSIE i ; Enable interrupts
|
||||
B __tx_ts_wait ; Loop to continue waiting
|
||||
;
|
||||
; /* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
|
||||
; already in the handler! */
|
||||
;
|
||||
__tx_ts_ready:
|
||||
MOV r7, #0x08000000 ; Build clear PendSV value
|
||||
MOV r8, #0xE000E000 ; Build base NVIC address
|
||||
STR r7, [r8, #0xD04] ; Clear any PendSV
|
||||
;
|
||||
; /* Re-enable interrupts and restore new thread. */
|
||||
;
|
||||
CPSIE i ; Enable interrupts
|
||||
B __tx_ts_restore ; Restore the thread
|
||||
;}
|
||||
|
||||
;
|
||||
; /* SVC Handler. */
|
||||
;
|
||||
PUBLIC SVC_Handler
|
||||
PUBLIC __tx_SVCallHandler
|
||||
SVC_Handler:
|
||||
__tx_SVCallHandler:
|
||||
;{
|
||||
MRS r0, PSP ; Pickup the PSP stack
|
||||
LDR r1, [r0, #24] ; Pickup the point of interrupt
|
||||
LDRB r2, [r1, #-2] ; Pickup the SVC parameter
|
||||
;
|
||||
; Determine which SVC trap we are processing
|
||||
;
|
||||
CMP r2, #1 ; Is it the entry into ThreadX?
|
||||
BNE _tx_thread_user_return ; No, return to user mode
|
||||
;
|
||||
; At this point we have an SVC 1, which means we are entering the kernel from a module thread with user mode selected
|
||||
;
|
||||
LDR r2, =_txm_module_priv-1 ; Subtract 1 because of THUMB mode.
|
||||
CMP r1, r2 ; Did we come from user_mode_entry?
|
||||
IT NE ; If no (not equal), then...
|
||||
BXNE lr ; return from where we came.
|
||||
|
||||
LDR r3, [r0, #20] ; This is the saved LR
|
||||
LDR r1, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r2, [r1] ; Pickup current thread pointer
|
||||
MOV r1, #0 ; Build clear value
|
||||
STR r1, [r2, #0x98] ; Clear the current user mode selection for thread
|
||||
STR r3, [r2, #0xA0] ; Save the original LR in thread control block
|
||||
|
||||
; If there is memory protection, use kernel stack
|
||||
LDR r0, [r2, #0x90] ; Load the module instance ptr
|
||||
LDR r0, [r0, #0x0C] ; Load the module property flags
|
||||
TST r0, #2 ; Check if memory protected
|
||||
BEQ _tx_skip_kernel_stack_enter
|
||||
|
||||
; Switch to the module thread's kernel stack
|
||||
LDR r0, [r2, #0xA8] ; Load the module kernel stack end
|
||||
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
|
||||
LDR r1, [r2, #0xA4] ; Load the module kernel stack start
|
||||
LDR r3, [r2, #0xAC] ; Load the module kernel stack size
|
||||
STR r1, [r2, #12] ; Set stack start
|
||||
STR r0, [r2, #16] ; Set stack end
|
||||
STR r3, [r2, #20] ; Set stack size
|
||||
#endif
|
||||
|
||||
MRS r3, PSP ; Pickup thread stack pointer
|
||||
STR r3, [r2, #0xB0] ; Save thread stack pointer
|
||||
|
||||
; Build kernel stack by copying thread stack two registers at a time
|
||||
ADD r3, r3, #32 ; start at bottom of hardware stack
|
||||
LDMDB r3!,{r1-r2} ;
|
||||
STMDB r0!,{r1-r2} ;
|
||||
LDMDB r3!,{r1-r2} ;
|
||||
STMDB r0!,{r1-r2} ;
|
||||
LDMDB r3!,{r1-r2} ;
|
||||
STMDB r0!,{r1-r2} ;
|
||||
LDMDB r3!,{r1-r2} ;
|
||||
STMDB r0!,{r1-r2} ;
|
||||
|
||||
MSR PSP, r0 ; Set kernel stack pointer
|
||||
|
||||
_tx_skip_kernel_stack_enter:
|
||||
MRS r0, CONTROL ; Pickup current CONTROL register
|
||||
BIC r0, r0, #1 ; Clear the UNPRIV bit
|
||||
MSR CONTROL, r0 ; Setup new CONTROL register
|
||||
BX lr ; Return to thread
|
||||
|
||||
_tx_thread_user_return:
|
||||
|
||||
LDR r2, =_txm_module_user_mode_exit-1 ; Subtract 1 because of THUMB mode.
|
||||
CMP r1, r2 ; Did we come from user_mode_exit?
|
||||
IT NE ; If no (not equal), then...
|
||||
BXNE lr ; return from where we came
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r2, [r1] ; Pickup current thread pointer
|
||||
LDR r1, [r2, #0x9C] ; Pick up user mode
|
||||
STR r1, [r2, #0x98] ; Set the current user mode selection for thread
|
||||
|
||||
; If there is memory protection, use kernel stack
|
||||
LDR r0, [r2, #0x90] ; Load the module instance ptr
|
||||
LDR r0, [r0, #0x0C] ; Load the module property flags
|
||||
TST r0, #2 ; Check if memory protected
|
||||
BEQ _tx_skip_kernel_stack_exit
|
||||
|
||||
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
|
||||
LDR r0, [r2, #0xB4] ; Load the module thread stack start
|
||||
LDR r1, [r2, #0xB8] ; Load the module thread stack end
|
||||
LDR r3, [r2, #0xBC] ; Load the module thread stack size
|
||||
STR r0, [r2, #12] ; Set stack start
|
||||
STR r1, [r2, #16] ; Set stack end
|
||||
STR r3, [r2, #20] ; Set stack size
|
||||
#endif
|
||||
LDR r0, [r2, #0xB0] ; Load the module thread stack pointer
|
||||
MRS r3, PSP ; Pickup kernel stack pointer
|
||||
|
||||
; Copy kernel hardware stack to module thread stack.
|
||||
LDM r3!,{r1-r2}
|
||||
STM r0!,{r1-r2}
|
||||
LDM r3!,{r1-r2}
|
||||
STM r0!,{r1-r2}
|
||||
LDM r3!,{r1-r2}
|
||||
STM r0!,{r1-r2}
|
||||
LDM r3!,{r1-r2}
|
||||
STM r0!,{r1-r2}
|
||||
SUB r0, r0, #32 ; Subtract 32 to get back to top of stack
|
||||
MSR PSP, r0 ; Set thread stack pointer
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r2, [r1] ; Pickup current thread pointer
|
||||
LDR r1, [r2, #0x9C] ; Pick up user mode
|
||||
|
||||
_tx_skip_kernel_stack_exit:
|
||||
MRS r0, CONTROL ; Pickup current CONTROL register
|
||||
ORR r0, r0, r1 ; OR in the user mode bit
|
||||
MSR CONTROL, r0 ; Setup new CONTROL register
|
||||
BX lr ; Return to thread
|
||||
;}
|
||||
|
||||
;
|
||||
; /* Kernel entry function from user mode. */
|
||||
;
|
||||
EXTERN _txm_module_manager_kernel_dispatch
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(5)
|
||||
THUMB
|
||||
ALIGNROM 5
|
||||
;VOID _txm_module_manager_user_mode_entry(VOID)
|
||||
;{
|
||||
PUBLIC _txm_module_manager_user_mode_entry
|
||||
_txm_module_manager_user_mode_entry:
|
||||
SVC 1 ; Enter kernel
|
||||
_txm_module_priv:
|
||||
; At this point, we are out of user mode. The original LR has been saved in the
|
||||
; thread control block. Simply call the kernel dispatch function.
|
||||
BL _txm_module_manager_kernel_dispatch
|
||||
|
||||
; Pickup the original LR value while still in privileged mode
|
||||
LDR r2, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r3, [r2] ; Pickup current thread pointer
|
||||
LDR lr, [r3, #0xA0] ; Pickup saved LR from original call
|
||||
|
||||
SVC 2 ; Exit kernel and return to user mode
|
||||
_txm_module_user_mode_exit:
|
||||
BX lr ; Return to the caller
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
;}
|
||||
END
|
||||
@@ -0,0 +1,135 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_stack_build Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* William E. Lamie, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function builds a stack frame on the supplied thread's stack. */
|
||||
;/* The stack frame results in a fake interrupt return to the supplied */
|
||||
;/* function pointer. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* thread_ptr Pointer to thread control blk */
|
||||
;/* function_ptr Pointer to return function */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* _tx_thread_create Create thread service */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
|
||||
;{
|
||||
PUBLIC _tx_thread_stack_build
|
||||
_tx_thread_stack_build:
|
||||
;
|
||||
;
|
||||
; /* Build a fake interrupt frame. The form of the fake interrupt stack
|
||||
; on the Cortex-M should look like the following after it is built:
|
||||
;
|
||||
; Stack Top:
|
||||
; LR Interrupted LR (LR at time of PENDSV)
|
||||
; r4 Initial value for r4
|
||||
; r5 Initial value for r5
|
||||
; r6 Initial value for r6
|
||||
; r7 Initial value for r7
|
||||
; r8 Initial value for r8
|
||||
; r9 Initial value for r9
|
||||
; r10 Initial value for r10
|
||||
; r11 Initial value for r11
|
||||
; r0 Initial value for r0 (Hardware stack starts here!!)
|
||||
; r1 Initial value for r1
|
||||
; r2 Initial value for r2
|
||||
; r3 Initial value for r3
|
||||
; r12 Initial value for r12
|
||||
; lr Initial value for lr
|
||||
; pc Initial value for pc
|
||||
; xPSR Initial value for xPSR
|
||||
;
|
||||
; Stack Bottom: (higher memory address) */
|
||||
;
|
||||
LDR r2, [r0, #16] ; Pickup end of stack area
|
||||
BIC r2, r2, #0x7 ; Align frame for 8-byte alignment
|
||||
SUB r2, r2, #68 ; Subtract frame size
|
||||
LDR r3, =0xFFFFFFFD ; Build initial LR value
|
||||
STR r3, [r2, #0] ; Save on the stack
|
||||
;
|
||||
; /* Actually build the stack frame. */
|
||||
;
|
||||
MOV r3, #0 ; Build initial register value
|
||||
STR r3, [r2, #4] ; Store initial r4
|
||||
STR r3, [r2, #8] ; Store initial r5
|
||||
STR r3, [r2, #12] ; Store initial r6
|
||||
STR r3, [r2, #16] ; Store initial r7
|
||||
STR r3, [r2, #20] ; Store initial r8
|
||||
STR r3, [r2, #24] ; Store initial r9
|
||||
STR r3, [r2, #28] ; Store initial r10
|
||||
STR r3, [r2, #32] ; Store initial r11
|
||||
;
|
||||
; /* Hardware stack follows. */
|
||||
;
|
||||
STR r3, [r2, #36] ; Store initial r0
|
||||
STR r3, [r2, #40] ; Store initial r1
|
||||
STR r3, [r2, #44] ; Store initial r2
|
||||
STR r3, [r2, #48] ; Store initial r3
|
||||
STR r3, [r2, #52] ; Store initial r12
|
||||
MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value
|
||||
STR r3, [r2, #56] ; Store initial lr
|
||||
STR r1, [r2, #60] ; Store initial pc
|
||||
MOV r3, #0x01000000 ; Only T-bit need be set
|
||||
STR r3, [r2, #64] ; Store initial xPSR
|
||||
;
|
||||
; /* Setup stack pointer. */
|
||||
; thread_ptr -> tx_thread_stack_ptr = r2;
|
||||
;
|
||||
STR r2, [r0, #8] ; Save stack pointer in thread's
|
||||
; control block
|
||||
BX lr ; Return to caller
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Thread */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_system_return Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* William E. Lamie, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function is target processor specific. It is used to transfer */
|
||||
;/* control from a thread back to the ThreadX system. Only a */
|
||||
;/* minimal context is saved since the compiler assumes temp registers */
|
||||
;/* are going to get slicked by a function call anyway. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* _tx_thread_schedule Thread scheduling loop */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* ThreadX components */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_system_return(VOID)
|
||||
;{
|
||||
PUBLIC _tx_thread_system_return
|
||||
_tx_thread_system_return??rA:
|
||||
_tx_thread_system_return:
|
||||
;
|
||||
; /* Return to real scheduler via PendSV. Note that this routine is often
|
||||
; replaced with in-line assembly in tx_port.h to improved performance. */
|
||||
;
|
||||
MOV r0, #0x10000000 ; Load PENDSVSET bit
|
||||
MOV r1, #0xE000E000 ; Load NVIC base
|
||||
STR r0, [r1, #0xD04] ; Set PENDSVBIT in ICSR
|
||||
MRS r0, IPSR ; Pickup IPSR
|
||||
CMP r0, #0 ; Is it a thread returning?
|
||||
BNE _isr_context ; If ISR, skip interrupt enable
|
||||
MRS r1, PRIMASK ; Thread context returning, pickup PRIMASK
|
||||
CPSIE i ; Enable interrupts
|
||||
MSR PRIMASK, r1 ; Restore original interrupt posture
|
||||
_isr_context:
|
||||
BX lr ; Return to caller
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
;/* and in the root directory of this software. */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;/** */
|
||||
;/** ThreadX Component */
|
||||
;/** */
|
||||
;/** Timer */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_timer.h"
|
||||
;#include "tx_thread.h"
|
||||
;
|
||||
;
|
||||
;Define Assembly language external references...
|
||||
;
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_timer_system_clock
|
||||
EXTERN _tx_timer_current_ptr
|
||||
EXTERN _tx_timer_list_start
|
||||
EXTERN _tx_timer_list_end
|
||||
EXTERN _tx_timer_expired_time_slice
|
||||
EXTERN _tx_timer_expired
|
||||
EXTERN _tx_thread_time_slice
|
||||
EXTERN _tx_timer_expiration_process
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_thread_execute_ptr
|
||||
EXTERN _tx_thread_preempt_disable
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_timer_interrupt Cortex-M3/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* William E. Lamie, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function processes the hardware timer interrupt. This */
|
||||
;/* processing includes incrementing the system clock and checking for */
|
||||
;/* time slice and/or timer expiration. If either is found, the */
|
||||
;/* expiration functions are called. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* _tx_timer_expiration_process Timer expiration processing */
|
||||
;/* _tx_thread_time_slice Time slice interrupted thread */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* interrupt vector */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_timer_interrupt(VOID)
|
||||
;{
|
||||
PUBLIC _tx_timer_interrupt
|
||||
_tx_timer_interrupt:
|
||||
;
|
||||
; /* Upon entry to this routine, it is assumed that the compiler scratch registers are available
|
||||
; for use. */
|
||||
;
|
||||
; /* Increment the system clock. */
|
||||
; _tx_timer_system_clock++;
|
||||
;
|
||||
MOV32 r1, _tx_timer_system_clock ; Pickup address of system clock
|
||||
LDR r0, [r1, #0] ; Pickup system clock
|
||||
ADD r0, r0, #1 ; Increment system clock
|
||||
STR r0, [r1, #0] ; Store new system clock
|
||||
;
|
||||
; /* Test for time-slice expiration. */
|
||||
; if (_tx_timer_time_slice)
|
||||
; {
|
||||
;
|
||||
MOV32 r3, _tx_timer_time_slice ; Pickup address of time-slice
|
||||
LDR r2, [r3, #0] ; Pickup time-slice
|
||||
CBZ r2, __tx_timer_no_time_slice ; Is it non-active?
|
||||
; Yes, skip time-slice processing
|
||||
;
|
||||
; /* Decrement the time_slice. */
|
||||
; _tx_timer_time_slice--;
|
||||
;
|
||||
SUB r2, r2, #1 ; Decrement the time-slice
|
||||
STR r2, [r3, #0] ; Store new time-slice value
|
||||
;
|
||||
; /* Check for expiration. */
|
||||
; if (__tx_timer_time_slice == 0)
|
||||
;
|
||||
CBNZ r2, __tx_timer_no_time_slice ; Has it expired?
|
||||
;
|
||||
; /* Set the time-slice expired flag. */
|
||||
; _tx_timer_expired_time_slice = TX_TRUE;
|
||||
;
|
||||
MOV32 r3, _tx_timer_expired_time_slice ; Pickup address of expired flag
|
||||
MOV r0, #1 ; Build expired value
|
||||
STR r0, [r3, #0] ; Set time-slice expiration flag
|
||||
;
|
||||
; }
|
||||
;
|
||||
__tx_timer_no_time_slice:
|
||||
;
|
||||
; /* Test for timer expiration. */
|
||||
; if (*_tx_timer_current_ptr)
|
||||
; {
|
||||
;
|
||||
MOV32 r1, _tx_timer_current_ptr ; Pickup current timer pointer address
|
||||
LDR r0, [r1, #0] ; Pickup current timer
|
||||
LDR r2, [r0, #0] ; Pickup timer list entry
|
||||
CBZ r2, __tx_timer_no_timer ; Is there anything in the list?
|
||||
; No, just increment the timer
|
||||
;
|
||||
; /* Set expiration flag. */
|
||||
; _tx_timer_expired = TX_TRUE;
|
||||
;
|
||||
MOV32 r3, _tx_timer_expired ; Pickup expiration flag address
|
||||
MOV r2, #1 ; Build expired value
|
||||
STR r2, [r3, #0] ; Set expired flag
|
||||
B __tx_timer_done ; Finished timer processing
|
||||
;
|
||||
; }
|
||||
; else
|
||||
; {
|
||||
__tx_timer_no_timer:
|
||||
;
|
||||
; /* No timer expired, increment the timer pointer. */
|
||||
; _tx_timer_current_ptr++;
|
||||
;
|
||||
ADD r0, r0, #4 ; Move to next timer
|
||||
;
|
||||
; /* Check for wrap-around. */
|
||||
; if (_tx_timer_current_ptr == _tx_timer_list_end)
|
||||
;
|
||||
MOV32 r3, _tx_timer_list_end ; Pickup addr of timer list end
|
||||
LDR r2, [r3, #0] ; Pickup list end
|
||||
CMP r0, r2 ; Are we at list end?
|
||||
BNE __tx_timer_skip_wrap ; No, skip wrap-around logic
|
||||
;
|
||||
; /* Wrap to beginning of list. */
|
||||
; _tx_timer_current_ptr = _tx_timer_list_start;
|
||||
;
|
||||
MOV32 r3, _tx_timer_list_start ; Pickup addr of timer list start
|
||||
LDR r0, [r3, #0] ; Set current pointer to list start
|
||||
;
|
||||
__tx_timer_skip_wrap:
|
||||
;
|
||||
STR r0, [r1, #0] ; Store new current timer pointer
|
||||
; }
|
||||
;
|
||||
__tx_timer_done:
|
||||
;
|
||||
;
|
||||
; /* See if anything has expired. */
|
||||
; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
|
||||
; {
|
||||
;
|
||||
MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of expired flag
|
||||
LDR r2, [r3, #0] ; Pickup time-slice expired flag
|
||||
CBNZ r2, __tx_something_expired ; Did a time-slice expire?
|
||||
; If non-zero, time-slice expired
|
||||
MOV32 r1, _tx_timer_expired ; Pickup addr of other expired flag
|
||||
LDR r0, [r1, #0] ; Pickup timer expired flag
|
||||
CBZ r0, __tx_timer_nothing_expired ; Did a timer expire?
|
||||
; No, nothing expired
|
||||
;
|
||||
__tx_something_expired:
|
||||
;
|
||||
;
|
||||
STMDB sp!, {r0, lr} ; Save the lr register on the stack
|
||||
; and save r0 just to keep 8-byte alignment
|
||||
;
|
||||
; /* Did a timer expire? */
|
||||
; if (_tx_timer_expired)
|
||||
; {
|
||||
;
|
||||
MOV32 r1, _tx_timer_expired ; Pickup addr of expired flag
|
||||
LDR r0, [r1, #0] ; Pickup timer expired flag
|
||||
CBZ r0, __tx_timer_dont_activate ; Check for timer expiration
|
||||
; If not set, skip timer activation
|
||||
;
|
||||
; /* Process timer expiration. */
|
||||
; _tx_timer_expiration_process();
|
||||
;
|
||||
BL _tx_timer_expiration_process ; Call the timer expiration handling routine
|
||||
;
|
||||
; }
|
||||
__tx_timer_dont_activate:
|
||||
;
|
||||
; /* Did time slice expire? */
|
||||
; if (_tx_timer_expired_time_slice)
|
||||
; {
|
||||
;
|
||||
MOV32 r3, _tx_timer_expired_time_slice ; Pickup addr of time-slice expired
|
||||
LDR r2, [r3, #0] ; Pickup the actual flag
|
||||
CBZ r2, __tx_timer_not_ts_expiration ; See if the flag is set
|
||||
; No, skip time-slice processing
|
||||
;
|
||||
; /* Time slice interrupted thread. */
|
||||
; _tx_thread_time_slice();
|
||||
|
||||
BL _tx_thread_time_slice ; Call time-slice processing
|
||||
MOV32 r0, _tx_thread_preempt_disable ; Build address of preempt disable flag
|
||||
LDR r1, [r0] ; Is the preempt disable flag set?
|
||||
CBNZ r1, __tx_timer_skip_time_slice ; Yes, skip the PendSV logic
|
||||
MOV32 r0, _tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r1, [r0] ; Pickup the current thread pointer
|
||||
MOV32 r2, _tx_thread_execute_ptr ; Build execute thread pointer address
|
||||
LDR r3, [r2] ; Pickup the execute thread pointer
|
||||
MOV32 r0, 0xE000ED04 ; Build address of control register
|
||||
MOV32 r2, 0x10000000 ; Build value for PendSV bit
|
||||
CMP r1, r3 ; Are they the same?
|
||||
BEQ __tx_timer_skip_time_slice ; If the same, there was no time-slice performed
|
||||
STR r2, [r0] ; Not the same, issue the PendSV for preemption
|
||||
__tx_timer_skip_time_slice:
|
||||
;
|
||||
; }
|
||||
;
|
||||
__tx_timer_not_ts_expiration:
|
||||
;
|
||||
LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for
|
||||
; the 8-byte stack alignment
|
||||
;
|
||||
; }
|
||||
;
|
||||
__tx_timer_nothing_expired:
|
||||
|
||||
DSB ; Complete all memory access
|
||||
BX lr ; Return to caller
|
||||
;
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Module Manager */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_power_of_two_block_size Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function calculates a power of two size at or immediately above*/
|
||||
/* the input size and returns it to the caller. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* size Block size */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* calculated size Rounded up to power of two */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _txm_module_manager_alignment_adjust Adjust alignment for Cortex-M */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
ULONG _txm_power_of_two_block_size(ULONG size)
|
||||
{
|
||||
/* Check for 0 size. */
|
||||
if(size == 0)
|
||||
return 0;
|
||||
|
||||
/* Minimum MPU block size is 32. */
|
||||
if(size <= 32)
|
||||
return 32;
|
||||
|
||||
/* Bit twiddling trick to round to next high power of 2
|
||||
(if original size is power of 2, it will return original size. Perfect!) */
|
||||
size--;
|
||||
size |= size >> 1;
|
||||
size |= size >> 2;
|
||||
size |= size >> 4;
|
||||
size |= size >> 8;
|
||||
size |= size >> 16;
|
||||
size++;
|
||||
|
||||
/* Return a power of 2 size at or above the input size. */
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_alignment_adjust Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function adjusts the alignment and size of the code and data */
|
||||
/* section for a given module implementation. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_preamble Pointer to module preamble */
|
||||
/* code_size Size of the code area (updated) */
|
||||
/* code_alignment Code area alignment (updated) */
|
||||
/* data_size Size of data area (updated) */
|
||||
/* data_alignment Data area alignment (updated) */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _txm_power_of_two_block_size Calculate power of two size */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Initial thread stack frame */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble,
|
||||
ULONG *code_size,
|
||||
ULONG *code_alignment,
|
||||
ULONG *data_size,
|
||||
ULONG *data_alignment)
|
||||
{
|
||||
|
||||
ULONG local_code_size;
|
||||
ULONG local_code_alignment;
|
||||
ULONG local_data_size;
|
||||
ULONG local_data_alignment;
|
||||
ULONG code_block_size;
|
||||
ULONG data_block_size;
|
||||
ULONG code_size_accum;
|
||||
ULONG data_size_accum;
|
||||
|
||||
/* Copy the input parameters into local variables for ease of use. */
|
||||
local_code_size = *code_size;
|
||||
local_code_alignment = *code_alignment;
|
||||
local_data_size = *data_size;
|
||||
local_data_alignment = *data_alignment;
|
||||
|
||||
|
||||
/* Test for external memory enabled in preamble. */
|
||||
if(module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS)
|
||||
{
|
||||
/* External/shared memory enabled. TXM_MODULE_MANAGER_CODE_MPU_ENTRIES-1 code entries will be used. */
|
||||
if (local_code_size <= (32*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 32 is best. */
|
||||
code_block_size = 32;
|
||||
}
|
||||
else if (local_code_size <= (64*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 64 is best. */
|
||||
code_block_size = 64;
|
||||
}
|
||||
else if (local_code_size <= (128*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 128 is best. */
|
||||
code_block_size = 128;
|
||||
}
|
||||
else if (local_code_size <= (256*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 256 is best. */
|
||||
code_block_size = 256;
|
||||
}
|
||||
else if (local_code_size <= (512*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 512 is best. */
|
||||
code_block_size = 512;
|
||||
}
|
||||
else if (local_code_size <= (1024*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 1024 is best. */
|
||||
code_block_size = 1024;
|
||||
}
|
||||
else if (local_code_size <= (2048*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 2048 is best. */
|
||||
code_block_size = 2048;
|
||||
}
|
||||
else if (local_code_size <= (4096*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 4096 is best. */
|
||||
code_block_size = 4096;
|
||||
}
|
||||
else if (local_code_size <= (8192*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 8192 is best. */
|
||||
code_block_size = 8192;
|
||||
}
|
||||
else if (local_code_size <= (16384*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 16384 is best. */
|
||||
code_block_size = 16384;
|
||||
}
|
||||
else if (local_code_size <= (32768*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 32768 is best. */
|
||||
code_block_size = 32768;
|
||||
}
|
||||
else if (local_code_size <= (65536*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 65536 is best. */
|
||||
code_block_size = 65536;
|
||||
}
|
||||
else if (local_code_size <= (131072*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 131072 is best. */
|
||||
code_block_size = 131072;
|
||||
}
|
||||
else if (local_code_size <= (262144*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 262144 is best. */
|
||||
code_block_size = 262144;
|
||||
}
|
||||
else if (local_code_size <= (524288*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 524288 is best. */
|
||||
code_block_size = 524288;
|
||||
}
|
||||
else if (local_code_size <= (1048576*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 1048576 is best. */
|
||||
code_block_size = 1048576;
|
||||
}
|
||||
else if (local_code_size <= (2097152*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 2097152 is best. */
|
||||
code_block_size = 2097152;
|
||||
}
|
||||
else if (local_code_size <= (4194304*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1)))
|
||||
{
|
||||
/* Block size of 4194304 is best. */
|
||||
code_block_size = 4194304;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just set block size to 32MB just to create an allocation error! */
|
||||
code_block_size = 33554432;
|
||||
}
|
||||
|
||||
/* Calculate the new code size. */
|
||||
local_code_size = code_block_size*(TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1);
|
||||
|
||||
/* Determine if the code block size is greater than the current alignment. If so, use block size
|
||||
as the alignment. */
|
||||
if (code_block_size > local_code_alignment)
|
||||
local_code_alignment = code_block_size;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Determine code block sizes. Minimize the alignment requirement.
|
||||
There are 4 MPU code entries available. The following is how the code size
|
||||
will be distributed:
|
||||
1. 1/4 of the largest power of two that is greater than or equal to code size.
|
||||
2. 1/4 of the largest power of two that is greater than or equal to code size.
|
||||
3. Largest power of 2 that fits in the remaining space.
|
||||
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
|
||||
local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2;
|
||||
code_size_accum = local_code_alignment + local_code_alignment;
|
||||
code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1);
|
||||
code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum);
|
||||
local_code_size = code_size_accum;
|
||||
}
|
||||
|
||||
/* Determine the best data block size, which in our case is the minimal alignment. */
|
||||
if (local_data_size <= (32*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
|
||||
/* Block size of 32 is best. */
|
||||
data_block_size = 32;
|
||||
}
|
||||
else if (local_data_size <= (64*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 64 is best. */
|
||||
data_block_size = 64;
|
||||
}
|
||||
else if (local_data_size <= (128*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 128 is best. */
|
||||
data_block_size = 128;
|
||||
}
|
||||
else if (local_data_size <= (256*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 256 is best. */
|
||||
data_block_size = 256;
|
||||
}
|
||||
else if (local_data_size <= (512*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 512 is best. */
|
||||
data_block_size = 512;
|
||||
}
|
||||
else if (local_data_size <= (1024*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 1024 is best. */
|
||||
data_block_size = 1024;
|
||||
}
|
||||
else if (local_data_size <= (2048*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 2048 is best. */
|
||||
data_block_size = 2048;
|
||||
}
|
||||
else if (local_data_size <= (4096*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 4096 is best. */
|
||||
data_block_size = 4096;
|
||||
}
|
||||
else if (local_data_size <= (8192*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 8192 is best. */
|
||||
data_block_size = 8192;
|
||||
}
|
||||
else if (local_data_size <= (16384*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 16384 is best. */
|
||||
data_block_size = 16384;
|
||||
}
|
||||
else if (local_data_size <= (32768*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 32768 is best. */
|
||||
data_block_size = 32768;
|
||||
}
|
||||
else if (local_data_size <= (65536*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 65536 is best. */
|
||||
data_block_size = 65536;
|
||||
}
|
||||
else if (local_data_size <= (131072*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 131072 is best. */
|
||||
data_block_size = 131072;
|
||||
}
|
||||
else if (local_data_size <= (262144*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 262144 is best. */
|
||||
data_block_size = 262144;
|
||||
}
|
||||
else if (local_data_size <= (524288*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 524288 is best. */
|
||||
data_block_size = 524288;
|
||||
}
|
||||
else if (local_data_size <= (1048576*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 1048576 is best. */
|
||||
data_block_size = 1048576;
|
||||
}
|
||||
else if (local_data_size <= (2097152*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 2097152 is best. */
|
||||
data_block_size = 2097152;
|
||||
}
|
||||
else if (local_data_size <= (4194304*TXM_MODULE_MANAGER_DATA_MPU_ENTRIES))
|
||||
{
|
||||
/* Block size of 4194304 is best. */
|
||||
data_block_size = 4194304;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Just set data block size to 32MB just to create an allocation error! */
|
||||
data_block_size = 33554432;
|
||||
}
|
||||
|
||||
/* Calculate the new data size. */
|
||||
data_size_accum = data_block_size;
|
||||
while(data_size_accum < local_data_size)
|
||||
{
|
||||
data_size_accum += data_block_size;
|
||||
}
|
||||
local_data_size = data_size_accum;
|
||||
|
||||
/* Determine if the data block size is greater than the current alignment. If so, use block size
|
||||
as the alignment. */
|
||||
if (data_block_size > local_data_alignment)
|
||||
local_data_alignment = data_block_size;
|
||||
|
||||
/* Return all the information to the caller. */
|
||||
*code_size = local_code_size;
|
||||
*code_alignment = local_code_alignment;
|
||||
*data_size = local_data_size;
|
||||
*data_alignment = local_data_alignment;
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the 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 Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance,
|
||||
VOID *start_address,
|
||||
ULONG length,
|
||||
UINT attributes)
|
||||
{
|
||||
|
||||
ULONG block_size;
|
||||
ULONG region_size;
|
||||
ULONG subregion_bits;
|
||||
ULONG address;
|
||||
UINT attributes_check = 0;
|
||||
TXM_MODULE_PREAMBLE *module_preamble;
|
||||
|
||||
/* Determine if the module manager has not been initialized yet. */
|
||||
if (_txm_module_manager_ready != TX_TRUE)
|
||||
{
|
||||
|
||||
/* Module manager has not been initialized. */
|
||||
return(TX_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
/* Determine if the module is valid. */
|
||||
if (module_instance == TX_NULL)
|
||||
{
|
||||
|
||||
/* Invalid module pointer. */
|
||||
return(TX_PTR_ERROR);
|
||||
}
|
||||
|
||||
/* Get module manager protection mutex. */
|
||||
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if the module instance is valid. */
|
||||
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
|
||||
{
|
||||
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Invalid module pointer. */
|
||||
return(TX_PTR_ERROR);
|
||||
}
|
||||
|
||||
/* Determine if the module instance is in the loaded state. */
|
||||
if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED)
|
||||
{
|
||||
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return error if the module is not ready. */
|
||||
return(TX_START_ERROR);
|
||||
}
|
||||
|
||||
/* Check if preamble shared mem and mem protection property bits are set. */
|
||||
module_preamble = module_instance -> txm_module_instance_preamble_ptr;
|
||||
if((module_preamble -> txm_module_preamble_property_flags & (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS))
|
||||
!= (TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS))
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return error if bit not set. */
|
||||
return(TXM_MODULE_INVALID_PROPERTIES);
|
||||
}
|
||||
|
||||
/* Start address and length must adhere to Cortex-M MPU.
|
||||
The address must align with the block size. */
|
||||
|
||||
block_size = _txm_power_of_two_block_size(length);
|
||||
address = (ULONG) start_address;
|
||||
if(address != (address & ~(block_size - 1)))
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return alignment error. */
|
||||
return(TXM_MODULE_ALIGNMENT_ERROR);
|
||||
}
|
||||
|
||||
/* At this point, we have a valid address and block size.
|
||||
Set up MPU registers. */
|
||||
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] = address | TXM_MODULE_MANAGER_SHARED_MPU_REGION | 0x10;
|
||||
|
||||
/* Calculate the region size. */
|
||||
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
|
||||
/* Calculate the subregion bits. */
|
||||
subregion_bits = _txm_module_manager_calculate_srd_bits(block_size, length);
|
||||
|
||||
/* Check for valid attributes. */
|
||||
if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE)
|
||||
{
|
||||
attributes_check = TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT;
|
||||
}
|
||||
|
||||
/* Build register with attributes. */
|
||||
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX+1] = region_size | subregion_bits | attributes_check | 0x12070001;
|
||||
|
||||
/* Keep track of shared memory address and length in module instance. */
|
||||
module_instance -> txm_module_instance_shared_memory_address = address;
|
||||
module_instance -> txm_module_instance_shared_memory_length = length;
|
||||
|
||||
/* Recalculate MPU settings. */
|
||||
_txm_module_manager_mm_register_setup(module_instance);
|
||||
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return success. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the 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 Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
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,86 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** 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 Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
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,683 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the 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"
|
||||
#include "txm_module_manager_util.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_region_size_get Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function converts the region size in bytes to the block size */
|
||||
/* for the Cortex-M3 MPU specification. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* block_size Size of the block in bytes */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* MPU size specification */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _txm_module_manager_mm_register_setup */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
ULONG _txm_module_manager_region_size_get(ULONG block_size)
|
||||
{
|
||||
|
||||
ULONG return_value;
|
||||
|
||||
|
||||
/* Process relative to the input block size. */
|
||||
if (block_size == 32)
|
||||
{
|
||||
return_value = 0x04;
|
||||
}
|
||||
else if (block_size == 64)
|
||||
{
|
||||
return_value = 0x05;
|
||||
}
|
||||
else if (block_size == 128)
|
||||
{
|
||||
return_value = 0x06;
|
||||
}
|
||||
else if (block_size == 256)
|
||||
{
|
||||
return_value = 0x07;
|
||||
}
|
||||
else if (block_size == 512)
|
||||
{
|
||||
return_value = 0x08;
|
||||
}
|
||||
else if (block_size == 1024)
|
||||
{
|
||||
return_value = 0x09;
|
||||
}
|
||||
else if (block_size == 2048)
|
||||
{
|
||||
return_value = 0x0A;
|
||||
}
|
||||
else if (block_size == 4096)
|
||||
{
|
||||
return_value = 0x0B;
|
||||
}
|
||||
else if (block_size == 8192)
|
||||
{
|
||||
return_value = 0x0C;
|
||||
}
|
||||
else if (block_size == 16384)
|
||||
{
|
||||
return_value = 0x0D;
|
||||
}
|
||||
else if (block_size == 32768)
|
||||
{
|
||||
return_value = 0x0E;
|
||||
}
|
||||
else if (block_size == 65536)
|
||||
{
|
||||
return_value = 0x0F;
|
||||
}
|
||||
else if (block_size == 131072)
|
||||
{
|
||||
return_value = 0x10;
|
||||
}
|
||||
else if (block_size == 262144)
|
||||
{
|
||||
return_value = 0x11;
|
||||
}
|
||||
else if (block_size == 524288)
|
||||
{
|
||||
return_value = 0x12;
|
||||
}
|
||||
else if (block_size == 1048576)
|
||||
{
|
||||
return_value = 0x13;
|
||||
}
|
||||
else if (block_size == 2097152)
|
||||
{
|
||||
return_value = 0x14;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Max 4MB MPU pages for modules. */
|
||||
return_value = 0x15;
|
||||
}
|
||||
|
||||
return(return_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_calculate_srd_bits Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function calculates the SRD bits that need to be set to */
|
||||
/* protect "length" bytes in a block. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* block_size Size of the block in bytes */
|
||||
/* length Actual length in bytes */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* SRD bits to be OR'ed with region attribute register. */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _txm_module_manager_mm_register_setup */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
ULONG _txm_module_manager_calculate_srd_bits(ULONG block_size, ULONG length)
|
||||
{
|
||||
|
||||
ULONG srd_bits = 0;
|
||||
UINT srd_bit_index;
|
||||
|
||||
/* length is smaller than block_size, set SRD bits if block_size is 256 or more. */
|
||||
if((block_size >= 256) && (length < block_size))
|
||||
{
|
||||
/* Divide block_size by 8 by shifting right 3. Result is size of subregion. */
|
||||
block_size = block_size >> 3;
|
||||
|
||||
/* Set SRD index into attribute register. */
|
||||
srd_bit_index = 8;
|
||||
|
||||
/* If subregion overlaps length, move to the next subregion. */
|
||||
while(length > block_size)
|
||||
{
|
||||
length = length - block_size;
|
||||
srd_bit_index++;
|
||||
}
|
||||
/* Check for a portion of code remaining. */
|
||||
if(length)
|
||||
{
|
||||
srd_bit_index++;
|
||||
}
|
||||
|
||||
/* Set unused subregion bits. */
|
||||
while(srd_bit_index < 16)
|
||||
{
|
||||
srd_bits = srd_bits | (0x1 << srd_bit_index);
|
||||
srd_bit_index++;
|
||||
}
|
||||
}
|
||||
|
||||
return(srd_bits);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_mm_register_setup Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function sets up the Cortex-M3 MPU register definitions based */
|
||||
/* on the module's memory characteristics. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Pointer to module instance */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* MPU specifications for module in module_instance */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _txm_module_manager_region_size_get */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _txm_module_manager_thread_create */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
|
||||
{
|
||||
|
||||
ULONG code_address;
|
||||
ULONG code_size;
|
||||
ULONG data_address;
|
||||
ULONG data_size;
|
||||
ULONG start_stop_stack_size;
|
||||
ULONG callback_stack_size;
|
||||
ULONG block_size;
|
||||
ULONG base_address_register;
|
||||
ULONG base_attribute_register;
|
||||
ULONG region_size;
|
||||
ULONG srd_bits = 0;
|
||||
UINT mpu_register = 0;
|
||||
UINT mpu_table_index;
|
||||
UINT i;
|
||||
|
||||
|
||||
/* Setup the first region for the ThreadX trampoline code. */
|
||||
/* Set base register to user mode entry, which is guaranteed to be at least 32-byte aligned. */
|
||||
base_address_register = (ULONG) _txm_module_manager_user_mode_entry;
|
||||
/* Mask address to proper range, region 0, set Valid bit. */
|
||||
base_address_register = (base_address_register & 0xFFFFFFE0) | mpu_register | 0x10;
|
||||
module_instance -> txm_module_instance_mpu_registers[0] = base_address_register;
|
||||
/* Attributes: read only, write-back, shareable, size 32 bytes, region enabled. */
|
||||
module_instance -> txm_module_instance_mpu_registers[1] = 0x06070009;
|
||||
|
||||
/* Initialize the MPU register. */
|
||||
mpu_register = 1;
|
||||
|
||||
/* Initialize the MPU table index. */
|
||||
mpu_table_index = 2;
|
||||
|
||||
/* Setup values for code area. */
|
||||
code_address = (ULONG) module_instance -> txm_module_instance_code_start;
|
||||
code_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_code_size;
|
||||
|
||||
|
||||
/* Check if shared memory was set up. If so, only 3 entries are available for
|
||||
code protection. If not set up, 4 code entries are available. */
|
||||
if(module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_SHARED_MPU_INDEX] == 0)
|
||||
{
|
||||
/* Determine code block sizes. Minimize the alignment requirement.
|
||||
There are 4 MPU code entries available. The following is how the code size
|
||||
will be distributed:
|
||||
1. 1/4 of the largest power of two that is greater than or equal to code size.
|
||||
2. 1/4 of the largest power of two that is greater than or equal to code size.
|
||||
3. Largest power of 2 that fits in the remaining space.
|
||||
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
|
||||
|
||||
/* Now loop through to setup MPU protection for the code area. */
|
||||
for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES; i++)
|
||||
{
|
||||
/* First two MPU blocks are 1/4 of the largest power of two
|
||||
that is greater than or equal to code size. */
|
||||
if (i < 2)
|
||||
{
|
||||
block_size = _txm_power_of_two_block_size(code_size) >> 2;
|
||||
}
|
||||
|
||||
/* Third MPU block is the largest power of 2 that fits in the remaining space. */
|
||||
else if (i == 2)
|
||||
{
|
||||
/* Subtract (block_size*2) from code_size to calculate remaining space. */
|
||||
code_size = code_size - (block_size << 1);
|
||||
block_size = _txm_power_of_two_block_size(code_size) >> 1;
|
||||
}
|
||||
|
||||
/* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */
|
||||
else
|
||||
{
|
||||
/* Calculate remaining space. */
|
||||
code_size = code_size - block_size;
|
||||
block_size = _txm_power_of_two_block_size(code_size);
|
||||
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size);
|
||||
}
|
||||
|
||||
/* Build the base address register. */
|
||||
base_address_register = (code_address & ~(block_size - 1)) | mpu_register | 0x10;
|
||||
|
||||
/* Calculate the region size information. */
|
||||
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
|
||||
|
||||
/* Build the base attribute register. */
|
||||
base_attribute_register = region_size | srd_bits | 0x06070001;
|
||||
|
||||
/* Setup the MPU Base Address Register. */
|
||||
module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register;
|
||||
|
||||
/* Setup the MPU Base Attribute Register. */
|
||||
module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register;
|
||||
|
||||
/* Adjust the code address. */
|
||||
code_address = code_address + block_size;
|
||||
|
||||
/* Move MPU table index. */
|
||||
mpu_table_index = mpu_table_index + 2;
|
||||
|
||||
/* Increment the MPU register index. */
|
||||
mpu_register++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only 3 code entries available. */
|
||||
else
|
||||
{
|
||||
/* Calculate block size, one code entry taken up by shared memory. */
|
||||
block_size = _txm_power_of_two_block_size(code_size / (TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1));
|
||||
|
||||
/* Calculate the region size information. */
|
||||
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
|
||||
|
||||
/* Now loop through to setup MPU protection for the code area. */
|
||||
for (i = 0; i < TXM_MODULE_MANAGER_CODE_MPU_ENTRIES - 1; i++)
|
||||
{
|
||||
|
||||
/* Build the base address register. */
|
||||
base_address_register = code_address & ~(block_size - 1) | mpu_register | 0x10;
|
||||
|
||||
/* Check if SRD bits need to be set. */
|
||||
if (code_size < block_size)
|
||||
{
|
||||
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size);
|
||||
}
|
||||
|
||||
/* Build the base attribute register. */
|
||||
base_attribute_register = region_size | srd_bits | 0x06070000;
|
||||
|
||||
/* Is there still some code? If so set the region enable bit. */
|
||||
if (code_size)
|
||||
{
|
||||
/* Set the region enable bit. */
|
||||
base_attribute_register = base_attribute_register | 0x1;
|
||||
}
|
||||
/* Setup the MPU Base Address Register. */
|
||||
module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register;
|
||||
|
||||
/* Setup the MPU Base Attribute Register. */
|
||||
module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register;
|
||||
|
||||
/* Adjust the code address. */
|
||||
code_address = code_address + block_size;
|
||||
|
||||
/* Decrement the code size. */
|
||||
if (code_size > block_size)
|
||||
code_size = code_size - block_size;
|
||||
else
|
||||
code_size = 0;
|
||||
|
||||
/* Move MPU table index. */
|
||||
mpu_table_index = mpu_table_index + 2;
|
||||
|
||||
/* Increment the MPU register index. */
|
||||
mpu_register++;
|
||||
}
|
||||
|
||||
/* Adjust indeces to pass over the shared memory entry. */
|
||||
/* Move MPU table index. */
|
||||
mpu_table_index = mpu_table_index + 2;
|
||||
|
||||
/* Increment the MPU register index. */
|
||||
mpu_register++;
|
||||
}
|
||||
|
||||
/* Setup values for data area. */
|
||||
data_address = (ULONG) module_instance -> txm_module_instance_data_start;
|
||||
|
||||
/* Adjust the size of the module elements to be aligned to the default alignment. We do this
|
||||
so that when we partition the allocated memory, we can simply place these regions right beside
|
||||
each other without having to align their pointers. Note this only works when they all have
|
||||
the same alignment. */
|
||||
|
||||
data_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_data_size;
|
||||
start_stop_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_start_stop_stack_size;
|
||||
callback_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_callback_stack_size;
|
||||
|
||||
data_size = ((data_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
|
||||
|
||||
start_stop_stack_size = ((start_stop_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
|
||||
|
||||
callback_stack_size = ((callback_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
|
||||
|
||||
/* Update the data size to include thread stacks. */
|
||||
data_size = data_size + start_stop_stack_size + callback_stack_size;
|
||||
|
||||
|
||||
block_size = _txm_power_of_two_block_size(data_size / TXM_MODULE_MANAGER_DATA_MPU_ENTRIES);
|
||||
|
||||
/* Reset SRD bitfield. */
|
||||
srd_bits = 0;
|
||||
|
||||
/* Calculate the region size information. */
|
||||
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
|
||||
|
||||
/* Now loop through to setup MPU protection for the data area. */
|
||||
for (i = 0; i < TXM_MODULE_MANAGER_DATA_MPU_ENTRIES; i++)
|
||||
{
|
||||
|
||||
/* Build the base address register. */
|
||||
base_address_register = (data_address & ~(block_size - 1)) | mpu_register | 0x10;
|
||||
|
||||
/* Check if SRD bits need to be set. */
|
||||
if (data_size < block_size)
|
||||
{
|
||||
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, data_size);
|
||||
}
|
||||
|
||||
/* Build the base attribute register. */
|
||||
base_attribute_register = region_size | srd_bits | 0x13070000;
|
||||
|
||||
/* Is there still some data? If so set the region enable bit. */
|
||||
if (data_size)
|
||||
{
|
||||
/* Set the region enable bit. */
|
||||
base_attribute_register = base_attribute_register | 0x1;
|
||||
}
|
||||
|
||||
/* Setup the MPU Base Address Register. */
|
||||
module_instance -> txm_module_instance_mpu_registers[mpu_table_index] = base_address_register;
|
||||
|
||||
/* Setup the MPU Base Attribute Register. */
|
||||
module_instance -> txm_module_instance_mpu_registers[mpu_table_index+1] = base_attribute_register;
|
||||
|
||||
/* Adjust the data address. */
|
||||
data_address = data_address + block_size;
|
||||
|
||||
/* Decrement the data size. */
|
||||
if (data_size > block_size)
|
||||
data_size = data_size - block_size;
|
||||
else
|
||||
data_size = 0;
|
||||
|
||||
/* Move MPU table index. */
|
||||
mpu_table_index = mpu_table_index + 2;
|
||||
|
||||
/* Increment the MPU register index. */
|
||||
mpu_register++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_shared_memory_check_outside */
|
||||
/* Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function checks if the specified object is outside shared */
|
||||
/* memory. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Pointer to module instance */
|
||||
/* obj_ptr Pointer to the object */
|
||||
/* obj_size Size of the object */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Whether the object is outside the shared memory region. */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* N/A */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Module dispatch check functions */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UCHAR _txm_module_manager_shared_memory_check_outside(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size)
|
||||
{
|
||||
|
||||
ALIGN_TYPE shared_memory_start;
|
||||
ALIGN_TYPE shared_memory_end;
|
||||
|
||||
shared_memory_start = (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address;
|
||||
shared_memory_end = shared_memory_start + module_instance -> txm_module_instance_shared_memory_length;
|
||||
|
||||
if (TXM_MODULE_MANAGER_CHECK_OUTSIDE_RANGE_EXCLUSIVE(shared_memory_start, shared_memory_end,
|
||||
obj_ptr, obj_size))
|
||||
{
|
||||
return(TX_TRUE);
|
||||
}
|
||||
return(TX_FALSE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_shared_memory_check_inside Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function checks if the specified object is inside shared */
|
||||
/* memory. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Pointer to module instance */
|
||||
/* obj_ptr Pointer to the object */
|
||||
/* obj_size Size of the object */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Whether the object is inside the shared memory region. */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* N/A */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Module dispatch check functions */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UCHAR _txm_module_manager_shared_memory_check_inside(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size)
|
||||
{
|
||||
|
||||
ALIGN_TYPE shared_memory_start;
|
||||
ALIGN_TYPE shared_memory_end;
|
||||
|
||||
shared_memory_start = (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address;
|
||||
shared_memory_end = shared_memory_start + module_instance -> txm_module_instance_shared_memory_length;
|
||||
|
||||
if (TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_EXCLUSIVE(shared_memory_start, shared_memory_end,
|
||||
obj_ptr, obj_size))
|
||||
{
|
||||
return(TX_TRUE);
|
||||
}
|
||||
return(TX_FALSE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_shared_memory_check_inside_byte */
|
||||
/* Cortex-M3/MPU/IAR */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function checks if the specified byte is inside shared memory. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Pointer to module instance */
|
||||
/* byte_ptr Pointer to the byte */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Whether the byte is inside the shared memory region. */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* N/A */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Module dispatch check functions */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UCHAR _txm_module_manager_shared_memory_check_inside_byte(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE byte_ptr)
|
||||
{
|
||||
|
||||
ALIGN_TYPE shared_memory_start;
|
||||
ALIGN_TYPE shared_memory_end;
|
||||
|
||||
shared_memory_start = (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address;
|
||||
shared_memory_end = shared_memory_start + module_instance -> txm_module_instance_shared_memory_length;
|
||||
|
||||
if (TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_EXCLUSIVE_BYTE(shared_memory_start, shared_memory_end,
|
||||
byte_ptr))
|
||||
{
|
||||
return(TX_TRUE);
|
||||
}
|
||||
return(TX_FALSE);
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
;/* */
|
||||
;/* This software is licensed under the Microsoft Software License */
|
||||
;/* Terms for Microsoft Azure RTOS. Full text of the 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 necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;
|
||||
;
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
THUMB
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _txm_module_manager_thread_stack_build Cortex-M3/MPU/IAR */
|
||||
;/* 6.0.1 */
|
||||
;/* 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 */
|
||||
;/* function_ptr Pointer to shell function */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* _tx_thread_create Create thread service */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;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 a fake interrupt frame. The form of the fake interrupt stack
|
||||
; on the Cortex-M should look like the following after it is built:
|
||||
;
|
||||
; Stack Top:
|
||||
; LR Interrupted LR (LR at time of PENDSV)
|
||||
; r4 Initial value for r4
|
||||
; r5 Initial value for r5
|
||||
; r6 Initial value for r6
|
||||
; r7 Initial value for r7
|
||||
; r8 Initial value for r8
|
||||
; r9 Initial value for r9
|
||||
; r10 (sl) Initial value for r10 (sl)
|
||||
; r11 Initial value for r11
|
||||
; r0 Initial value for r0 (Hardware stack starts here!!)
|
||||
; r1 Initial value for r1
|
||||
; r2 Initial value for r2
|
||||
; r3 Initial value for r3
|
||||
; r12 Initial value for r12
|
||||
; lr Initial value for lr
|
||||
; pc Initial value for pc
|
||||
; xPSR Initial value for xPSR
|
||||
;
|
||||
; Stack Bottom: (higher memory address) */
|
||||
;
|
||||
LDR r2, [r0, #16] ; Pickup end of stack area
|
||||
BIC r2, r2, #0x7 ; Align frame
|
||||
SUB r2, r2, #68 ; Subtract frame size
|
||||
LDR r3, =0xFFFFFFFD ; Build initial LR value
|
||||
STR r3, [r2, #0] ; Save on the stack
|
||||
;
|
||||
; /* Actually build the stack frame. */
|
||||
;
|
||||
MOV r3, #0 ; Build initial register value
|
||||
STR r3, [r2, #4] ; Store initial r4
|
||||
STR r3, [r2, #8] ; Store initial r5
|
||||
STR r3, [r2, #12] ; Store initial r6
|
||||
STR r3, [r2, #16] ; Store initial r7
|
||||
STR r3, [r2, #20] ; Store initial r8
|
||||
LDR r3, [r0, #12] ; Pickup stack starting address
|
||||
STR r3, [r2, #28] ; Store initial r10 (sl)
|
||||
MOV r3, #0 ; Build initial register value
|
||||
STR r3, [r2, #32] ; Store initial r11
|
||||
;
|
||||
; /* Hardware stack follows. /
|
||||
;
|
||||
STR r0, [r2, #36] ; Store initial r0, which is the thread control block
|
||||
|
||||
LDR r3, [r0, #8] ; 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.
|
||||
STR r3, [r2, #40] ; Store initial r1, which is the module entry information.
|
||||
LDR r3, [r3, #8] ; Pickup data base register from the module information
|
||||
STR r3, [r2, #24] ; Store initial r9 (data base register)
|
||||
MOV r3, #0 ; Clear r3 again
|
||||
|
||||
STR r3, [r2, #44] ; Store initial r2
|
||||
STR r3, [r2, #48] ; Store initial r3
|
||||
STR r3, [r2, #52] ; Store initial r12
|
||||
MOV r3, #0xFFFFFFFF ; Poison EXC_RETURN value
|
||||
STR r3, [r2, #56] ; Store initial lr
|
||||
STR r1, [r2, #60] ; Store initial pc
|
||||
MOV r3, #0x01000000 ; Only T-bit need be set
|
||||
STR r3, [r2, #64] ; Store initial xPSR
|
||||
;
|
||||
; /* Setup stack pointer. */
|
||||
; thread_ptr -> tx_thread_stack_ptr = r2;
|
||||
;
|
||||
STR r2, [r0, #8] ; Save stack pointer in thread's
|
||||
; control block
|
||||
BX lr ; Return to caller
|
||||
;}
|
||||
END
|
||||
|
||||
Binary file not shown.
19
ports_module/cortex-m4/iar/example_build/azure_rtos.eww
Normal file
19
ports_module/cortex-m4/iar/example_build/azure_rtos.eww
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\sample_threadx.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\sample_threadx_module_manager.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\sample_threadx_module.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\tx.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\txm.ewp</path>
|
||||
</project>
|
||||
<batchBuild />
|
||||
</workspace>
|
||||
73
ports_module/cortex-m4/iar/example_build/cstartup_M.s
Normal file
73
ports_module/cortex-m4/iar/example_build/cstartup_M.s
Normal file
@@ -0,0 +1,73 @@
|
||||
EXTERN __iar_program_start
|
||||
PUBLIC __vector_table
|
||||
|
||||
SECTION .text:CODE:REORDER(1)
|
||||
|
||||
;; Keep vector table even if it's not referenced
|
||||
REQUIRE __vector_table
|
||||
|
||||
THUMB
|
||||
|
||||
;; Forward declaration of sections.
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
SECTION .intvec:CODE:NOROOT(2)
|
||||
|
||||
DATA
|
||||
|
||||
__vector_table
|
||||
DCD sfe(CSTACK)
|
||||
DCD __Reset_Vector
|
||||
|
||||
DCD NMI_Handler
|
||||
DCD HardFault_Handler
|
||||
DCD MemManage_Handler
|
||||
DCD BusFault_Handler
|
||||
DCD UsageFault_Handler
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD SVC_Handler
|
||||
DCD DebugMon_Handler
|
||||
DCD 0
|
||||
DCD PendSV_Handler
|
||||
DCD SysTick_Handler
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Default interrupt handlers.
|
||||
;;
|
||||
|
||||
PUBWEAK NMI_Handler
|
||||
PUBWEAK HardFault_Handler
|
||||
PUBWEAK MemManage_Handler
|
||||
PUBWEAK BusFault_Handler
|
||||
PUBWEAK UsageFault_Handler
|
||||
PUBWEAK SVC_Handler
|
||||
PUBWEAK DebugMon_Handler
|
||||
PUBWEAK PendSV_Handler
|
||||
PUBWEAK SysTick_Handler
|
||||
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
THUMB
|
||||
__Reset_Vector:
|
||||
CPSID i ; Disable interrupts
|
||||
B __iar_program_start
|
||||
|
||||
|
||||
NMI_Handler
|
||||
HardFault_Handler
|
||||
MemManage_Handler
|
||||
BusFault_Handler
|
||||
UsageFault_Handler
|
||||
SVC_Handler
|
||||
DebugMon_Handler
|
||||
PendSV_Handler
|
||||
SysTick_Handler
|
||||
Default_Handler
|
||||
__default_handler
|
||||
CALL_GRAPH_ROOT __default_handler, "interrupt"
|
||||
NOCALL __default_handler
|
||||
B __default_handler
|
||||
|
||||
END
|
||||
389
ports_module/cortex-m4/iar/example_build/sample_threadx.c
Normal file
389
ports_module/cortex-m4/iar/example_build/sample_threadx.c
Normal file
@@ -0,0 +1,389 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
byte pool, and block pool. Please refer to Chapter 6 of the ThreadX User Guide for a complete
|
||||
description of this demonstration. */
|
||||
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
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 byte pool memory. */
|
||||
|
||||
UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE];
|
||||
|
||||
|
||||
/* Define event buffer. */
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
UCHAR trace_buffer[0x10000];
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Please refer to Chapter 6 of the ThreadX User Guide for a complete
|
||||
description of this demonstration. */
|
||||
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
CHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
tx_trace_enable(trace_buffer, sizeof(trace_buffer), 32);
|
||||
#endif
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", byte_pool_memory, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create the main thread. */
|
||||
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 1. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
message queue. It is also interesting to note that these threads have a time
|
||||
slice. */
|
||||
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 2. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 3. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
An interesting thing here is that both threads share the same instruction area. */
|
||||
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 4. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create thread 5. This thread simply pends on an event flag which will be set
|
||||
by thread_0. */
|
||||
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 6. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
|
||||
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 7. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
2974
ports_module/cortex-m4/iar/example_build/sample_threadx.ewd
Normal file
2974
ports_module/cortex-m4/iar/example_build/sample_threadx.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2137
ports_module/cortex-m4/iar/example_build/sample_threadx.ewp
Normal file
2137
ports_module/cortex-m4/iar/example_build/sample_threadx.ewp
Normal file
File diff suppressed because it is too large
Load Diff
2788
ports_module/cortex-m4/iar/example_build/sample_threadx.ewt
Normal file
2788
ports_module/cortex-m4/iar/example_build/sample_threadx.ewt
Normal file
File diff suppressed because it is too large
Load Diff
42
ports_module/cortex-m4/iar/example_build/sample_threadx.icf
Normal file
42
ports_module/cortex-m4/iar/example_build/sample_threadx.icf
Normal file
@@ -0,0 +1,42 @@
|
||||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 0x200;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x200;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol FlashConfig_start__= 0x00000400;
|
||||
define symbol FlashConfig_end__ = 0x0000040f;
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to (FlashConfig_start__ - 1)] | [from (FlashConfig_end__+1) to __ICFEDIT_region_ROM_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
define region FlashConfig_region = mem:[from FlashConfig_start__ to FlashConfig_end__];
|
||||
|
||||
initialize by copy { readwrite };
|
||||
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
|
||||
do not initialize { section .noinit };
|
||||
|
||||
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
|
||||
place in ROM_region { readonly };
|
||||
place in RAM_region { readwrite,
|
||||
block CSTACK, block HEAP };
|
||||
|
||||
place in FlashConfig_region
|
||||
{section FlashConfig};
|
||||
|
||||
place in RAM_region { last section FREE_MEM};
|
||||
|
||||
428
ports_module/cortex-m4/iar/example_build/sample_threadx_module.c
Normal file
428
ports_module/cortex-m4/iar/example_build/sample_threadx_module.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/* 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 512
|
||||
#define DEMO_BYTE_POOL_SIZE 6000
|
||||
#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", (UCHAR*)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)
|
||||
{
|
||||
/* Test memory handler. */
|
||||
*(ULONG *)0x64005000 = 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2974
ports_module/cortex-m4/iar/example_build/sample_threadx_module.ewd
Normal file
2974
ports_module/cortex-m4/iar/example_build/sample_threadx_module.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2135
ports_module/cortex-m4/iar/example_build/sample_threadx_module.ewp
Normal file
2135
ports_module/cortex-m4/iar/example_build/sample_threadx_module.ewp
Normal file
File diff suppressed because it is too large
Load Diff
2785
ports_module/cortex-m4/iar/example_build/sample_threadx_module.ewt
Normal file
2785
ports_module/cortex-m4/iar/example_build/sample_threadx_module.ewt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = 0x0;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x080f0000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x080fffff;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x64002800;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x64100000;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 0;
|
||||
define symbol __ICFEDIT_size_svcstack__ = 0;
|
||||
define symbol __ICFEDIT_size_irqstack__ = 0;
|
||||
define symbol __ICFEDIT_size_fiqstack__ = 0;
|
||||
define symbol __ICFEDIT_size_undstack__ = 0;
|
||||
define symbol __ICFEDIT_size_abtstack__ = 0;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x1000;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
|
||||
//define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
//define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { };
|
||||
//define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
|
||||
//define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
|
||||
//define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
|
||||
//define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
initialize by copy { readwrite };
|
||||
do not initialize { section .noinit };
|
||||
|
||||
//place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
|
||||
define movable block ROPI with alignment = 4, fixed order
|
||||
{
|
||||
ro object txm_module_preamble.o,
|
||||
ro,
|
||||
ro data
|
||||
};
|
||||
|
||||
define movable block RWPI with alignment = 8, fixed order, static base
|
||||
{
|
||||
rw,
|
||||
block HEAP
|
||||
};
|
||||
|
||||
place in ROM_region { block ROPI };
|
||||
place in RAM_region { block RWPI };
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/* 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[16384];
|
||||
|
||||
|
||||
/* 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 *) 0x64000000, 0x1000000);
|
||||
|
||||
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 *) 0x080F0000);
|
||||
|
||||
/* Enable 128 byte read/write shared memory region at 0x64005000. */
|
||||
txm_module_manager_external_memory_enable(&my_module, (void *) 0x64005000, 128, 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 *) 0x080F0000);
|
||||
|
||||
/* Start the module again. */
|
||||
txm_module_manager_start(&my_module);
|
||||
|
||||
/* Now just spin... */
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_sleep(100);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user