mirror of
https://github.com/azure-rtos/threadx
synced 2025-02-06 08:08:27 +08:00
247 lines
10 KiB
Plaintext
247 lines
10 KiB
Plaintext
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:
|
|
|
|
04-02-2021 Release 6.1.6 changes:
|
|
tx_port.h Updated macro definition
|
|
|
|
08/09/2020 Initial ThreadX version for RISC-V using IAR Tools.
|
|
|
|
|
|
Copyright(c) 1996-2020 Microsoft Corporation
|
|
|
|
|
|
https://azure.com/rtos
|
|
|