6.1 minor release
This commit is contained in:
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
|
||||
|
||||
Reference in New Issue
Block a user