1
0
mirror of https://github.com/azure-rtos/threadx synced 2025-02-06 08:08:27 +08:00
threadx/ports/risc-v32/iar/readme_threadx.txt
2021-04-03 01:03:21 +00:00

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