updated to 6.0.1 and added additional processors/toolchains

This commit is contained in:
tameraw
2020-07-16 14:32:40 -07:00
parent f8e91d4762
commit 2c35570dc9
1285 changed files with 550383 additions and 50 deletions

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\sample_threadx.ewp</path>
</project>
<project>
<path>$WS_DIR$\tx.ewp</path>
</project>
<batchBuild/>
</workspace>

View 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

View 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;
}
}

View File

@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<fileVersion>4</fileVersion>
<fileChecksum>1715762055</fileChecksum>
<configuration>
<name>Debug</name>
<outputs>
<file>$PROJ_DIR$\sample_threadx.c</file>
<file>$PROJ_DIR$\cstartup_M.s</file>
<file>$PROJ_DIR$\Debug\Exe\tx.a</file>
<file>$PROJ_DIR$\tx_initialize_low_level.s</file>
<file>$PROJ_DIR$\Debug\Obj\tx_initialize_low_level.o</file>
<file>$TOOLKIT_DIR$\inc\c\DLib_Product.h</file>
<file>$TOOLKIT_DIR$\inc\c\yvals.h</file>
<file>$TOOLKIT_DIR$\lib\dl7M_tln.a</file>
<file>$TOOLKIT_DIR$\lib\m7M_tl.a</file>
<file>$TOOLKIT_DIR$\inc\c\DLib_Defaults.h</file>
<file>$PROJ_DIR$\sample_threadx.icf</file>
<file>$TOOLKIT_DIR$\lib\rt7M_tl.a</file>
<file>$TOOLKIT_DIR$\inc\c\DLib_Product_stdlib.h</file>
<file>$TOOLKIT_DIR$\inc\c\ysizet.h</file>
<file>$TOOLKIT_DIR$\inc\c\intrinsics.h</file>
<file>$TOOLKIT_DIR$\lib\shb_l.a</file>
<file>$TOOLKIT_DIR$\inc\c\string.h</file>
<file>$TOOLKIT_DIR$\inc\c\ycheck.h</file>
<file>$TOOLKIT_DIR$\inc\c\DLib_Config_Normal.h</file>
<file>$PROJ_DIR$\Debug\Obj\sample_threadx.xcl</file>
<file>$TOOLKIT_DIR$\inc\c\stdlib.h</file>
<file>$PROJ_DIR$\Debug\Obj\cstartup_M.o</file>
<file>$PROJ_DIR$\Debug\Obj\sample_threadx.pbd</file>
<file>$PROJ_DIR$\Debug\Exe\sample_threadx.out</file>
<file>$TOOLKIT_DIR$\inc\c\DLib_Product_string.h</file>
<file>$PROJ_DIR$\Debug\Obj\sample_threadx.o</file>
<file>$PROJ_DIR$\Debug\Obj\sample_threadx.__cstat.et</file>
<file>$PROJ_DIR$\..\..\..\..\common\inc\tx_api.h</file>
<file>$TOOLKIT_DIR$\inc\c\iar_intrinsics_common.h</file>
<file>$PROJ_DIR$\..\inc\tx_port.h</file>
<file>$TOOLKIT_DIR$\inc\c\iccarm_builtin.h</file>
<file>$PROJ_DIR$\..\..\..\..\common\src\tx_queue_send.c</file>
</outputs>
<file>
<name>[ROOT_NODE]</name>
<outputs>
<tool>
<name>ILINK</name>
<file> 23</file>
</tool>
</outputs>
</file>
<file>
<name>$PROJ_DIR$\sample_threadx.c</name>
<outputs>
<tool>
<name>ICCARM</name>
<file> 25</file>
</tool>
<tool>
<name>__cstat</name>
<file> 26</file>
</tool>
<tool>
<name>BICOMP</name>
<file> 19</file>
</tool>
</outputs>
<inputs>
<tool>
<name>ICCARM</name>
<file> 27 29 20 17 6 9 18 5 13 12 16 24 14 30 28</file>
</tool>
</inputs>
</file>
<file>
<name>$PROJ_DIR$\cstartup_M.s</name>
<outputs>
<tool>
<name>AARM</name>
<file> 21</file>
</tool>
</outputs>
</file>
<file>
<name>$PROJ_DIR$\tx_initialize_low_level.s</name>
<outputs>
<tool>
<name>AARM</name>
<file> 4</file>
</tool>
</outputs>
</file>
<file>
<name>$PROJ_DIR$\Debug\Exe\sample_threadx.out</name>
<inputs>
<tool>
<name>ILINK</name>
<file> 10 21 25 2 4 15 11 8 7</file>
</tool>
</inputs>
</file>
</configuration>
<configuration>
<name>Release</name>
<outputs />
<forcedrebuild>
<name>[MULTI_TOOL]</name>
<tool>ILINK</tool>
</forcedrebuild>
<forcedrebuild>
<name>[REBUILD_ALL]</name>
</forcedrebuild>
</configuration>
</project>

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

View 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};

View File

@@ -0,0 +1,535 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace>
<ConfigDictionary>
<CurrentConfigs>
<Project>sample_threadx/Debug</Project>
<Project>tx/Debug</Project>
</CurrentConfigs>
<CurrentProj>sample_threadx</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>265</Column0>
<Column1>30</Column1>
<Column2>30</Column2>
<Column3>30</Column3>
</ColumnWidths>
<NodeDict>
<ExpandedNode>&lt;ws&gt;</ExpandedNode>
</NodeDict>
</IarPane-34065>
<ControlBarVersion>
<Major>14</Major>
<Minor>25</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>0100000030002596000002000000138600000800000029810000020000005786000001000000108600003600000001840000010000005992000001000000268100000100000000DA00000100000029E1000002000000ED8000000100000020810000010000000F810000010000000C8100000E0000000D8000000100000001E10000010000001D81000002000000EA8000000100000008DA000001000000048600000200000003DC0000010000002496000001000000178100000400000056860000010000000384000005000000148100000100000007B000000100000000810000020000000C8600000100000003E10000020000001A86000001000000EC800000010000000E81000001000000E9800000020000000B810000020000001486000002000000118600003500000002840000010000000086000001000000F48000000100000055860000010000002481000001000000468100000200000008860000010000000D81000002000000EB80000002000000E88000000300000006DA000001000000</CommandsUsage>
</MFCToolBarParameters>
<CommandManager>
<CommandsWithoutImages>0A000D8400000F84000008840000FFFFFFFF54840000328100001C810000098400000E84000030840000</CommandsWithoutImages>
<MenuUserImages>0400048400004C000000068400004E0000000B8100001B0000000D8100001D000000</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>0000000033040000000A000065050000</RectRecentFloat>
<RectRecentDocked>000000001C040000000A00004E050000</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>0400000034040000FC09000034050000</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_m4\iar\example_build\BuildLog.log</LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34052>
<Pane-34048>
<ID>34048</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000034040000FC09000034050000</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>0400000034040000FC09000034050000</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></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34056>
<Pane-34057>
<ID>34057</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000034040000FC09000034050000</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></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34057>
<Pane-34058>
<ID>34058</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000034040000FC09000034050000</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></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34058>
<Pane-34059>
<ID>34059</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000034040000FC09000034050000</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></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34059>
<Pane-34062>
<ID>34062</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000034040000FC09000034050000</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></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></item>
</cg_symbol>
<cg_user>
<item></item>
</cg_user>
<cg_display>
<item>&lt;Right-click on a symbol in the editor to show a call graph&gt;</item>
</cg_display>
<cg_def_file>
<item></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></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\x-ware_libs\threadx\ports\cortex_m4\iar\example_build\Debug\Obj\sample_threadx.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>0</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>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34064>
<BasePane-34064>
<IsVisible>0</IsVisible>
</BasePane-34064>
<IarPane-34064 />
<Pane-34065>
<ID>34065</ID>
<RectRecentFloat>00000000170000000601000078010000</RectRecentFloat>
<RectRecentDocked>00000000320000005101000018040000</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>0000000014000000000000000010000001000000FFFFFFFFFFFFFFFF510100003200000055010000180400000100000002000010040000000100000091FFFFFFF1080000118500000000000000000000000000000000000001000000118500000100000011850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000108500000000000000000000000000000000000001000000108500000100000010850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000001000000FFFFFFFFFFFFFFFF0000000018040000000A00001C040000010000000100001004000000010000009EFBFFFF6F000000FFFFFFFF07000000048500000085000008850000098500000A8500000B8500000E850000FFFF02000B004354616262656450616E6500800000010000000000000033040000000A000065050000000000001C040000000A00004E050000000000004080005607000000FFFEFF054200750069006C006400010000000485000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000085000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0485000001000000FFFFFFFF04850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000038500000000000000000000000000000000000001000000038500000100000003850000000000000000000000000000</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>00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000035000000FFFEFF000000000000000000000000000100000001000000018001E100000000000036000000FFFEFF000000000000000000000000000100000001000000018003E100000000040038000000FFFEFF0000000000000000000000000001000000010000000180008100000000000019000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000004003B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004003D000000FFFEFF000000000000000000000000000100000001000000018022E10000000004003C000000FFFEFF000000000000000000000000000100000001000000018025E10000000004003F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040042000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040043000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000400FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004002C000000FFFEFF000000000000000000000000000100000001000000018024E10000000004003E000000FFFEFF000000000000000000000000000100000001000000018028E100000000040040000000FFFEFF000000000000000000000000000100000001000000018029E100000000040041000000FFFEFF000000000000000000000000000100000001000000018002810000000004001B000000FFFEFF0000000000000000000000000001000000010000000180298100000000040030000000FFFEFF000000000000000000000000000100000001000000018027810000000004002E000000FFFEFF000000000000000000000000000100000001000000018028810000000004002F000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040028000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040029000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000004001F000000FFFEFF00000000000000000000000000010000000100000001800C8100000000000020000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000034000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000000000022000000FFFEFF00000000000000000000000000010000000100000001800F8100000000000023000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00E8020000</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>01000000030000000100000000000000000000000100000001000000FFFFFFFF00000000010000000100000000000000280000002800000000000000</MDITabsState>
</MDIClientArea-0>
</MDIWindows>
</WindowStorage>
</Workspace>

View File

@@ -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\cortex_m4\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_m4\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\x-ware_libs\threadx\ports\cortex_m4\iar\example_build\settings\sample_threadx.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_m4\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
@echo off
:end

View File

@@ -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\cortex_m4\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_m4\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\x-ware_libs\threadx\ports\cortex_m4\iar\example_build\settings\sample_threadx.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_m4\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
}

View File

@@ -0,0 +1,13 @@
"--endian=little"
"--cpu=Cortex-M4"
"--fpu=None"
"--semihosting"
"--multicore_nr_of_cores=1"

View File

@@ -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\cortex_m4\iar\example_build\Debug\Exe\sample_threadx.out"
--plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armbat.dll"

View 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>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,100 @@
<?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>4132951230</Checksum>
</DebugChecksum>
<Disassembly>
<MixedMode>1</MixedMode>
<InstrCount>0</InstrCount>
</Disassembly>
<Exceptions>
<StopOnUncaught>_ 0</StopOnUncaught>
<StopOnThrow>_ 0</StopOnThrow>
</Exceptions>
<CallStack>
<ShowArgs>0</ShowArgs>
</CallStack>
<CodeCoverage>
<Enabled>0</Enabled>
<ShowSource>0</ShowSource>
<HideCovered>0</HideCovered>
</CodeCoverage>
<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>

View File

@@ -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

View File

@@ -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"
}

View File

@@ -0,0 +1,13 @@
"--endian=little"
"--cpu=Cortex-M4"
"--fpu=None"
"--semihosting"
"--multicore_nr_of_cores=1"

View File

@@ -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"

View 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>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<Project>
<WindowStorage />
</Project>

View 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>

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

File diff suppressed because it is too large Load Diff

View File

@@ -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 */
;/** */
;/** 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 25000000
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-M4/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
;}
;
PUBLIC SysTick_Handler
PUBLIC __tx_SysTickHandler
__tx_SysTickHandler:
SysTick_Handler:
;
; VOID SysTick_Handler(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

View File

@@ -0,0 +1,493 @@
/**************************************************************************/
/* */
/* 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-M4/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 int INT;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned long ULONG;
typedef short SHORT;
typedef unsigned short USHORT;
/* Define the priority levels for ThreadX. Legal values range
from 32 to 1024 and MUST be evenly divisible by 32. */
#ifndef TX_MAX_PRIORITIES
#define TX_MAX_PRIORITIES 32
#endif
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
thread creation is less than this value, the thread create call will return an error. */
#ifndef TX_MINIMUM_STACK
#define TX_MINIMUM_STACK 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 *) 0x0a800024)
#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_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#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
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION
#define TX_SEMAPHORE_EXTENSION
#define TX_TIMER_EXTENSION
/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
#define TX_THREAD_USER_EXTENSION
#endif
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
tx_thread_shell_entry, and tx_thread_terminate. */
#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
#ifdef __ARMVFP__
#ifdef TX_MISRA_ENABLE
ULONG _tx_misra_control_get(void);
void _tx_misra_control_set(ULONG value);
ULONG _tx_misra_fpccr_get(void);
void _tx_misra_vfp_touch(void);
#endif
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
in order to ensure no lazy stacking will occur. */
#ifndef TX_MISRA_ENABLE
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = __get_CONTROL(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
__set_CONTROL(_tx_vfp_state); \
}
#else
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_misra_control_set(_tx_vfp_state); \
}
#endif
/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR.
If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating
this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush
the lazy FPU save, then restore the CONTROL.FPCA state. */
#ifndef TX_MISRA_ENABLE
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \
ULONG _tx_system_state; \
_tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = __get_CONTROL(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
__set_CONTROL(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = __get_CONTROL(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
__asm volatile ("vmov.f32 s0, s0"); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = __get_CONTROL(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
__set_CONTROL(_tx_vfp_state); \
} \
} \
} \
}
#else
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \
ULONG _tx_system_state; \
_tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_misra_control_set(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = _tx_misra_fpccr_get(); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
_tx_misra_vfp_touch(); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_misra_control_set(_tx_vfp_state); \
} \
} \
} \
}
#endif
#else
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
#endif
/* 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 FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
void tx_thread_fpu_disable(void);
/* 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-M4/IAR Version 6.0 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
#endif
#endif

View File

@@ -0,0 +1,224 @@
Microsoft's Azure RTOS ThreadX for Cortex-M4
Using the IAR Tools
1. Building the ThreadX run-time Library
Building the ThreadX library is easy. First, open the Azure RTOS workspace
azure_rtos.eww. Next, make the TX project the "active project" in the
IAR Embedded Workbench and select the "Make" button. You should observe
assembly and compilation of a series of ThreadX source files. This
results in the ThreadX run-time library file tx.a, which is needed by
the application.
2. Demonstration System
The ThreadX demonstration is designed to execute under the IAR debugger under
simulation.
Building the demonstration is easy; simply open the threadx.www workspace file,
make the sample_threadx.ewp project the "active project" in the IAR Embedded
Workbench, and select the "Make" button.
You should observe the compilation of sample_threadx.c (which is the demonstration
application) and linking with tx.a. The resulting file sample_threadx.out is a
binary ELF file that can be downloaded and executed on the IAR Windows-based
Cortex-M4 simulator.
3. System Initialization
The entry point in ThreadX for the Cortex-M4 using IAR tools is at label
__iar_program_start. This is defined within the IAR compiler's startup code.
In addition, this is where all static and global preset C variable
initialization processing takes place.
The ThreadX tx_initialize_low_level.s file is responsible for setting up
various system data structures, and a periodic timer interrupt source.
By default, the vector area is defined at the top of cstartup_M.s, which is
a slightly modified from the base IAR file.
The _tx_initialize_low_level function inside of tx_initialize_low_level.s
also determines the first available address for use by the application, which
is supplied as the sole input parameter to your application definition function,
tx_application_define. To accomplish this, a section is created in
tx_initialize_low_level.s called FREE_MEM, which must be located after all
other RAM sections in memory.
4. Register Usage and Stack Frames
The following defines the saved context stack frames for context switches
that occur as a result of interrupt handling or from thread-level API calls.
All suspended threads have the same stack frame in the Cortex-M4 version of
ThreadX. The top of the suspended thread's stack is pointed to by
tx_thread_stack_ptr in the associated thread control block TX_THREAD.
Non-FPU Stack Frame:
Stack Offset Stack Contents
0x00 LR Interrupted LR (LR at time of PENDSV)
0x04 r4
0x08 r5
0x0C r6
0x10 r7
0x14 r8
0x18 r9
0x1C r10 (sl)
0x20 r11
0x24 r0 (Hardware stack starts here!!)
0x28 r1
0x2C r2
0x30 r3
0x34 r12
0x38 lr
0x3C pc
0x40 xPSR
FPU Stack Frame (only interrupted thread with FPU enabled):
Stack Offset Stack Contents
0x00 LR Interrupted LR (LR at time of PENDSV)
0x04 s0
0x08 s1
0x0C s2
0x10 s3
0x14 s4
0x18 s5
0x1C s6
0x20 s7
0x24 s8
0x28 s9
0x2C s10
0x30 s11
0x34 s12
0x38 s13
0x3C s14
0x40 s15
0x44 s16
0x48 s17
0x4C s18
0x50 s19
0x54 s20
0x58 s21
0x5C s22
0x60 s23
0x64 s24
0x68 s25
0x6C s26
0x70 s27
0x74 s28
0x78 s29
0x7C s30
0x80 s31
0x84 fpscr
0x88 r4
0x8C r5
0x90 r6
0x94 r7
0x98 r8
0x9C r9
0xA0 r10 (sl)
0xA4 r11
0xA8 r0 (Hardware stack starts here!!)
0xAC r1
0xB0 r2
0xB4 r3
0xB8 r12
0xBC lr
0xC0 pc
0xC4 xPSR
5. Improving Performance
The distribution version of ThreadX is built without any compiler
optimizations. This makes it easy to debug because you can trace or set
breakpoints inside of ThreadX itself. Of course, this costs some
performance. To make it run faster, you can change the ThreadX library
project to enable various compiler optimizations.
In addition, you can eliminate the ThreadX basic API error checking by
compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
defined.
6. Interrupt Handling
The Cortex-M4 vectors start at the label __vector_table and is defined in cstartup_M.s.
The application may modify the vector area according to its needs.
6.1 Managed Interrupts
ISRs for Cortex-M using the IAR tools can be written completely in C (or assembly
language) without any calls to _tx_thread_context_save or _tx_thread_context_restore.
These ISRs are allowed access to the ThreadX API that is available to ISRs.
ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table):
void your_C_isr(void)
{
/* ISR processing goes here, including any needed function calls. */
}
ISRs written in assembly language will take the form:
PUBLIC your_assembly_isr
your_assembly_isr:
PUSH {lr}
; ISR processing goes here, including any needed function calls.
POP {lr}
BX lr
7. IAR Thread-safe Library Support
Thread-safe support for the IAR tools is easily enabled by building the ThreadX library
and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file
should have the following line added (if not already in place):
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
7. IAR Thread-safe Library Support
Thread-safe support for the IAR tools is easily enabled by building the ThreadX library
and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file
should have the following line added (if not already in place):
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
The project options "General Options -> Library Configuration" should also have the
"Enable thread support in library" box selected.
8. VFP Support
ThreadX for Cortex-M4 supports automatic ("lazy") VFP support, which means that applications threads
can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread
context - no additional setup by the application.
9. Revision History
For generic code revision information, please refer to the readme_threadx_generic.txt
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX:
06/30/2020 Initial ThreadX 6.0.1 version for Cortex-M4 using IAR's ARM tools.
Copyright(c) 1996-2020 Microsoft Corporation
https://azure.com/rtos

View 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. */

File diff suppressed because it is too large Load Diff

View File

@@ -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"
;
;
EXTERN _tx_execution_isr_exit
;
;
SECTION `.text`:CODE:NOROOT(2)
THUMB
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_restore Cortex-M4/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 return address
BL _tx_execution_isr_exit ; Call the ISR exit function
POP {r0, lr} ; Save return address
#endif
;
POP {lr}
BX lr
;
;}
END

View File

@@ -0,0 +1,95 @@
;/**************************************************************************/
;/* */
;/* 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-M4/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 */
;/* */
;/* None */
;/* */
;/* 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

View File

@@ -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-M4/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

View File

@@ -0,0 +1,84 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** 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-M4/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

View File

@@ -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-M4/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

View File

@@ -0,0 +1,291 @@
;/**************************************************************************/
;/* */
;/* 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
;
;
SECTION `.text`:CODE:NOROOT(2)
THUMB
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_schedule Cortex-M4/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function waits for a thread control block pointer to appear in */
;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
;/* in the variable, the corresponding thread is resumed. */
;/* */
;/* INPUT */
;/* */
;/* None */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* None */
;/* */
;/* CALLED BY */
;/* */
;/* _tx_initialize_kernel_enter ThreadX entry function */
;/* _tx_thread_system_return Return to system from thread */
;/* _tx_thread_context_restore Restore thread's context */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 06-30-2020 William E. Lamie 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
;
; /* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */
;
#ifdef __ARMVFP__
MRS r0, CONTROL ; Pickup current CONTROL register
BIC r0, r0, #4 ; Clear the FPCA bit
MSR CONTROL, r0 ; Setup new CONTROL register
#endif
;
; /* 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
DSB ; Complete all memory accesses
ISB ; Flush pipeline
;
; /* Wait here for the PendSV to take place. */
;
__tx_wait_here:
B __tx_wait_here ; Wait for the PendSV to happen
;}
;
; /* 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
#ifdef __ARMVFP__
TST LR, #0x10 ; Determine if the VFP extended frame is present
BNE _skip_vfp_save
VSTMDB r12!,{s16-s31} ; Yes, save additional VFP registers
_skip_vfp_save:
#endif
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/r1
BL _tx_execution_thread_enter ; Call the thread execution enter function
POP {r0, r1} ; Recover r3
#endif
;
; /* Restore the thread context and PSP. */
;
LDR r12, [r1, #8] ; Pickup thread's stack pointer
LDMIA r12!, {LR} ; Pickup LR
#ifdef __ARMVFP__
TST LR, #0x10 ; Determine if the VFP extended frame is present
BNE _skip_vfp_restore ; If not, skip VFP restore
VLDMIA r12!, {s16-s31} ; Yes, restore additional VFP registers
_skip_vfp_restore:
#endif
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
;}
;
#ifdef __ARMVFP__
PUBLIC tx_thread_fpu_enable
tx_thread_fpu_enable:
;
; /* Automatic VPF logic is supported, this function is present only for
; backward compatibility purposes and therefore simply returns. */
;
BX LR ; Return to caller
PUBLIC tx_thread_fpu_disable
tx_thread_fpu_disable:
;
; /* Automatic VPF logic is supported, this function is present only for
; backward compatibility purposes and therefore simply returns. */
;
BX LR ; Return to caller
#endif
END

View File

@@ -0,0 +1,144 @@
;/**************************************************************************/
;/* */
;/* 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_stack_build Cortex-M4/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

View File

@@ -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-M4/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

View File

@@ -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-M4/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