mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-03-24 09:29:38 +08:00
Fixes to the RISC-V32 architecture port layer for Clang.
This commit is contained in:
@@ -1,58 +0,0 @@
|
||||
# RISCV32 clang port
|
||||
|
||||
This is basically a copy of the RISC64 gnu port.
|
||||
The only major modification was changing the load double word (ld)
|
||||
and store double double (sd) word with load word (ld) and store word (sd).
|
||||
|
||||
I also added support for semihosting so the example can be executed on QEMU.
|
||||
|
||||
## How to build
|
||||
|
||||
cd to the folder where this repo is cloned and run the following commands:
|
||||
|
||||
```
|
||||
cd /threadx/ports/risc-v32/clang/example_build/qemu_virt
|
||||
./build_libthreadx.sh
|
||||
./build_threadx_sample.sh
|
||||
```
|
||||
|
||||
The first script will build the ThreadX libraries.
|
||||
You can find the library in <threadx repo>/build/libthreadx.a.
|
||||
|
||||
The second script will build the demo application.
|
||||
You can find the demo application in <threadx repo>/ports/risc-v32/clang/example_build/qemu_virt/build/demo_threadx.elf
|
||||
|
||||
## How to run using QEMU
|
||||
|
||||
cd to the folder where this repo is cloned and run the following command:
|
||||
|
||||
```
|
||||
docker run --rm -it -p 1234:1234 -v $(pwd):/threadx -w /threadx ghcr.io/quintauris-tech/qemu-system-riscv32-v10:latest bash
|
||||
```
|
||||
|
||||
The commands assumes that this repo is clone into a folder named "threadx"
|
||||
|
||||
```
|
||||
cd /threadx/ports/risc-v32/clang/example_build/qemu_virt
|
||||
|
||||
qemu-system-riscv32 -machine virt -m 16M -bios ./build/demo_threadx.elf -display none -chardev stdio,id=stdio0 -semihosting-config enable=on,userspace=on,chardev=stdio0 -gdb tcp::1234
|
||||
```
|
||||
|
||||
This should print output from different threads. In the QEMU output you should see output like the following:
|
||||
|
||||
```
|
||||
[Thread] : thread_xxxx_entry is here!
|
||||
```
|
||||
|
||||
You can use option -S with qemu-system-riscv32 to debug.
|
||||
|
||||
In this case run debugger as /opt/riscv_rv32ima_zicsr/bin/riscv32-unknown-elf-gdb <repo>/ports/risc-v32/gnu/example_build/qemu_virt/build/demo_threadx.elf
|
||||
|
||||
```
|
||||
target remote :1234
|
||||
```
|
||||
|
||||
to connect to the target. Enter 'c' to continue execution.
|
||||
|
||||
|
||||
|
||||
@@ -228,6 +228,8 @@ UINT status;
|
||||
/* Send message to queue 0. */
|
||||
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
|
||||
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS) {
|
||||
puts("[Thread 1] ERROR: Failed to send message!");
|
||||
@@ -257,6 +259,8 @@ UINT status;
|
||||
/* Retrieve a message from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
|
||||
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Check completion status and make sure the message is what we
|
||||
expected. */
|
||||
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received)){
|
||||
|
||||
@@ -67,12 +67,12 @@
|
||||
.extern _tx_thread_context_restore
|
||||
trap_entry:
|
||||
#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
|
||||
addi sp, sp, -65*REGBYTES // Allocate space for all registers - with floating point enabled
|
||||
addi sp, sp, -65*4 // Allocate space for all registers - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, -32*REGBYTES // Allocate space for all registers - without floating point enabled
|
||||
addi sp, sp, -32*4 // Allocate space for all registers - without floating point enabled
|
||||
#endif
|
||||
|
||||
STORE x1, 28*REGBYTES(sp) // Store RA, 28*REGBYTES(because call will override ra [ra is a calle register in riscv])
|
||||
sw x1, 28*4(sp) // Store RA, 28*4(because call will override ra [ra is a calle register in riscv])
|
||||
|
||||
call _tx_thread_context_save
|
||||
|
||||
|
||||
@@ -53,25 +53,7 @@
|
||||
#ifndef TX_PORT_H
|
||||
#define TX_PORT_H
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
# define SLL32 sllw
|
||||
# define STORE sd
|
||||
# define LOAD ld
|
||||
# define LWU lwu
|
||||
# define LOG_REGBYTES 3
|
||||
#else
|
||||
# define SLL32 sll
|
||||
# define STORE sw
|
||||
# define LOAD lw
|
||||
# define LWU lw
|
||||
# define LOG_REGBYTES 2
|
||||
#endif
|
||||
#define REGBYTES (1 << LOG_REGBYTES)
|
||||
|
||||
#else /*not __ASSEMBLER__ */
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Include for memset. */
|
||||
#include <string.h>
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
|
||||
Prerequisites
|
||||
- Install a RISC-V32 bare-metal Clang toolchain
|
||||
- Install a RISC-V32 bare-metal GNU toolchain with riscv32-unknown-elf prefix
|
||||
- Common source: https://github.com/riscv-collab/riscv-gnu-toolchain
|
||||
- Install a RISC-V32 bare-metal GNU toolchain with riscv32-unknown-elf prefix.
|
||||
Common source: https://github.com/riscv-collab/riscv-gnu-toolchain
|
||||
|
||||
Verify the Clang toolchaing:
|
||||
The GNU toolchain is needed because the Clang toolchain does not include some
|
||||
standard headers and libraries, i.e. "string.h".
|
||||
|
||||
Verify the Clang toolchain:
|
||||
clang --version
|
||||
|
||||
Verify the GCC toolchain:
|
||||
@@ -21,6 +24,9 @@ CMake-based build (recommended)
|
||||
|
||||
From the ThreadX top-level directory:
|
||||
|
||||
Set environment variable "GCC_INSTALL_PREFIX" with the location of the
|
||||
GNU toolchain, i.e., export GCC_INSTALL_PREFIX=/opt/riscv_rv32ima
|
||||
|
||||
cmake -Bbuild -GNinja -DCMAKE_TOOLCHAIN_FILE=cmake/riscv32_clang.cmake .
|
||||
cmake --build ./build/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user