mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2025-11-16 04:24:48 +00:00
6.1 minor release
This commit is contained in:
10
ports/risc-v32/iar/example_build/azure_rtos.eww
Normal file
10
ports/risc-v32/iar/example_build/azure_rtos.eww
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\sample_threadx.ewp</path>
|
||||
</project>
|
||||
<project>
|
||||
<path>$WS_DIR$\tx.ewp</path>
|
||||
</project>
|
||||
<batchBuild />
|
||||
</workspace>
|
||||
395
ports/risc-v32/iar/example_build/sample_threadx.c
Normal file
395
ports/risc-v32/iar/example_build/sample_threadx.c
Normal file
@@ -0,0 +1,395 @@
|
||||
/* 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;
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma vector = 3
|
||||
__interrupt void test()
|
||||
{
|
||||
thread_6_and_7_entry(1);
|
||||
}
|
||||
848
ports/risc-v32/iar/example_build/sample_threadx.ewd
Normal file
848
ports/risc-v32/iar/example_build/sample_threadx.ewd
Normal file
@@ -0,0 +1,848 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<fileVersion>3</fileVersion>
|
||||
<configuration>
|
||||
<name>Debug</name>
|
||||
<toolchain>
|
||||
<name>RISCV</name>
|
||||
</toolchain>
|
||||
<debug>1</debug>
|
||||
<settings>
|
||||
<name>C-SPY</name>
|
||||
<archiveVersion>3</archiveVersion>
|
||||
<data>
|
||||
<version>1</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
<name>CSPYInput</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYProcessor</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYDynDriver</name>
|
||||
<state>SIMRISCV</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYRunToEnable</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYRunoToName</name>
|
||||
<state>main</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMacOverride</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMacFile</name>
|
||||
<state>$PROJ_DIR$/config/debugger/timer.mac</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMemOverride</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMemFile</name>
|
||||
<state>$PROJ_DIR$/config/debugger/ioriscv.ddf</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMandatory</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYDDFileSlave</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesSuppressCheck1</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesPath1</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesSuppressCheck2</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesPath2</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesSuppressCheck3</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesPath3</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesOffset1</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesOffset2</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesOffset3</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesUse1</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesUse2</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesUse3</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYExtraOptionsCheck</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYExtraOptions</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCDownloadSuppressDownload</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCDownloadVerifyAll</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>UseFlashLoader</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OverrideDefFlashBoard</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>FlashLoaders</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>MassEraseBeforeFlashing</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreNrOfCores</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreWorkspace</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreSlaveProject</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreSlaveConfiguration</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCAttachSlave</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreNrOfCoresSlave</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreAMPConfigType</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreSessionFile</name>
|
||||
<state></state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>IJETRISCV</name>
|
||||
<archiveVersion>2</archiveVersion>
|
||||
<data>
|
||||
<version>1</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
<name>OCDriverInfo</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCIarProbeScriptFile</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCProbeCfgOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCProbeConfig</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetProbeConfigRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetSelectedCPUBehaviour</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>ICpuName</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetResetList</name>
|
||||
<version>0</version>
|
||||
<state>5</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetHWResetDuration</name>
|
||||
<state>300</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetHWResetDelay</name>
|
||||
<state>200</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetPowerFromProbe</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetPowerRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCIjetUsbSerialNo</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCIjetUsbSerialNoSelect</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetDoLogfile</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetLogFile</name>
|
||||
<state>$PROJ_DIR$\cspycomm.log</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetInterfaceRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetInterfaceCmdLine</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiTargetEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiTarget</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetScanChainNonRISCVDevices</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetIRLength</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiCPUEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiCPUNumber</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetJtagSpeedList</name>
|
||||
<version>0</version>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetBreakpointRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetRestoreBreakpointsCheck</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetUpdateBreakpointsEdit</name>
|
||||
<state>_call_main</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchReset</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CatchDummy</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCJetEmuParams</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>FlashBoardPathSlave</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchNmi</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchInstrMis</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchInstrFault</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchIllegalInstr</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchLoadMis</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchLoadFault</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchStoreAddr</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchStoreAccess</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchEnvironment</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchInstrPage</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchLoadPage</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchStorePage</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchExternal</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchTimer</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchSoftware</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchModeM</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchModeS</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchModeU</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>GDelayAfterOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>SIMRISCV</name>
|
||||
<archiveVersion>3</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
<name>SIMMandatory</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<debuggerPlugins>
|
||||
<plugin>
|
||||
<file>$TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
</debuggerPlugins>
|
||||
</configuration>
|
||||
<configuration>
|
||||
<name>Release</name>
|
||||
<toolchain>
|
||||
<name>RISCV</name>
|
||||
</toolchain>
|
||||
<debug>0</debug>
|
||||
<settings>
|
||||
<name>C-SPY</name>
|
||||
<archiveVersion>3</archiveVersion>
|
||||
<data>
|
||||
<version>1</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
<name>CSPYInput</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYProcessor</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYDynDriver</name>
|
||||
<state>SIMRISCV</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYRunToEnable</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYRunoToName</name>
|
||||
<state>main</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMacOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMacFile</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMemOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMemFile</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYMandatory</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYDDFileSlave</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesSuppressCheck1</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesPath1</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesSuppressCheck2</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesPath2</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesSuppressCheck3</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesPath3</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesOffset1</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesOffset2</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesOffset3</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesUse1</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesUse2</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYImagesUse3</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYExtraOptionsCheck</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSPYExtraOptions</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCDownloadSuppressDownload</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCDownloadVerifyAll</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>UseFlashLoader</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OverrideDefFlashBoard</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>FlashLoaders</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>MassEraseBeforeFlashing</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreNrOfCores</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreWorkspace</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreSlaveProject</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreSlaveConfiguration</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCAttachSlave</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreNrOfCoresSlave</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreAMPConfigType</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCMulticoreSessionFile</name>
|
||||
<state></state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>IJETRISCV</name>
|
||||
<archiveVersion>2</archiveVersion>
|
||||
<data>
|
||||
<version>1</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
<name>OCDriverInfo</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCIarProbeScriptFile</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCProbeCfgOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCProbeConfig</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetProbeConfigRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetSelectedCPUBehaviour</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>ICpuName</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetResetList</name>
|
||||
<version>0</version>
|
||||
<state>5</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetHWResetDuration</name>
|
||||
<state>300</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetHWResetDelay</name>
|
||||
<state>###uninitialized###</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetPowerFromProbe</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetPowerRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCIjetUsbSerialNo</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCIjetUsbSerialNoSelect</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetDoLogfile</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetLogFile</name>
|
||||
<state>$PROJ_DIR$\cspycomm.log</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetInterfaceRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetInterfaceCmdLine</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiTargetEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiTarget</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetScanChainNonRISCVDevices</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetIRLength</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiCPUEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetMultiCPUNumber</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetJtagSpeedList</name>
|
||||
<version>0</version>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetBreakpointRadio</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetRestoreBreakpointsCheck</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>IjetUpdateBreakpointsEdit</name>
|
||||
<state>_call_main</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchReset</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CatchDummy</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OCJetEmuParams</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>FlashBoardPathSlave</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchNmi</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchInstrMis</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchInstrFault</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchIllegalInstr</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchLoadMis</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchLoadFault</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchStoreAddr</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchStoreAccess</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchEnvironment</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchInstrPage</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchLoadPage</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchStorePage</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchExternal</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchTimer</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchSoftware</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchModeM</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchModeS</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>RDICatchModeU</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>GDelayAfterOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>SIMRISCV</name>
|
||||
<archiveVersion>3</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
<name>SIMMandatory</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<debuggerPlugins>
|
||||
<plugin>
|
||||
<file>$TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
</debuggerPlugins>
|
||||
</configuration>
|
||||
</project>
|
||||
1800
ports/risc-v32/iar/example_build/sample_threadx.ewp
Normal file
1800
ports/risc-v32/iar/example_build/sample_threadx.ewp
Normal file
File diff suppressed because it is too large
Load Diff
47
ports/risc-v32/iar/example_build/sample_threadx.icf
Normal file
47
ports/risc-v32/iar/example_build/sample_threadx.icf
Normal file
@@ -0,0 +1,47 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RISC-V ilink configuration file.
|
||||
//
|
||||
|
||||
define exported symbol _link_file_version_2 = 1;
|
||||
define exported symbol _auto_vector_setup = 1;
|
||||
define exported symbol _max_vector = 16;
|
||||
define exported symbol _CLINT = 1;
|
||||
|
||||
define memory mem with size = 4G;
|
||||
|
||||
define region RAM_region32 = mem:[from 0x80000000 to 0x8003FFFF];
|
||||
define region ROM_region32 = mem:[from 0x20000000 to 0x3FFFFFFF];
|
||||
|
||||
initialize by copy { rw };
|
||||
do not initialize { section *.noinit };
|
||||
|
||||
define block CSTACK with alignment = 16, size = CSTACK_SIZE { };
|
||||
define block HEAP with alignment = 16, size = HEAP_SIZE { };
|
||||
|
||||
define block MVECTOR with alignment = 128 { ro section .mintvec };
|
||||
|
||||
if (isdefinedsymbol(_uses_clic))
|
||||
{
|
||||
define block MINTERRUPT with alignment = 128 { ro section .mtext };
|
||||
define block MINTERRUPTS { block MVECTOR,
|
||||
block MINTERRUPT };
|
||||
}
|
||||
else
|
||||
{
|
||||
define block MINTERRUPTS with maximum size = 64k { ro section .mtext,
|
||||
midway block MVECTOR };
|
||||
}
|
||||
|
||||
define block RW_DATA with static base GPREL { rw data };
|
||||
keep { symbol __iar_cstart_init_gp }; // defined in cstartup.s
|
||||
|
||||
"CSTARTUP32" : place at start of ROM_region32 { ro section .cstartup };
|
||||
|
||||
"ROM32":place in ROM_region32 { ro,
|
||||
block MINTERRUPTS };
|
||||
|
||||
"RAM32":place in RAM_region32 { block RW_DATA,
|
||||
block HEAP,
|
||||
block CSTACK };
|
||||
|
||||
"RAM32":place in RAM_region32 { last section FREE_MEM};
|
||||
2406
ports/risc-v32/iar/example_build/tx.ewp
Normal file
2406
ports/risc-v32/iar/example_build/tx.ewp
Normal file
File diff suppressed because it is too large
Load Diff
275
ports/risc-v32/iar/inc/tx_port.h
Normal file
275
ports/risc-v32/iar/inc/tx_port.h
Normal file
@@ -0,0 +1,275 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 RISC-V32/IAR */
|
||||
/* 6.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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_PORT_H
|
||||
#define TX_PORT_H
|
||||
|
||||
|
||||
/* Include prototypes for memset. */
|
||||
|
||||
#include <string.h>
|
||||
#include <intrinsics.h>
|
||||
|
||||
|
||||
/* Determine if the optional ThreadX user define file should be used. */
|
||||
|
||||
#ifdef TX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
|
||||
/* Yes, include the user defines in tx_user.h. The defines in this file may
|
||||
alternately be defined on the command line. */
|
||||
|
||||
#include "tx_user.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler library include files. */
|
||||
|
||||
|
||||
/* 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 512 /* 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 RISC-V port. */
|
||||
|
||||
#define TX_INT_DISABLE 0x00000000 /* Disable interrupts value */
|
||||
#define TX_INT_ENABLE 0x00000008 /* Enable interrupt value */
|
||||
|
||||
|
||||
/* 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_TRACE_TIME_SOURCE
|
||||
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
|
||||
#endif
|
||||
#ifndef TX_TRACE_TIME_MASK
|
||||
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the port specific options for the _tx_build_options variable. This variable indicates
|
||||
how the ThreadX library was built. */
|
||||
|
||||
#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
|
||||
|
||||
|
||||
/* Define the in-line initialization constant so that modules with in-line
|
||||
initialization capabilities can prevent their initialization from being
|
||||
a function call. */
|
||||
|
||||
#define TX_INLINE_INITIALIZATION
|
||||
|
||||
|
||||
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
|
||||
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
|
||||
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
|
||||
define is negated, thereby forcing the stack fill which is necessary for the stack checking
|
||||
logic. */
|
||||
|
||||
#ifdef TX_ENABLE_STACK_CHECKING
|
||||
#undef TX_DISABLE_STACK_FILLING
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the TX_THREAD control block extensions for this port. The main reason
|
||||
for the multiple macros is so that backward compatibility can be maintained with
|
||||
existing ThreadX kernel awareness modules. */
|
||||
|
||||
#define TX_THREAD_EXTENSION_0
|
||||
#define TX_THREAD_EXTENSION_1
|
||||
#define TX_THREAD_EXTENSION_2
|
||||
#define TX_THREAD_EXTENSION_3
|
||||
|
||||
|
||||
/* Define the port extensions of the remaining ThreadX objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_EXTENSION
|
||||
#define TX_BYTE_POOL_EXTENSION
|
||||
#define TX_EVENT_FLAGS_GROUP_EXTENSION
|
||||
#define TX_MUTEX_EXTENSION
|
||||
#define TX_QUEUE_EXTENSION
|
||||
#define TX_SEMAPHORE_EXTENSION
|
||||
#define TX_TIMER_EXTENSION
|
||||
|
||||
|
||||
/* Define the user extension field of the thread control block. Nothing
|
||||
additional is needed for this port so it is defined as white space. */
|
||||
|
||||
#ifndef TX_THREAD_USER_EXTENSION
|
||||
#define TX_THREAD_USER_EXTENSION
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
|
||||
tx_thread_shell_entry, and tx_thread_terminate. */
|
||||
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object creation extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object deletion extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Define ThreadX interrupt lockout and restore macros for protection on
|
||||
access of critical kernel information. The restore interrupt macro must
|
||||
restore the interrupt posture of the running thread prior to the value
|
||||
present prior to the disable macro. In most cases, the save area macro
|
||||
is used to define a local function save area for the disable and restore
|
||||
macros. */
|
||||
|
||||
#ifdef TX_DISABLE_INLINE
|
||||
|
||||
unsigned int _tx_thread_interrupt_control(unsigned int new_posture);
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA register int interrupt_save;
|
||||
|
||||
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
|
||||
#define TX_RESTORE _tx_thread_interrupt_control(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);};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the interrupt lockout macros for each ThreadX object. */
|
||||
|
||||
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
|
||||
#define TX_BYTE_POOL_DISABLE TX_DISABLE
|
||||
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
|
||||
#define TX_MUTEX_DISABLE TX_DISABLE
|
||||
#define TX_QUEUE_DISABLE TX_DISABLE
|
||||
#define TX_SEMAPHORE_DISABLE TX_DISABLE
|
||||
|
||||
|
||||
/* Define the version ID of ThreadX. This may be utilized by the application. */
|
||||
|
||||
#ifdef TX_THREAD_INIT
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RISC-V32/IAR Version G6.1 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
243
ports/risc-v32/iar/readme_threadx.txt
Normal file
243
ports/risc-v32/iar/readme_threadx.txt
Normal file
@@ -0,0 +1,243 @@
|
||||
Microsoft's Azure RTOS ThreadX for RISC-V
|
||||
|
||||
32-bit Mode
|
||||
|
||||
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.ewp 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
|
||||
Windows-based RISC-V simulator.
|
||||
|
||||
Building the demonstration is easy; simply 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 file that can be downloaded and executed on IAR's RISC-V simulator.
|
||||
|
||||
|
||||
3. System Initialization
|
||||
|
||||
The entry point in ThreadX for the RISC-V 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.
|
||||
|
||||
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 IAR RISC-V compiler assumes that registers t0-t6 and a0-a7 are scratch
|
||||
registers for each function. All other registers used by a C function must
|
||||
be preserved by the function. ThreadX takes advantage of this in situations
|
||||
where a context switch happens as a result of making a ThreadX service call
|
||||
(which is itself a C function). In such cases, the saved context of a thread
|
||||
is only the non-scratch registers.
|
||||
|
||||
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 one of these two types of stack frames. The top
|
||||
of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
|
||||
associated thread control block TX_THREAD.
|
||||
|
||||
|
||||
|
||||
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
|
||||
|
||||
0x00 1 0
|
||||
0x04 s11 (x27) s11 (x27)
|
||||
0x08 s10 (x26) s10 (x26)
|
||||
0x0C s9 (x25) s9 (x25)
|
||||
0x10 s8 (x24) s8 (x24)
|
||||
0x14 s7 (x23) s7 (x23)
|
||||
0x18 s6 (x22) s6 (x22)
|
||||
0x1C s5 (x21) s5 (x21)
|
||||
0x20 s4 (x20) s4 (x20)
|
||||
0x24 s3 (x19) s3 (x19)
|
||||
0x28 s2 (x18) s2 (x18)
|
||||
0x2C s1 (x9) s1 (x9)
|
||||
0x30 s0 (x8) s0 (x8)
|
||||
0x34 t6 (x31) ra (x1)
|
||||
0x38 t5 (x30) mstatus
|
||||
0x3C t4 (x29) fs0
|
||||
0x40 t3 (x28) fs1
|
||||
0x44 t2 (x7) fs2
|
||||
0x48 t1 (x6) fs3
|
||||
0x4C t0 (x5) fs4
|
||||
0x50 a7 (x17) fs5
|
||||
0x54 a6 (x16) fs6
|
||||
0x58 a5 (x15) fs7
|
||||
0x5C a4 (x14) fs8
|
||||
0x60 a3 (x13) fs9
|
||||
0x64 a2 (x12) fs10
|
||||
0x68 a1 (x11) fs11
|
||||
0x6C a0 (x10) fcsr
|
||||
0x70 ra (x1)
|
||||
0x74 reserved
|
||||
0x78 mepc
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
0x7C ft0
|
||||
0x80 ft1
|
||||
0x84 ft2
|
||||
0x88 ft3
|
||||
0x8C ft4
|
||||
0x90 ft5
|
||||
0x94 ft6
|
||||
0x98 ft7
|
||||
0x9C fs0
|
||||
0xA0 fs1
|
||||
0xA4 fa0
|
||||
0xA8 fa1
|
||||
0xAC fa2
|
||||
0xB0 fa3
|
||||
0xB4 fa4
|
||||
0xB8 fa5
|
||||
0xBC fa6
|
||||
0xC0 fa7
|
||||
0xC4 fs2
|
||||
0xC8 fs3
|
||||
0xCC fs4
|
||||
0xD0 fs5
|
||||
0xD4 fs6
|
||||
0xD8 fs7
|
||||
0xDC fs8
|
||||
0xE0 fs9
|
||||
0xE4 fs10
|
||||
0xE8 fs11
|
||||
0xEC ft8
|
||||
0xF0 ft9
|
||||
0xF4 ft10
|
||||
0xF8 ft11
|
||||
0xFC fcsr
|
||||
#endif
|
||||
|
||||
|
||||
5. Improving Performance
|
||||
|
||||
The distribution version of ThreadX is built without any compiler
|
||||
optimizations. This makes it easy to debug because you can trace or set
|
||||
breakpoints inside of ThreadX itself. Of course, this costs some
|
||||
performance. To make ThreadX run faster, you can change the project
|
||||
options to disable debug information and enable the desired
|
||||
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 before tx_api.h is included.
|
||||
|
||||
|
||||
6. Interrupt Handling
|
||||
|
||||
ThreadX provides complete and high-performance interrupt handling for RISC-V
|
||||
targets.The ThreadX general exception handler sample is defined as follows,
|
||||
where "*" represents the interrupt vector number:
|
||||
|
||||
PUBLIC _sample_interrupt_handler
|
||||
PUBLIC __minterrupt_00000*
|
||||
EXTWEAK __require_minterrupt_vector_table
|
||||
_sample_interrupt_handler:
|
||||
__minterrupt_00000*:
|
||||
REQUIRE __require_minterrupt_vector_table
|
||||
|
||||
|
||||
/* Before calling _tx_thread_context_save, we have to allocate an interrupt
|
||||
stack frame and save the current value of x1 (ra). */
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, -260 ; Allocate space for all registers - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, -128 ; Allocate space for all registers - without floating point enabled
|
||||
#endif
|
||||
sw x1, 0x70(sp) ; Store RA
|
||||
call _tx_thread_context_save ; Call ThreadX context save
|
||||
|
||||
/* Call your ISR processing here! */
|
||||
call your_ISR_processing
|
||||
|
||||
/* Timer interrupt processing is done, jump to ThreadX context restore. */
|
||||
j _tx_thread_context_restore ; Jump to ThreadX context restore function. Note: this does not return!
|
||||
|
||||
|
||||
Some additional conditions:
|
||||
|
||||
1. In the project settings Linker -> Extra Options, --auto_vector_setup should be defined.
|
||||
2. The project linker control file should have the following sections to include the vector table:
|
||||
|
||||
define block MVECTOR with alignment = 128 { ro section .mintvec };
|
||||
|
||||
if (isdefinedsymbol(_uses_clic))
|
||||
{
|
||||
define block MINTERRUPT with alignment = 128 { ro section .mtext };
|
||||
define block MINTERRUPTS { block MVECTOR,
|
||||
block MINTERRUPT };
|
||||
}
|
||||
else
|
||||
{
|
||||
define block MINTERRUPTS with maximum size = 64k { ro section .mtext,
|
||||
midway block MVECTOR };
|
||||
}
|
||||
|
||||
6.1 Sample Timer ISR
|
||||
|
||||
The following sample timer ISR using vector 7 is defined in tx_initialize_low_level.s such that timer
|
||||
functionality is available under IAR simulation:
|
||||
|
||||
PUBLIC _tx_timer_interrupt_handler
|
||||
PUBLIC __minterrupt_000007
|
||||
EXTWEAK __require_minterrupt_vector_table
|
||||
_tx_timer_interrupt_handler:
|
||||
__minterrupt_000007:
|
||||
REQUIRE __require_minterrupt_vector_table
|
||||
|
||||
|
||||
/* Before calling _tx_thread_context_save, we have to allocate an interrupt
|
||||
stack frame and save the current value of x1 (ra). */
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, -260 ; Allocate space for all registers - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, -128 ; Allocate space for all registers - without floating point enabled
|
||||
#endif
|
||||
sw x1, 0x70(sp) ; Store RA
|
||||
call _tx_thread_context_save ; Call ThreadX context save
|
||||
|
||||
/* Call the ThreadX timer routine. */
|
||||
call _tx_timer_interrupt ; Call timer interrupt handler
|
||||
|
||||
/* Timer interrupt processing is done, jump to ThreadX context restore. */
|
||||
j _tx_thread_context_restore ; Jump to ThreadX context restore function. Note: this does not return!
|
||||
|
||||
|
||||
7. Revision History
|
||||
|
||||
For generic code revision information, please refer to the readme_threadx_generic.txt
|
||||
file, which is included in your distribution. The following details the revision
|
||||
information associated with this specific port of ThreadX:
|
||||
|
||||
08/09/2020 Initial ThreadX version for RISC-V using IAR Tools.
|
||||
|
||||
|
||||
Copyright(c) 1996-2020 Microsoft Corporation
|
||||
|
||||
|
||||
https://azure.com/rtos
|
||||
|
||||
130
ports/risc-v32/iar/src/tx_initialize_low_level.s
Normal file
130
ports/risc-v32/iar/src/tx_initialize_low_level.s
Normal file
@@ -0,0 +1,130 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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_thread_context_save
|
||||
EXTERN _tx_thread_context_restore
|
||||
EXTERN _tx_timer_interrupt
|
||||
|
||||
RSEG FREE_MEM:DATA
|
||||
PUBLIC __tx_free_memory_start
|
||||
__tx_free_memory_start:
|
||||
DS32 4
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_low_level RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_initialize_low_level(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_initialize_low_level
|
||||
_tx_initialize_low_level:
|
||||
sw sp, _tx_thread_system_stack_ptr, t0 ; Save system stack pointer
|
||||
|
||||
la t0, __tx_free_memory_start ; Pickup first free address
|
||||
sw t0, _tx_initialize_unused_memory, t1 ; Save unused memory address
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/* Define the actual timer interrupt/exception handler. */
|
||||
|
||||
PUBLIC _tx_timer_interrupt_handler
|
||||
PUBLIC __minterrupt_000007
|
||||
EXTWEAK __require_minterrupt_vector_table
|
||||
_tx_timer_interrupt_handler:
|
||||
__minterrupt_000007:
|
||||
REQUIRE __require_minterrupt_vector_table
|
||||
|
||||
|
||||
/* Before calling _tx_thread_context_save, we have to allocate an interrupt
|
||||
stack frame and save the current value of x1 (ra). */
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, -260 ; Allocate space for all registers - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, -128 ; Allocate space for all registers - without floating point enabled
|
||||
#endif
|
||||
sw x1, 0x70(sp) ; Store RA
|
||||
call _tx_thread_context_save ; Call ThreadX context save
|
||||
|
||||
/* Call the ThreadX timer routine. */
|
||||
call _tx_timer_interrupt ; Call timer interrupt handler
|
||||
|
||||
/* Timer interrupt processing is done, jump to ThreadX context restore. */
|
||||
j _tx_thread_context_restore ; Jump to ThreadX context restore function. Note: this does not return!
|
||||
|
||||
|
||||
END
|
||||
|
||||
344
ports/risc-v32/iar/src/tx_thread_context_restore.s
Normal file
344
ports/risc-v32/iar/src/tx_thread_context_restore.s
Normal file
@@ -0,0 +1,344 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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_execute_ptr
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_thread_preempt_disable
|
||||
EXTERN _tx_thread_schedule
|
||||
EXTERN _tx_thread_system_state
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_isr_exit
|
||||
#endif
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_restore RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function restores the interrupt context if it is processing a */
|
||||
/* nested interrupt. If not, it returns to the interrupt thread if no */
|
||||
/* preemption is necessary. Otherwise, if preemption is necessary or */
|
||||
/* if no thread was running, the function returns to the scheduler. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_schedule Thread scheduling routine */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ISRs Interrupt Service Routines */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_context_restore(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_context_restore
|
||||
_tx_thread_context_restore:
|
||||
|
||||
/* Lockout interrupts. */
|
||||
|
||||
csrci mstatus, 0x08 ; Disable interrupts
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
call _tx_execution_isr_exit ; Call the ISR execution exit function
|
||||
#endif
|
||||
|
||||
/* Determine if interrupts are nested. */
|
||||
/* if (--_tx_thread_system_state)
|
||||
{ */
|
||||
|
||||
la t0, _tx_thread_system_state ; Pickup addr of nested interrupt count
|
||||
lw t1, 0(t0) ; Pickup nested interrupt count
|
||||
addi t1, t1, -1 ; Decrement the nested interrupt counter
|
||||
sw t1, 0(t0) ; Store new nested count
|
||||
beqz t1, _tx_thread_not_nested_restore ; If 0, not nested restore
|
||||
|
||||
/* Interrupts are nested. */
|
||||
|
||||
/* Just recover the saved registers and return to the point of
|
||||
interrupt. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Recover floating point registers. */
|
||||
|
||||
flw f0, 0x7C(sp) ; Recover ft0
|
||||
flw f1, 0x80(sp) ; Recover ft1
|
||||
flw f2, 0x84(sp) ; Recover ft2
|
||||
flw f3, 0x88(sp) ; Recover ft3
|
||||
flw f4, 0x8C(sp) ; Recover ft4
|
||||
flw f5, 0x90(sp) ; Recover ft5
|
||||
flw f6, 0x94(sp) ; Recover ft6
|
||||
flw f7, 0x98(sp) ; Recover ft7
|
||||
flw f10,0xA4(sp) ; Recover fa0
|
||||
flw f11,0xA8(sp) ; Recover fa1
|
||||
flw f12,0xAC(sp) ; Recover fa2
|
||||
flw f13,0xB0(sp) ; Recover fa3
|
||||
flw f14,0xB4(sp) ; Recover fa4
|
||||
flw f15,0xB8(sp) ; Recover fa5
|
||||
flw f16,0xBC(sp) ; Recover fa6
|
||||
flw f17,0xC0(sp) ; Recover fa7
|
||||
flw f28,0xEC(sp) ; Recover ft8
|
||||
flw f29,0xF0(sp) ; Recover ft9
|
||||
flw f30,0xF4(sp) ; Recover ft10
|
||||
flw f31,0xF8(sp) ; Recover ft11
|
||||
lw t0, 0xFC(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover standard registers. */
|
||||
|
||||
/* Restore registers,
|
||||
Skip global pointer because that does not change
|
||||
Also skip the saved registers since they have been restored by any function we called.
|
||||
Except s0 since we use it ourselves. */
|
||||
|
||||
lw t0, 0x78(sp) ; Recover mepc
|
||||
csrw mepc, t0 ; Setup mepc
|
||||
li t0, 0x1880 ; Prepare MPIP
|
||||
csrw mstatus, t0 ; Enable MPIP
|
||||
|
||||
lw x1, 0x70(sp) ; Recover RA
|
||||
lw x5, 0x4C(sp) ; Recover t0
|
||||
lw x6, 0x48(sp) ; Recover t1
|
||||
lw x7, 0x44(sp) ; Recover t2
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x10, 0x6C(sp) ; Recover a0
|
||||
lw x11, 0x68(sp) ; Recover a1
|
||||
lw x12, 0x64(sp) ; Recover a2
|
||||
lw x13, 0x60(sp) ; Recover a3
|
||||
lw x14, 0x5C(sp) ; Recover a4
|
||||
lw x15, 0x58(sp) ; Recover a5
|
||||
lw x16, 0x54(sp) ; Recover a6
|
||||
lw x17, 0x50(sp) ; Recover a7
|
||||
lw x28, 0x40(sp) ; Recover t3
|
||||
lw x29, 0x3C(sp) ; Recover t4
|
||||
lw x30, 0x38(sp) ; Recover t5
|
||||
lw x31, 0x34(sp) ; Recover t6
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover stack frame - without floating point enabled
|
||||
#endif
|
||||
mret ; Return to point of interrupt
|
||||
|
||||
/* } */
|
||||
_tx_thread_not_nested_restore:
|
||||
/* Determine if a thread was interrupted and no preemption is required. */
|
||||
/* else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
|
||||
|| (_tx_thread_preempt_disable))
|
||||
{ */
|
||||
|
||||
lw t1, _tx_thread_current_ptr ; Pickup current thread pointer
|
||||
beqz t1, _tx_thread_idle_system_restore ; If NULL, idle system restore
|
||||
|
||||
lw t2, _tx_thread_preempt_disable ; Pickup preempt disable flag
|
||||
bgtz t2, _tx_thread_no_preempt_restore ; If set, restore interrupted thread
|
||||
|
||||
lw t2, _tx_thread_execute_ptr ; Pickup thread execute pointer
|
||||
bne t1, t2, _tx_thread_preempt_restore ; If higher-priority thread is ready, preempt
|
||||
|
||||
|
||||
_tx_thread_no_preempt_restore:
|
||||
/* Restore interrupted thread or ISR. */
|
||||
|
||||
/* Pickup the saved stack pointer. */
|
||||
/* SP = _tx_thread_current_ptr -> tx_thread_stack_ptr; */
|
||||
|
||||
lw sp, 8(t1) ; Switch back to thread's stack
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Recover floating point registers. */
|
||||
|
||||
flw f0, 0x7C(sp) ; Recover ft0
|
||||
flw f1, 0x80(sp) ; Recover ft1
|
||||
flw f2, 0x84(sp) ; Recover ft2
|
||||
flw f3, 0x88(sp) ; Recover ft3
|
||||
flw f4, 0x8C(sp) ; Recover ft4
|
||||
flw f5, 0x90(sp) ; Recover ft5
|
||||
flw f6, 0x94(sp) ; Recover ft6
|
||||
flw f7, 0x98(sp) ; Recover ft7
|
||||
flw f10,0xA4(sp) ; Recover fa0
|
||||
flw f11,0xA8(sp) ; Recover fa1
|
||||
flw f12,0xAC(sp) ; Recover fa2
|
||||
flw f13,0xB0(sp) ; Recover fa3
|
||||
flw f14,0xB4(sp) ; Recover fa4
|
||||
flw f15,0xB8(sp) ; Recover fa5
|
||||
flw f16,0xBC(sp) ; Recover fa6
|
||||
flw f17,0xC0(sp) ; Recover fa7
|
||||
flw f28,0xEC(sp) ; Recover ft8
|
||||
flw f29,0xF0(sp) ; Recover ft9
|
||||
flw f30,0xF4(sp) ; Recover ft10
|
||||
flw f31,0xF8(sp) ; Recover ft11
|
||||
lw t0, 0xFC(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover the saved context and return to the point of interrupt. */
|
||||
|
||||
/* Recover standard registers. */
|
||||
/* Restore registers,
|
||||
Skip global pointer because that does not change */
|
||||
|
||||
lw t0, 0x78(sp) ; Recover mepc
|
||||
csrw mepc, t0 ; Setup mepc
|
||||
li t0, 0x1880 ; Prepare MPIP
|
||||
csrw mstatus, t0 ; Enable MPIP
|
||||
|
||||
lw x1, 0x70(sp) ; Recover RA
|
||||
lw x5, 0x4C(sp) ; Recover t0
|
||||
lw x6, 0x48(sp) ; Recover t1
|
||||
lw x7, 0x44(sp) ; Recover t2
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x10, 0x6C(sp) ; Recover a0
|
||||
lw x11, 0x68(sp) ; Recover a1
|
||||
lw x12, 0x64(sp) ; Recover a2
|
||||
lw x13, 0x60(sp) ; Recover a3
|
||||
lw x14, 0x5C(sp) ; Recover a4
|
||||
lw x15, 0x58(sp) ; Recover a5
|
||||
lw x16, 0x54(sp) ; Recover a6
|
||||
lw x17, 0x50(sp) ; Recover a7
|
||||
lw x28, 0x40(sp) ; Recover t3
|
||||
lw x29, 0x3C(sp) ; Recover t4
|
||||
lw x30, 0x38(sp) ; Recover t5
|
||||
lw x31, 0x34(sp) ; Recover t6
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover stack frame - without floating point enabled
|
||||
#endif
|
||||
mret ; Return to point of interrupt
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
_tx_thread_preempt_restore:
|
||||
/* Instead of directly activating the thread again, ensure we save the
|
||||
entire stack frame by saving the remaining registers. */
|
||||
|
||||
lw t0, 8(t1) ; Pickup thread's stack pointer
|
||||
ori t3, x0, 1 ; Build interrupt stack type
|
||||
sw t3, 0(t0) ; Store stack type
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Store floating point preserved registers. */
|
||||
|
||||
fsw f8, 0x9C(t0) ; Store fs0
|
||||
fsw f9, 0xA0(t0) ; Store fs1
|
||||
fsw f18, 0xC4(t0) ; Store fs2
|
||||
fsw f19, 0xC8(t0) ; Store fs3
|
||||
fsw f20, 0xCC(t0) ; Store fs4
|
||||
fsw f21, 0xD0(t0) ; Store fs5
|
||||
fsw f22, 0xD4(t0) ; Store fs6
|
||||
fsw f23, 0xD8(t0) ; Store fs7
|
||||
fsw f24, 0xDC(t0) ; Store fs8
|
||||
fsw f25, 0xE0(t0) ; Store fs9
|
||||
fsw f26, 0xE4(t0) ; Store fs10
|
||||
fsw f27, 0xE8(t0) ; Store fs11
|
||||
#endif
|
||||
|
||||
/* Store standard preserved registers. */
|
||||
|
||||
sw x9, 0x2C(t0) ; Store s1
|
||||
sw x18, 0x28(t0) ; Store s2
|
||||
sw x19, 0x24(t0) ; Store s3
|
||||
sw x20, 0x20(t0) ; Store s4
|
||||
sw x21, 0x1C(t0) ; Store s5
|
||||
sw x22, 0x18(t0) ; Store s6
|
||||
sw x23, 0x14(t0) ; Store s7
|
||||
sw x24, 0x10(t0) ; Store s8
|
||||
sw x25, 0x0C(t0) ; Store s9
|
||||
sw x26, 0x08(t0) ; Store s10
|
||||
sw x27, 0x04(t0) ; Store s11
|
||||
; Note: s0 is already stored!
|
||||
|
||||
/* Save the remaining time-slice and disable it. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
la t0, _tx_timer_time_slice ; Pickup time slice variable address
|
||||
lw t2, 0(t0) ; Pickup time slice
|
||||
beqz t2, _tx_thread_dont_save_ts ; If 0, skip time slice processing
|
||||
|
||||
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice
|
||||
_tx_timer_time_slice = 0; */
|
||||
|
||||
sw t2, 24(t1) ; Save current time slice
|
||||
sw x0, 0(t0) ; Clear global time slice
|
||||
|
||||
|
||||
/* } */
|
||||
_tx_thread_dont_save_ts:
|
||||
/* Clear the current task pointer. */
|
||||
/* _tx_thread_current_ptr = TX_NULL; */
|
||||
|
||||
/* Return to the scheduler. */
|
||||
/* _tx_thread_schedule(); */
|
||||
|
||||
sw x0, _tx_thread_current_ptr, t0 ; Clear current thread pointer*/
|
||||
/* } */
|
||||
|
||||
_tx_thread_idle_system_restore:
|
||||
/* Just return back to the scheduler! */
|
||||
j _tx_thread_schedule ; Return to scheduler
|
||||
|
||||
/* } */
|
||||
END
|
||||
263
ports/risc-v32/iar/src/tx_thread_context_save.s
Normal file
263
ports/risc-v32/iar/src/tx_thread_context_save.s
Normal file
@@ -0,0 +1,263 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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_system_state
|
||||
EXTERN _tx_thread_system_stack_ptr
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_isr_enter
|
||||
#endif
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_save RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_context_save(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_context_save
|
||||
_tx_thread_context_save:
|
||||
|
||||
/* Upon entry to this routine, it is assumed that interrupts are locked
|
||||
out and the interrupt stack fame has been allocated and x1 (ra) has
|
||||
been saved on the stack. */
|
||||
|
||||
sw x5, 0x4C(sp) ; First store t0 and t1
|
||||
sw x6, 0x48(sp)
|
||||
|
||||
la x5, _tx_thread_system_state ; Pickup address of system state
|
||||
lw x6, 0(x5) ; Pickup system state
|
||||
|
||||
/* Check for a nested interrupt condition. */
|
||||
/* if (_tx_thread_system_state++)
|
||||
{ */
|
||||
beqz x6, _tx_thread_not_nested_save ; If 0, first interrupt condition
|
||||
addi x6, x6, 1 ; Increment the interrupt counter
|
||||
sw x6, 0(x5) ; Store the interrupt counter
|
||||
|
||||
/* Nested interrupt condition.
|
||||
Save the reset of the scratch registers on the stack and return to the
|
||||
calling ISR. */
|
||||
|
||||
sw x7, 0x44(sp) ; Store t2
|
||||
sw x8, 0x30(sp) ; Store s0
|
||||
sw x10, 0x6C(sp) ; Store a0
|
||||
sw x11, 0x68(sp) ; Store a1
|
||||
sw x12, 0x64(sp) ; Store a2
|
||||
sw x13, 0x60(sp) ; Store a3
|
||||
sw x14, 0x5C(sp) ; Store a4
|
||||
sw x15, 0x58(sp) ; Store a5
|
||||
sw x16, 0x54(sp) ; Store a6
|
||||
sw x17, 0x50(sp) ; Store a7
|
||||
sw x28, 0x40(sp) ; Store t3
|
||||
sw x29, 0x3C(sp) ; Store t4
|
||||
sw x30, 0x38(sp) ; Store t5
|
||||
sw x31, 0x34(sp) ; Store t6
|
||||
csrr t0, mepc ; Load exception program counter
|
||||
sw t0, 0x78(sp) ; Save it on the stack
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Save floating point scratch registers. */
|
||||
|
||||
fsw f0, 0x7C(sp) ; Store ft0
|
||||
fsw f1, 0x80(sp) ; Store ft1
|
||||
fsw f2, 0x84(sp) ; Store ft2
|
||||
fsw f3, 0x88(sp) ; Store ft3
|
||||
fsw f4, 0x8C(sp) ; Store ft4
|
||||
fsw f5, 0x90(sp) ; Store ft5
|
||||
fsw f6, 0x94(sp) ; Store ft6
|
||||
fsw f7, 0x98(sp) ; Store ft7
|
||||
fsw f10,0xA4(sp) ; Store fa0
|
||||
fsw f11,0xA8(sp) ; Store fa1
|
||||
fsw f12,0xAC(sp) ; Store fa2
|
||||
fsw f13,0xB0(sp) ; Store fa3
|
||||
fsw f14,0xB4(sp) ; Store fa4
|
||||
fsw f15,0xB8(sp) ; Store fa5
|
||||
fsw f16,0xBC(sp) ; Store fa6
|
||||
fsw f17,0xC0(sp) ; Store fa7
|
||||
fsw f28,0xEC(sp) ; Store ft8
|
||||
fsw f29,0xF0(sp) ; Store ft9
|
||||
fsw f30,0xF4(sp) ; Store ft10
|
||||
fsw f31,0xF8(sp) ; Store ft11
|
||||
csrr t0, fcsr
|
||||
sw t0, 0xFC(sp) ; Store fcsr
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
call _tx_execution_isr_enter ; Call the ISR execution enter function
|
||||
#endif
|
||||
|
||||
ret ; Return to calling ISR
|
||||
|
||||
_tx_thread_not_nested_save:
|
||||
/* } */
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
/* else if (_tx_thread_current_ptr)
|
||||
{ */
|
||||
addi x6, x6, 1 ; Increment the interrupt counter
|
||||
sw x6, 0(x5) ; Store the interrupt counter
|
||||
|
||||
/* Not nested: Find the user thread that was running and load our SP */
|
||||
|
||||
lw x5, _tx_thread_current_ptr ; Pickup current thread pointer
|
||||
beqz x5, _tx_thread_idle_system_save ; If NULL, idle system was interrupted
|
||||
|
||||
/* Save the standard scratch registers. */
|
||||
|
||||
sw x7, 0x44(sp) ; Store t2
|
||||
sw x8, 0x30(sp) ; Store s0
|
||||
sw x10, 0x6C(sp) ; Store a0
|
||||
sw x11, 0x68(sp) ; Store a1
|
||||
sw x12, 0x64(sp) ; Store a2
|
||||
sw x13, 0x60(sp) ; Store a3
|
||||
sw x14, 0x5C(sp) ; Store a4
|
||||
sw x15, 0x58(sp) ; Store a5
|
||||
sw x16, 0x54(sp) ; Store a6
|
||||
sw x17, 0x50(sp) ; Store a7
|
||||
sw x28, 0x40(sp) ; Store t3
|
||||
sw x29, 0x3C(sp) ; Store t4
|
||||
sw x30, 0x38(sp) ; Store t5
|
||||
sw x31, 0x34(sp) ; Store t6
|
||||
|
||||
csrr t0, mepc ; Load exception program counter
|
||||
sw t0, 0x78(sp) ; Save it on the stack
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Save floating point scratch registers. */
|
||||
|
||||
fsw f0, 0x7C(sp) ; Store ft0
|
||||
fsw f1, 0x80(sp) ; Store ft1
|
||||
fsw f2, 0x84(sp) ; Store ft2
|
||||
fsw f3, 0x88(sp) ; Store ft3
|
||||
fsw f4, 0x8C(sp) ; Store ft4
|
||||
fsw f5, 0x90(sp) ; Store ft5
|
||||
fsw f6, 0x94(sp) ; Store ft6
|
||||
fsw f7, 0x98(sp) ; Store ft7
|
||||
fsw f10,0xA4(sp) ; Store fa0
|
||||
fsw f11,0xA8(sp) ; Store fa1
|
||||
fsw f12,0xAC(sp) ; Store fa2
|
||||
fsw f13,0xB0(sp) ; Store fa3
|
||||
fsw f14,0xB4(sp) ; Store fa4
|
||||
fsw f15,0xB8(sp) ; Store fa5
|
||||
fsw f16,0xBC(sp) ; Store fa6
|
||||
fsw f17,0xC0(sp) ; Store fa7
|
||||
fsw f28,0xEC(sp) ; Store ft8
|
||||
fsw f29,0xF0(sp) ; Store ft9
|
||||
fsw f30,0xF4(sp) ; Store ft10
|
||||
fsw f31,0xF8(sp) ; Store ft11
|
||||
csrr t0, fcsr
|
||||
sw t0, 0xFC(sp) ; Store fcsr
|
||||
#endif
|
||||
|
||||
/* Save the current stack pointer in the thread's control block. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
|
||||
|
||||
/* Switch to the system stack. */
|
||||
/* sp = _tx_thread_system_stack_ptr; */
|
||||
|
||||
lw t1, _tx_thread_current_ptr ; Pickup current thread pointer
|
||||
sw sp, 8(t1) ; Save stack pointer*/
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
/* _tx_execution_isr_enter is called with thread stack pointer */
|
||||
call _tx_execution_isr_enter ; Call the ISR execution enter function
|
||||
#endif
|
||||
|
||||
|
||||
lw sp, _tx_thread_system_stack_ptr ; Switch to system stack
|
||||
ret ; Return to calling ISR
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
|
||||
_tx_thread_idle_system_save:
|
||||
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
call _tx_execution_isr_enter ; Call the ISR execution enter function
|
||||
#endif
|
||||
|
||||
/* Interrupt occurred in the scheduling loop. */
|
||||
|
||||
/* }
|
||||
} */
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover the reserved stack space
|
||||
#endif
|
||||
ret ; Return to calling ISR
|
||||
|
||||
END
|
||||
|
||||
94
ports/risc-v32/iar/src/tx_thread_interrupt_control.s
Normal file
94
ports/risc-v32/iar/src/tx_thread_interrupt_control.s
Normal file
@@ -0,0 +1,94 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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" */
|
||||
|
||||
RETURN_MASK DEFINE 0x0000000F
|
||||
SET_SR_MASK DEFINE 0xFFFFFFF0
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_control RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* UINT _tx_thread_interrupt_control(UINT new_posture)
|
||||
{ */
|
||||
PUBLIC _tx_thread_interrupt_control
|
||||
_tx_thread_interrupt_control:
|
||||
/* Pickup current interrupt lockout posture. */
|
||||
|
||||
csrr t0, mstatus
|
||||
mv t1, t0 ; Save original mstatus for return
|
||||
|
||||
/* Apply the new interrupt posture. */
|
||||
|
||||
li t2, SET_SR_MASK ; Build set SR mask
|
||||
and t0, t0, t2 ; Isolate interrupt lockout bits
|
||||
or t0, t0, a0 ; Put new lockout bits in
|
||||
csrw mstatus, t0
|
||||
andi a0, t1, RETURN_MASK ; Return original mstatus.
|
||||
ret
|
||||
/* } */
|
||||
END
|
||||
|
||||
274
ports/risc-v32/iar/src/tx_thread_schedule.s
Normal file
274
ports/risc-v32/iar/src/tx_thread_schedule.s
Normal file
@@ -0,0 +1,274 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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_execute_ptr
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_timer_time_slice
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_thread_enter
|
||||
#endif
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_schedule RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_schedule(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_schedule
|
||||
_tx_thread_schedule:
|
||||
|
||||
/* Enable interrupts. */
|
||||
csrsi mstatus, 0x08 ; Enable interrupts
|
||||
|
||||
/* Wait for a thread to execute. */
|
||||
/* do
|
||||
{ */
|
||||
|
||||
la t0, _tx_thread_execute_ptr ; Pickup address of execute ptr
|
||||
_tx_thread_schedule_loop:
|
||||
lw t1, 0(t0) ; Pickup next thread to execute
|
||||
beqz t1, _tx_thread_schedule_loop ; If NULL, wait for thread to execute
|
||||
|
||||
/* }
|
||||
while(_tx_thread_execute_ptr == TX_NULL); */
|
||||
|
||||
/* Yes! We have a thread to execute. Lockout interrupts and
|
||||
transfer control to it. */
|
||||
csrci mstatus, 0x08 ; Lockout interrupts
|
||||
|
||||
/* Setup the current thread pointer. */
|
||||
/* _tx_thread_current_ptr = _tx_thread_execute_ptr; */
|
||||
|
||||
la t0, _tx_thread_current_ptr ; Pickup current thread pointer address
|
||||
sw t1, 0(t0) ; Set current thread pointer
|
||||
|
||||
/* Increment the run count for this thread. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_run_count++; */
|
||||
|
||||
lw t2, 4(t1) ; Pickup run count
|
||||
lw t3, 24(t1) ; Pickup time slice value
|
||||
addi t2, t2, 1 ; Increment run count
|
||||
sw t2, 4(t1) ; Store new run count
|
||||
|
||||
/* Setup time-slice, if present. */
|
||||
/* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */
|
||||
|
||||
la t2, _tx_timer_time_slice ; Pickup time-slice variable address
|
||||
|
||||
/* Switch to the thread's stack. */
|
||||
/* SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */
|
||||
|
||||
lw sp, 8(t1) ; Switch to thread's stack
|
||||
sw t3, 0(t2) ; Store new time-slice*/
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
call _tx_execution_thread_enter ; Call the thread execution enter function
|
||||
#endif
|
||||
|
||||
/* Determine if an interrupt frame or a synchronous task suspension frame
|
||||
is present. */
|
||||
|
||||
lw t2, 0(sp) ; Pickup stack type
|
||||
beqz t2, _tx_thread_synch_return ; If 0, solicited thread return
|
||||
|
||||
/* Determine if floating point registers need to be recovered. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
flw f0, 0x7C(sp) ; Recover ft0
|
||||
flw f1, 0x80(sp) ; Recover ft1
|
||||
flw f2, 0x84(sp) ; Recover ft2
|
||||
flw f3, 0x88(sp) ; Recover ft3
|
||||
flw f4, 0x8C(sp) ; Recover ft4
|
||||
flw f5, 0x90(sp) ; Recover ft5
|
||||
flw f6, 0x94(sp) ; Recover ft6
|
||||
flw f7, 0x98(sp) ; Recover ft7
|
||||
flw f8, 0x9C(sp) ; Recover fs0
|
||||
flw f9, 0xA0(sp) ; Recover fs1
|
||||
flw f10,0xA4(sp) ; Recover fa0
|
||||
flw f11,0xA8(sp) ; Recover fa1
|
||||
flw f12,0xAC(sp) ; Recover fa2
|
||||
flw f13,0xB0(sp) ; Recover fa3
|
||||
flw f14,0xB4(sp) ; Recover fa4
|
||||
flw f15,0xB8(sp) ; Recover fa5
|
||||
flw f16,0xBC(sp) ; Recover fa6
|
||||
flw f17,0xC0(sp) ; Recover fa7
|
||||
flw f18,0xC4(sp) ; Recover fs2
|
||||
flw f19,0xC8(sp) ; Recover fs3
|
||||
flw f20,0xCC(sp) ; Recover fs4
|
||||
flw f21,0xD0(sp) ; Recover fs5
|
||||
flw f22,0xD4(sp) ; Recover fs6
|
||||
flw f23,0xD8(sp) ; Recover fs7
|
||||
flw f24,0xDC(sp) ; Recover fs8
|
||||
flw f25,0xE0(sp) ; Recover fs9
|
||||
flw f26,0xE4(sp) ; Recover fs10
|
||||
flw f27,0xE8(sp) ; Recover fs11
|
||||
flw f28,0xEC(sp) ; Recover ft8
|
||||
flw f29,0xF0(sp) ; Recover ft9
|
||||
flw f30,0xF4(sp) ; Recover ft10
|
||||
flw f31,0xF8(sp) ; Recover ft11
|
||||
lw t0, 0xFC(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover standard registers. */
|
||||
|
||||
lw t0, 0x78(sp) ; Recover mepc
|
||||
csrw mepc, t0 ; Store mepc
|
||||
li t0, 0x1880 ; Prepare MPIP
|
||||
csrw mstatus, t0 ; Enable MPIP
|
||||
|
||||
lw x1, 0x70(sp) ; Recover RA
|
||||
lw x5, 0x4C(sp) ; Recover t0
|
||||
lw x6, 0x48(sp) ; Recover t1
|
||||
lw x7, 0x44(sp) ; Recover t2
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x9, 0x2C(sp) ; Recover s1
|
||||
lw x10, 0x6C(sp) ; Recover a0
|
||||
lw x11, 0x68(sp) ; Recover a1
|
||||
lw x12, 0x64(sp) ; Recover a2
|
||||
lw x13, 0x60(sp) ; Recover a3
|
||||
lw x14, 0x5C(sp) ; Recover a4
|
||||
lw x15, 0x58(sp) ; Recover a5
|
||||
lw x16, 0x54(sp) ; Recover a6
|
||||
lw x17, 0x50(sp) ; Recover a7
|
||||
lw x18, 0x28(sp) ; Recover s2
|
||||
lw x19, 0x24(sp) ; Recover s3
|
||||
lw x20, 0x20(sp) ; Recover s4
|
||||
lw x21, 0x1C(sp) ; Recover s5
|
||||
lw x22, 0x18(sp) ; Recover s6
|
||||
lw x23, 0x14(sp) ; Recover s7
|
||||
lw x24, 0x10(sp) ; Recover s8
|
||||
lw x25, 0x0C(sp) ; Recover s9
|
||||
lw x26, 0x08(sp) ; Recover s10
|
||||
lw x27, 0x04(sp) ; Recover s11
|
||||
lw x28, 0x40(sp) ; Recover t3
|
||||
lw x29, 0x3C(sp) ; Recover t4
|
||||
lw x30, 0x38(sp) ; Recover t5
|
||||
lw x31, 0x34(sp) ; Recover t6
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point registers
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover stack frame - without floating point registers
|
||||
#endif
|
||||
mret ; Return to point of interrupt
|
||||
|
||||
_tx_thread_synch_return:
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
flw f8, 0x3C(sp) ; Recover fs0
|
||||
flw f9, 0x40(sp) ; Recover fs1
|
||||
flw f18,0x44(sp) ; Recover fs2
|
||||
flw f19,0x48(sp) ; Recover fs3
|
||||
flw f20,0x4C(sp) ; Recover fs4
|
||||
flw f21,0x50(sp) ; Recover fs5
|
||||
flw f22,0x54(sp) ; Recover fs6
|
||||
flw f23,0x58(sp) ; Recover fs7
|
||||
flw f24,0x5C(sp) ; Recover fs8
|
||||
flw f25,0x60(sp) ; Recover fs9
|
||||
flw f26,0x64(sp) ; Recover fs10
|
||||
flw f27,0x68(sp) ; Recover fs11
|
||||
lw t0, 0x6C(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover standard preserved registers. */
|
||||
/* Recover standard registers. */
|
||||
|
||||
lw x1, 0x34(sp) ; Recover RA
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x9, 0x2C(sp) ; Recover s1
|
||||
lw x18, 0x28(sp) ; Recover s2
|
||||
lw x19, 0x24(sp) ; Recover s3
|
||||
lw x20, 0x20(sp) ; Recover s4
|
||||
lw x21, 0x1C(sp) ; Recover s5
|
||||
lw x22, 0x18(sp) ; Recover s6
|
||||
lw x23, 0x14(sp) ; Recover s7
|
||||
lw x24, 0x10(sp) ; Recover s8
|
||||
lw x25, 0x0C(sp) ; Recover s9
|
||||
lw x26, 0x08(sp) ; Recover s10
|
||||
lw x27, 0x04(sp) ; Recover s11
|
||||
lw t0, 0x38(sp) ; Recover mstatus
|
||||
csrw mstatus, t0 ; Store mstatus, enables interrupt
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 116 ; Recover stack frame
|
||||
#else
|
||||
addi sp, sp, 64 ; Recover stack frame
|
||||
#endif
|
||||
ret ; Return to thread
|
||||
|
||||
/* } */
|
||||
END
|
||||
|
||||
240
ports/risc-v32/iar/src/tx_thread_stack_build.s
Normal file
240
ports/risc-v32/iar/src/tx_thread_stack_build.s
Normal file
@@ -0,0 +1,240 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_stack_build RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.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 RISC-V RV32 should look like the following after it is built:
|
||||
|
||||
Stack Top: 1 (00) Interrupt stack frame type
|
||||
x27 (04) Initial s11
|
||||
x26 (08) Initial s10
|
||||
x25 (12) Initial s9
|
||||
x24 (16) Initial s8
|
||||
x23 (20) Initial s7
|
||||
x22 (24) Initial s6
|
||||
x21 (28) Initial s5
|
||||
x20 (32) Initial s4
|
||||
x19 (36) Initial s3
|
||||
x18 (40) Initial s2
|
||||
x9 (44) Initial s1
|
||||
x8 (48) Initial s0
|
||||
x31 (52) Initial t6
|
||||
x30 (56) Initial t5
|
||||
x29 (60) Initial t4
|
||||
x28 (64) Initial t3
|
||||
x7 (68) Initial t2
|
||||
x6 (72) Initial t1
|
||||
x5 (76) Initial t0
|
||||
x17 (80) Initial a7
|
||||
x16 (84) Initial a6
|
||||
x15 (88) Initial a5
|
||||
x14 (92) Initial a4
|
||||
x13 (96) Initial a3
|
||||
x12 (100) Initial a2
|
||||
x11 (104) Initial a1
|
||||
x10 (108) Initial a0
|
||||
x1 (112) Initial ra
|
||||
mepc (120) Initial mepc
|
||||
If floating point support:
|
||||
f0 (124) Inital ft0
|
||||
f1 (128) Inital ft1
|
||||
f2 (132) Inital ft2
|
||||
f3 (136) Inital ft3
|
||||
f4 (140) Inital ft4
|
||||
f5 (144) Inital ft5
|
||||
f6 (148) Inital ft6
|
||||
f7 (152) Inital ft7
|
||||
f8 (156) Inital fs0
|
||||
f9 (160) Inital fs1
|
||||
f10 (164) Inital fa0
|
||||
f11 (168) Inital fa1
|
||||
f12 (172) Inital fa2
|
||||
f13 (176) Inital fa3
|
||||
f14 (180) Inital fa4
|
||||
f15 (184) Inital fa5
|
||||
f16 (188) Inital fa6
|
||||
f17 (192) Inital fa7
|
||||
f18 (196) Inital fs2
|
||||
f19 (200) Inital fs3
|
||||
f20 (204) Inital fs4
|
||||
f21 (208) Inital fs5
|
||||
f22 (212) Inital fs6
|
||||
f23 (216) Inital fs7
|
||||
f24 (220) Inital fs8
|
||||
f25 (224) Inital fs9
|
||||
f26 (228) Inital fs10
|
||||
f27 (232) Inital fs11
|
||||
f28 (236) Inital ft8
|
||||
f29 (240) Inital ft9
|
||||
f30 (244) Inital ft10
|
||||
f31 (248) Inital ft11
|
||||
fscr (252) Inital fscr
|
||||
|
||||
Stack Bottom: (higher memory address) */
|
||||
|
||||
lw t0, 16(a0) ; Pickup end of stack area
|
||||
li t1, ~15 ; Build 16-byte alignment mask
|
||||
and t0, t0, t1 ; Make sure 16-byte alignment
|
||||
|
||||
/* Actually build the stack frame. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi t0, t0, -260
|
||||
#else
|
||||
addi t0, t0, -128 ; Allocate space for the stack frame
|
||||
#endif
|
||||
li t1, 1 ; Build stack type
|
||||
sw t1, 0(t0) ; Place stack type on the top
|
||||
sw x0, 4(t0) ; Initial s11
|
||||
sw x0, 8(t0) ; Initial s10
|
||||
sw x0, 12(t0) ; Initial s9
|
||||
sw x0, 16(t0) ; Initial s8
|
||||
sw x0, 20(t0) ; Initial s7
|
||||
sw x0, 24(t0) ; Initial s6
|
||||
sw x0, 28(t0) ; Initial s5
|
||||
sw x0, 32(t0) ; Initial s4
|
||||
sw x0, 36(t0) ; Initial s3
|
||||
sw x0, 40(t0) ; Initial s2
|
||||
sw x0, 44(t0) ; Initial s1
|
||||
sw x0, 48(t0) ; Initial s0
|
||||
sw x0, 52(t0) ; Initial t6
|
||||
sw x0, 56(t0) ; Initial t5
|
||||
sw x0, 60(t0) ; Initial t4
|
||||
sw x0, 64(t0) ; Initial t3
|
||||
sw x0, 68(t0) ; Initial t2
|
||||
sw x0, 72(t0) ; Initial t1
|
||||
sw x0, 76(t0) ; Initial t0
|
||||
sw x0, 80(t0) ; Initial a7
|
||||
sw x0, 84(t0) ; Initial a6
|
||||
sw x0, 88(t0) ; Initial a5
|
||||
sw x0, 92(t0) ; Initial a4
|
||||
sw x0, 96(t0) ; Initial a3
|
||||
sw x0, 100(t0) ; Initial a2
|
||||
sw x0, 104(t0) ; Initial a1
|
||||
sw x0, 108(t0) ; Initial a0
|
||||
sw x0, 112(t0) ; Initial ra
|
||||
sw a1, 120(t0) ; Initial mepc
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
sw x0, 124(t0) ; Inital ft0
|
||||
sw x0, 128(t0) ; Inital ft1
|
||||
sw x0, 132(t0) ; Inital ft2
|
||||
sw x0, 136(t0) ; Inital ft3
|
||||
sw x0, 140(t0) ; Inital ft4
|
||||
sw x0, 144(t0) ; Inital ft5
|
||||
sw x0, 148(t0) ; Inital ft6
|
||||
sw x0, 152(t0) ; Inital ft7
|
||||
sw x0, 156(t0) ; Inital fs0
|
||||
sw x0, 160(t0) ; Inital fs1
|
||||
sw x0, 164(t0) ; Inital fa0
|
||||
sw x0, 168(t0) ; Inital fa1
|
||||
sw x0, 172(t0) ; Inital fa2
|
||||
sw x0, 176(t0) ; Inital fa3
|
||||
sw x0, 180(t0) ; Inital fa4
|
||||
sw x0, 184(t0) ; Inital fa5
|
||||
sw x0, 188(t0) ; Inital fa6
|
||||
sw x0, 192(t0) ; Inital fa7
|
||||
sw x0, 196(t0) ; Inital fs2
|
||||
sw x0, 200(t0) ; Inital fs3
|
||||
sw x0, 204(t0) ; Inital fs4
|
||||
sw x0, 208(t0) ; Inital fs5
|
||||
sw x0, 212(t0) ; Inital fs6
|
||||
sw x0, 216(t0) ; Inital fs7
|
||||
sw x0, 220(t0) ; Inital fs8
|
||||
sw x0, 224(t0) ; Inital fs9
|
||||
sw x0, 228(t0) ; Inital fs10
|
||||
sw x0, 232(t0) ; Inital fs11
|
||||
sw x0, 236(t0) ; Inital ft8
|
||||
sw x0, 240(t0) ; Inital ft9
|
||||
sw x0, 244(t0) ; Inital ft10
|
||||
sw x0, 248(t0) ; Inital ft11
|
||||
csrr a1, fcsr ; Read fcsr and use it for initial value for each thread
|
||||
sw a1, 252(t0) ; Initial fscr
|
||||
sw x0, 256(t0) ; Reserved word (0)
|
||||
#else
|
||||
sw x0, 124(t0) ; Reserved word (0)
|
||||
#endif
|
||||
|
||||
/* Setup stack pointer. */
|
||||
/* thread_ptr -> tx_thread_stack_ptr = t0; */
|
||||
|
||||
sw t0, 8(a0) ; Save stack pointer in thread's
|
||||
ret ; control block and return
|
||||
/* } */
|
||||
END
|
||||
|
||||
184
ports/risc-v32/iar/src/tx_thread_system_return.s
Normal file
184
ports/risc-v32/iar/src/tx_thread_system_return.s
Normal file
@@ -0,0 +1,184 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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_execute_ptr
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_thread_system_stack_ptr
|
||||
EXTERN _tx_thread_schedule
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_thread_exit
|
||||
#endif
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_system_return RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is target processor specific. It is used to transfer */
|
||||
/* control from a thread back to the system. Only a minimal context */
|
||||
/* is saved since the compiler assumes temp registers are going to get */
|
||||
/* slicked by a function call anyway. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_schedule Thread scheduling loop */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ThreadX components */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_system_return(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_system_return
|
||||
_tx_thread_system_return:
|
||||
|
||||
/* Save minimal context on the stack. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, -116 ; Allocate space on the stack - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, -64 ; Allocate space on the stack - without floating point enabled
|
||||
#endif
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Store floating point preserved registers. */
|
||||
|
||||
fsw f8, 0x3C(sp) ; Store fs0
|
||||
fsw f9, 0x40(sp) ; Store fs1
|
||||
fsw f18, 0x44(sp) ; Store fs2
|
||||
fsw f19, 0x48(sp) ; Store fs3
|
||||
fsw f20, 0x4C(sp) ; Store fs4
|
||||
fsw f21, 0x50(sp) ; Store fs5
|
||||
fsw f22, 0x54(sp) ; Store fs6
|
||||
fsw f23, 0x58(sp) ; Store fs7
|
||||
fsw f24, 0x5C(sp) ; Store fs8
|
||||
fsw f25, 0x60(sp) ; Store fs9
|
||||
fsw f26, 0x64(sp) ; Store fs10
|
||||
fsw f27, 0x68(sp) ; Store fs11
|
||||
csrr t0, fcsr
|
||||
sw t0, 0x6C(sp) ; Store fcsr
|
||||
#endif
|
||||
|
||||
|
||||
sw x0, 0(sp) ; Solicited stack type
|
||||
sw x1, 0x34(sp) ; Save RA
|
||||
sw x8, 0x30(sp) ; Save s0
|
||||
sw x9, 0x2C(sp) ; Save s1
|
||||
sw x18, 0x28(sp) ; Save s2
|
||||
sw x19, 0x24(sp) ; Save s3
|
||||
sw x20, 0x20(sp) ; Save s4
|
||||
sw x21, 0x1C(sp) ; Save s5
|
||||
sw x22, 0x18(sp) ; Save s6
|
||||
sw x23, 0x14(sp) ; Save s7
|
||||
sw x24, 0x10(sp) ; Save s8
|
||||
sw x25, 0x0C(sp) ; Save s9
|
||||
sw x26, 0x08(sp) ; Save s10
|
||||
sw x27, 0x04(sp) ; Save s11
|
||||
csrr t0, mstatus ; Pickup mstatus
|
||||
sw t0, 0x38(sp) ; Save mstatus
|
||||
|
||||
|
||||
/* Lockout interrupts. - will be enabled in _tx_thread_schedule */
|
||||
|
||||
csrci mstatus, 0xF
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
call _tx_execution_thread_exit ; Call the thread execution exit function
|
||||
#endif
|
||||
|
||||
la t0, _tx_thread_current_ptr ; Pickup address of pointer
|
||||
lw t1, 0(t0) ; Pickup current thread pointer
|
||||
la t2,_tx_thread_system_stack_ptr ; Pickup stack pointer address
|
||||
|
||||
/* Save current stack and switch to system stack. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
|
||||
SP = _tx_thread_system_stack_ptr; */
|
||||
|
||||
sw sp, 8(t1) ; Save stack pointer
|
||||
lw sp, 0(t2) ; Switch to system stack
|
||||
|
||||
/* Determine if the time-slice is active. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
la t4, _tx_timer_time_slice ; Pickup time slice variable addr
|
||||
lw t3, 0(t4) ; Pickup time slice value
|
||||
la t2, _tx_thread_schedule ; Pickup address of scheduling loop
|
||||
beqz t3, _tx_thread_dont_save_ts ; If no time-slice, don't save it
|
||||
|
||||
/* Save time-slice for the thread and clear the current time-slice. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
|
||||
_tx_timer_time_slice = 0; */
|
||||
|
||||
sw t3, 24(t1) ; Save current time-slice for thread
|
||||
sw x0, 0(t4) ; Clear time-slice variable
|
||||
|
||||
/* } */
|
||||
_tx_thread_dont_save_ts:
|
||||
|
||||
/* Clear the current thread pointer. */
|
||||
/* _tx_thread_current_ptr = TX_NULL; */
|
||||
|
||||
sw x0, 0(t0) ; Clear current thread pointer
|
||||
jr t2 ; Return to thread scheduler
|
||||
|
||||
/* } */
|
||||
|
||||
END
|
||||
|
||||
234
ports/risc-v32/iar/src/tx_timer_interrupt.s
Normal file
234
ports/risc-v32/iar/src/tx_timer_interrupt.s
Normal file
@@ -0,0 +1,234 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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" */
|
||||
|
||||
EXTERN _tx_timer_system_clock
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_timer_expired_time_slice
|
||||
EXTERN _tx_timer_current_ptr
|
||||
EXTERN _tx_timer_expired
|
||||
EXTERN _tx_timer_list_end
|
||||
EXTERN _tx_timer_list_start
|
||||
EXTERN _tx_timer_expiration_process
|
||||
EXTERN _tx_thread_time_slice
|
||||
|
||||
|
||||
SECTION `.mtext`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_timer_interrupt RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function processes the hardware timer interrupt. This */
|
||||
/* processing includes incrementing the system clock and checking for */
|
||||
/* time slice and/or timer expiration. If either is found, the */
|
||||
/* interrupt context save/restore functions are called along with the */
|
||||
/* expiration functions. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_timer_expiration_process Timer expiration processing */
|
||||
/* _tx_thread_time_slice Time slice interrupted thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* interrupt vector */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_timer_interrupt(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_timer_interrupt
|
||||
_tx_timer_interrupt:
|
||||
|
||||
/* Increment the system clock. */
|
||||
/* _tx_timer_system_clock++; */
|
||||
|
||||
la t0, _tx_timer_system_clock ; Pickup address of system clock
|
||||
lw t1, 0(t0) ; Pickup system clock
|
||||
la t2, _tx_timer_time_slice ; Pickup address of time slice
|
||||
lw t3, 0(t2) ; Pickup time slice
|
||||
addi t1, t1, 1 ; Increment system clock
|
||||
sw t1, 0(t0) ; Store new system clock
|
||||
li t6, 0 ; Clear local expired flag
|
||||
|
||||
/* Test for time-slice expiration. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
beqz t3, _tx_timer_no_time_slice ; If 0, skip time slice processing
|
||||
addi t3, t3, -1 ; Decrement the time slice
|
||||
|
||||
/* Decrement the time_slice. */
|
||||
/* _tx_timer_time_slice--; */
|
||||
|
||||
sw t3, 0(t2) ; Store new time slice
|
||||
|
||||
/* Check for expiration. */
|
||||
/* if (__tx_timer_time_slice == 0) */
|
||||
|
||||
bgtz t3, _tx_timer_no_time_slice ; If not 0, has not expired yet
|
||||
li t1, 1 ; Build expired flag
|
||||
|
||||
/* Set the time-slice expired flag. */
|
||||
/* _tx_timer_expired_time_slice = TX_TRUE; */
|
||||
|
||||
la t4, _tx_timer_expired_time_slice ; Get address of expired flag
|
||||
sw t1, 0(t4) ; Set expired flag
|
||||
ori t6, t6, 1 ; Set local expired flag
|
||||
|
||||
/* } */
|
||||
|
||||
_tx_timer_no_time_slice:
|
||||
|
||||
/* Test for timer expiration. */
|
||||
/* if (*_tx_timer_current_ptr)
|
||||
{ */
|
||||
|
||||
la t0, _tx_timer_current_ptr ; Pickup address of current ptr
|
||||
lw t1, 0(t0) ; Pickup current pointer
|
||||
lw t3, 0(t1) ; Pickup the current timer entry
|
||||
la t2, _tx_timer_expired ; Pickup address of timer expired flag
|
||||
li t4, 1 ; Build TX_TRUE flag
|
||||
beqz t3, _tx_timer_no_timer ; If NULL, no timer has expired
|
||||
|
||||
/* Set expiration flag. */
|
||||
/* _tx_timer_expired = TX_TRUE; */
|
||||
|
||||
ori t6, t6, 2 ; Set local expired flag
|
||||
sw t4, 0(t2) ; Set expired flag in memory
|
||||
j _tx_timer_done ; Finished timer processing
|
||||
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
_tx_timer_no_timer:
|
||||
|
||||
/* No timer expired, increment the timer pointer. */
|
||||
/* _tx_timer_current_ptr++; */
|
||||
|
||||
/* Check for wrap-around. */
|
||||
/* if (_tx_timer_current_ptr == _tx_timer_list_end) */
|
||||
|
||||
la t2, _tx_timer_list_end ; Pickup address of list end pointer
|
||||
lw t3, 0(t2) ; Pickup actual list end
|
||||
addi t1, t1, 4 ; Point to next timer entry
|
||||
sw t1, 0(t0) ; Store new timer pointer
|
||||
bne t1, t3, _tx_timer_skip_wrap ; If not same, good pointer
|
||||
|
||||
/* Wrap to beginning of list. */
|
||||
/* _tx_timer_current_ptr = _tx_timer_list_start; */
|
||||
|
||||
la t2, _tx_timer_list_start ; Pickup address of list start pointer
|
||||
lw t4, 0(t2) ; Pickup start of the list
|
||||
sw t4, 0(t0) ; Store new timer pointer*/
|
||||
|
||||
|
||||
_tx_timer_skip_wrap:
|
||||
/* } */
|
||||
|
||||
_tx_timer_done:
|
||||
|
||||
|
||||
/* See if anything has expired. */
|
||||
/* if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
|
||||
{ */
|
||||
|
||||
beqz t6, _tx_timer_nothing_expired ; If nothing expired skip the rest
|
||||
and t2, t6, 2 ; Isolate the timer expired bit
|
||||
addi sp, sp, -16 ; Allocate some storage on the stack
|
||||
sw t6, 0(sp) ; Save local expired flag
|
||||
sw ra, 4(sp) ; Save ra
|
||||
|
||||
/* Did a timer expire? */
|
||||
/* if (_tx_timer_expired)
|
||||
{ */
|
||||
|
||||
beqz t2, _tx_timer_dont_activate ; No, timer not expired
|
||||
|
||||
/* Call the timer expiration processing. */
|
||||
/* _tx_timer_expiration_process(void); */
|
||||
|
||||
call _tx_timer_expiration_process ; Call _tx_timer_expiration_process
|
||||
lw t6, 0(sp) ; Recover local expired flag
|
||||
|
||||
/* } */
|
||||
_tx_timer_dont_activate:
|
||||
|
||||
/* Did time slice expire? */
|
||||
/* if (_tx_timer_expired_time_slice)
|
||||
{ */
|
||||
|
||||
and t2, t6, 1 ; Is the timer expired bit set?
|
||||
beqz t2, _tx_timer_not_ts_expiration ; If not, skip time slice processing
|
||||
|
||||
/* Time slice interrupted thread. */
|
||||
/* _tx_thread_time_slice(); */
|
||||
|
||||
call _tx_thread_time_slice ; Call time slice
|
||||
|
||||
/* } */
|
||||
|
||||
_tx_timer_not_ts_expiration:
|
||||
|
||||
lw ra, 4(sp) ; Recover ra
|
||||
addi sp, sp, 16 ; Recover stack space
|
||||
/* } */
|
||||
|
||||
_tx_timer_nothing_expired:
|
||||
|
||||
ret
|
||||
|
||||
/* } */
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user