summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrédéric Desbiens <[email protected]>2026-05-27 17:06:37 -0400
committerGitHub <[email protected]>2026-05-27 17:06:37 -0400
commitd4b9448f84a108ff027bae1731394fda1a33aeea (patch)
treef4f47406c17f60bdd122072e034441b8907847f1
parent6061c43f96dcaf6b5588861f247dae98493a9eee (diff)
Added riscv-none-elf-rv32imc toolchain file for xPack (risc-v32) (#539)
Add cmake/riscv-none-elf-rv32imc.cmake targeting the xPack riscv-none-elf-gcc toolchain with rv32imc_zicsr/ilp32 ABI for bare-metal CORE-V MCU builds. Update cmake/riscv32-unknown-elf-rv32imc.cmake to correctly target rv32gc/ilp32d (matching riscv-collab riscv32-elf ABI) for QEMU regression tests. Update cmake/riscv64-gcc-rv32imc.cmake compat alias to include the new riscv-none-elf-rv32imc.cmake. Update CORE-V MCU example_build: build.sh exports xPack PATH, install_deps.sh downloads xPack 15.2.0-1, README.md reflects new toolchain name/path. Co-authored-by: Copilot <[email protected]>
-rw-r--r--cmake/riscv-none-elf-rv32imc.cmake71
-rw-r--r--cmake/riscv32-unknown-elf-rv32imc.cmake52
-rw-r--r--cmake/riscv64-gcc-rv32imc.cmake4
-rw-r--r--ports/risc-v32/gnu/example_build/core_v_mcu/README.md30
-rwxr-xr-xports/risc-v32/gnu/example_build/core_v_mcu/build.sh8
-rwxr-xr-xports/risc-v32/gnu/example_build/core_v_mcu/install_deps.sh45
6 files changed, 168 insertions, 42 deletions
diff --git a/cmake/riscv-none-elf-rv32imc.cmake b/cmake/riscv-none-elf-rv32imc.cmake
new file mode 100644
index 00000000..647d8099
--- /dev/null
+++ b/cmake/riscv-none-elf-rv32imc.cmake
@@ -0,0 +1,71 @@
+# /***************************************************************************
+# * Copyright (C) 2026 Eclipse ThreadX contributors
+# *
+# * This program and the accompanying materials are made available under the
+# * terms of the MIT License which is available at
+# * https://opensource.org/licenses/MIT.
+# *
+# * SPDX-License-Identifier: MIT
+# ***************************************************************************/
+
+# CMake toolchain file for bare-metal RV32IMC targets (e.g. CORE-V MCU / CV32E40P)
+#
+# Uses the xPack riscv-none-elf-gcc toolchain:
+# https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
+#
+# This is a cross-platform (Linux/macOS/Windows), multilib-capable toolchain
+# analogous to arm-none-eabi-gcc. Its multilib includes rv32imc/ilp32
+# (soft-float), so -lgcc resolves correctly without any distro package.
+#
+# Install via: bash ports/risc-v32/gnu/example_build/core_v_mcu/install_deps.sh
+# (downloads the latest xPack release to /opt/xpack-riscv-none-elf-gcc/)
+#
+# Do NOT use riscv32-unknown-elf-gcc (riscv-collab riscv32-elf release) for
+# this target: that toolchain is built --disable-multilib --with-abi=ilp32d,
+# so its libgcc only provides ilp32d (hardware FP) helpers and cannot link
+# rv32imc/ilp32 soft-float objects.
+#
+# Target ISA : rv32imc_zicsr (integer, multiply, compressed, Zicsr)
+# ABI : ilp32 (32-bit int/long/ptr, soft-float)
+# Code model : medlow (addresses in [0, 2 GiB))
+
+set(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR riscv)
+
+set(THREADX_ARCH "risc-v32")
+set(THREADX_TOOLCHAIN "gnu")
+
+set(ARCH_FLAGS "-march=rv32imc_zicsr -mabi=ilp32 -mcmodel=medlow")
+set(CFLAGS "${ARCH_FLAGS}")
+set(ASFLAGS "${ARCH_FLAGS}")
+set(LDFLAGS "${ARCH_FLAGS}")
+
+# xPack riscv-none-elf multilib toolchain.
+set(CMAKE_C_COMPILER riscv-none-elf-gcc)
+set(CMAKE_CXX_COMPILER riscv-none-elf-g++)
+set(AS riscv-none-elf-as)
+set(AR riscv-none-elf-ar)
+set(OBJCOPY riscv-none-elf-objcopy)
+set(OBJDUMP riscv-none-elf-objdump)
+set(SIZE riscv-none-elf-size)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+# Use static library for compiler feature probing (no linker script yet)
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
+set(CMAKE_C_FLAGS "${CFLAGS}" CACHE INTERNAL "c compiler flags")
+set(CMAKE_CXX_FLAGS "${CFLAGS}" CACHE INTERNAL "cxx compiler flags")
+set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__" CACHE INTERNAL "asm compiler flags")
+set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS}" CACHE INTERNAL "exe link flags")
+
+set(CMAKE_C_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "c debug flags")
+set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "cxx debug flags")
+set(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug flags")
+
+set(CMAKE_C_FLAGS_RELEASE "-Os" CACHE INTERNAL "c release flags")
+set(CMAKE_CXX_FLAGS_RELEASE "-Os" CACHE INTERNAL "cxx release flags")
+set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "asm release flags")
diff --git a/cmake/riscv32-unknown-elf-rv32imc.cmake b/cmake/riscv32-unknown-elf-rv32imc.cmake
index 7e935689..0109799f 100644
--- a/cmake/riscv32-unknown-elf-rv32imc.cmake
+++ b/cmake/riscv32-unknown-elf-rv32imc.cmake
@@ -8,24 +8,26 @@
# * SPDX-License-Identifier: MIT
# ***************************************************************************/
-# CMake toolchain file for CORE-V MCU (CV32E40P, RV32IMC)
+# CMake toolchain file for RV32GC targets (QEMU virt, etc.)
#
# Uses the dedicated riscv32-unknown-elf-gcc bare-metal toolchain from
-# riscv-collab (riscv32-elf-ubuntu-24.04-gcc.tar.xz, installs to /opt/riscv).
-# This is the correct toolchain for RV32 bare-metal targets — analogous to
-# arm-none-eabi-gcc for Cortex-M. It ships a native rv32/ilp32 libgcc with
-# all soft-float and integer helpers (__clzsi2, __muldf3, etc.) built for the
-# correct ABI.
+# riscv-collab (riscv32-elf-ubuntu-24.04-gcc.tar.xz, installs to /opt/riscv
+# via scripts/install_riscv.sh).
#
-# Do NOT use riscv64-unknown-elf-gcc for this target: the riscv-collab
-# riscv64-elf toolchain is built without rv32 multilib and will produce
-# missing-symbol linker errors with -nodefaultlibs.
+# IMPORTANT: the riscv-collab riscv32-elf toolchain is built
+# --disable-multilib --with-abi=ilp32d, so its libgcc only provides
+# ilp32d (hardware double-FP) helpers. This cmake file therefore targets
+# rv32gc/ilp32d, which matches the toolchain's built-in ABI and works
+# correctly with QEMU virt (which emulates hardware FP).
#
-# Install both toolchains with: bash scripts/install_riscv.sh
+# Do NOT use this file for bare-metal targets that lack hardware FP (e.g.
+# CV32E40P, rv32imc). For those, use cmake/riscv64-ubuntu-rv32imc.cmake
+# which calls the Ubuntu gcc-riscv64-unknown-elf package — a multilib build
+# that includes the rv32im/ilp32 (soft-float) libgcc variant.
#
-# Target ISA : rv32imc_zicsr (integer, multiply, compressed, Zicsr)
-# ABI : ilp32 (32-bit int/long/ptr, no hardware FP)
-# Code model : medlow (addresses in [0, 2 GiB))
+# Target ISA : rv32gc (integer, multiply, atomics, FP, compressed, Zicsr)
+# ABI : ilp32d (32-bit int/long/ptr, hardware double-precision FP)
+# Code model : medlow (addresses in [0, 2 GiB))
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR riscv)
@@ -33,7 +35,7 @@ set(CMAKE_SYSTEM_PROCESSOR riscv)
set(THREADX_ARCH "risc-v32")
set(THREADX_TOOLCHAIN "gnu")
-set(ARCH_FLAGS "-march=rv32imc_zicsr -mabi=ilp32 -mcmodel=medlow")
+set(ARCH_FLAGS "-march=rv32gc -mabi=ilp32d -mcmodel=medlow")
set(CFLAGS "${ARCH_FLAGS}")
set(ASFLAGS "${ARCH_FLAGS}")
set(LDFLAGS "${ARCH_FLAGS}")
@@ -67,3 +69,25 @@ set(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug flags")
set(CMAKE_C_FLAGS_RELEASE "-Os" CACHE INTERNAL "c release flags")
set(CMAKE_CXX_FLAGS_RELEASE "-Os" CACHE INTERNAL "cxx release flags")
set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "asm release flags")
+
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+# Use static library for compiler feature probing (no linker script yet)
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
+set(CMAKE_C_FLAGS "${CFLAGS}" CACHE INTERNAL "c compiler flags")
+set(CMAKE_CXX_FLAGS "${CFLAGS}" CACHE INTERNAL "cxx compiler flags")
+set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__" CACHE INTERNAL "asm compiler flags")
+set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS}" CACHE INTERNAL "exe link flags")
+
+set(CMAKE_C_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "c debug flags")
+set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "cxx debug flags")
+set(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug flags")
+
+set(CMAKE_C_FLAGS_RELEASE "-Os" CACHE INTERNAL "c release flags")
+set(CMAKE_CXX_FLAGS_RELEASE "-Os" CACHE INTERNAL "cxx release flags")
+set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "asm release flags")
diff --git a/cmake/riscv64-gcc-rv32imc.cmake b/cmake/riscv64-gcc-rv32imc.cmake
index d3d50115..b0916a2f 100644
--- a/cmake/riscv64-gcc-rv32imc.cmake
+++ b/cmake/riscv64-gcc-rv32imc.cmake
@@ -1,2 +1,2 @@
-# This file is a compatibility alias. Use riscv32-unknown-elf-rv32imc.cmake.
-include(${CMAKE_CURRENT_LIST_DIR}/riscv32-unknown-elf-rv32imc.cmake)
+# This file is a compatibility alias. Use riscv-none-elf-rv32imc.cmake.
+include(${CMAKE_CURRENT_LIST_DIR}/riscv-none-elf-rv32imc.cmake)
diff --git a/ports/risc-v32/gnu/example_build/core_v_mcu/README.md b/ports/risc-v32/gnu/example_build/core_v_mcu/README.md
index d2b8a844..41f45dab 100644
--- a/ports/risc-v32/gnu/example_build/core_v_mcu/README.md
+++ b/ports/risc-v32/gnu/example_build/core_v_mcu/README.md
@@ -57,18 +57,18 @@ Or install individually:
| Tool | Minimum version | Notes |
|------|----------------|-------|
-| `riscv32-unknown-elf-gcc` | 15.x | riscv-collab `riscv32-elf` release — run `bash scripts/install_riscv.sh` |
+| `riscv-none-elf-gcc` | 15.x | xPack riscv-none-elf-gcc — run `bash install_deps.sh` |
| CMake | 3.15 | `apt install cmake` |
| Ninja | 1.10 | `apt install ninja-build` |
| OpenOCD | 0.12 | `apt install openocd` |
-| GDB | any multiarch | `apt install gdb-multiarch` — Ubuntu does not ship `riscv32-unknown-elf-gdb` |
+| GDB | any multiarch | `apt install gdb-multiarch` |
-> **Note:** Use the dedicated `riscv32-unknown-elf-gcc` bare-metal toolchain
-> (riscv-collab `riscv32-elf` release, installs to `/opt/riscv`). This is
-> the RV32 equivalent of `arm-none-eabi-gcc` and ships a native rv32/ilp32
-> libgcc with all required soft-float and integer helpers. Do **not** use
-> `riscv64-unknown-elf-gcc` — the riscv-collab riscv64-elf toolchain has no
-> rv32 multilib and will produce missing-symbol linker errors.
+> **Note:** Use the [xPack riscv-none-elf-gcc](https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack)
+> toolchain — a cross-platform (Linux/macOS/Windows) multilib bare-metal
+> toolchain analogous to `arm-none-eabi-gcc`. Its multilib includes
+> rv32imc/ilp32 (soft-float) libgcc required for the CV32E40P. Do **not**
+> use `riscv32-unknown-elf-gcc` (riscv-collab) — that release is built
+> `--disable-multilib --with-abi=ilp32d` and cannot link soft-float objects.
---
@@ -224,19 +224,19 @@ build/demo_threadx.map — linker map
```bash
THREADX_ROOT=$(realpath ../../../../..)
cmake -B build -G Ninja \
- -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake" \
+ -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv-none-elf-rv32imc.cmake" \
.
cmake --build build
```
### Toolchain file
-`${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake` sets:
+`${THREADX_ROOT}/cmake/riscv-none-elf-rv32imc.cmake` sets:
```
-CMAKE_C_COMPILER riscv32-unknown-elf-gcc
-CMAKE_ASM_COMPILER riscv32-unknown-elf-gcc
-CMAKE_OBJCOPY riscv32-unknown-elf-objcopy
+CMAKE_C_COMPILER riscv-none-elf-gcc
+CMAKE_ASM_COMPILER riscv-none-elf-gcc
+CMAKE_OBJCOPY riscv-none-elf-objcopy
CMAKE_C_FLAGS -march=rv32imc_zicsr -mabi=ilp32 -mcmodel=medlow
```
@@ -288,7 +288,7 @@ port 3333 (GDB) and 4444 (telnet).
In a second terminal:
```bash
-riscv32-unknown-elf-gdb --command=gdb_init
+riscv-none-elf-gdb --command=gdb_init
```
`gdb_init` connects to OpenOCD, loads the ELF, sets a breakpoint at `main`, and
@@ -488,7 +488,7 @@ bash deploy.sh --debug
```
The script starts OpenOCD in the background, waits for it to become ready,
-then drives `riscv32-unknown-elf-gdb` to load the ELF. OpenOCD is always
+then drives `riscv-none-elf-gdb` to load the ELF. OpenOCD is always
stopped on exit (including Ctrl-C).
---
diff --git a/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh b/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh
index c2ccfc55..2e1bb844 100755
--- a/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh
+++ b/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh
@@ -1,9 +1,15 @@
#!/bin/bash
set -e
+
+XPACK_GCC_DIR=/opt/xpack-riscv-none-elf-gcc-15.2.0-1
+if [ -d "${XPACK_GCC_DIR}/bin" ]; then
+ export PATH="${XPACK_GCC_DIR}/bin:${PATH}"
+fi
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
THREADX_ROOT="${SCRIPT_DIR}/../../../../.."
cmake -B "${SCRIPT_DIR}/build" \
-G Ninja \
- -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake" \
+ -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv-none-elf-rv32imc.cmake" \
"${SCRIPT_DIR}"
cmake --build "${SCRIPT_DIR}/build"
diff --git a/ports/risc-v32/gnu/example_build/core_v_mcu/install_deps.sh b/ports/risc-v32/gnu/example_build/core_v_mcu/install_deps.sh
index b4cd46a8..d0192665 100755
--- a/ports/risc-v32/gnu/example_build/core_v_mcu/install_deps.sh
+++ b/ports/risc-v32/gnu/example_build/core_v_mcu/install_deps.sh
@@ -6,11 +6,7 @@
# * terms of the MIT License which is available at
# * https://opensource.org/licenses/MIT.
# *
-# * AI Disclosure: This file was largely AI-generated by Copilot (Sonnet 4.6).
-# * The AI-generated portions may be considered public domain (CC0-1.0)
-# * and not subject to the project's licence.
-# *
-# * SPDX-License-Identifier: MIT AND CC0-1.0
+# * SPDX-License-Identifier: MIT
# ***************************************************************************/
# install_deps.sh -- Install Linux build/debug dependencies for the CORE-V MCU ThreadX port.
@@ -18,6 +14,10 @@
# Supported: Ubuntu 20.04 / 22.04 / 24.04 and Debian derivatives.
# Run as a regular user; sudo is invoked internally where needed.
#
+# Installs:
+# - xPack riscv-none-elf-gcc (multilib bare-metal toolchain, rv32imc/ilp32 capable)
+# - cmake, ninja-build, gdb-multiarch, openocd, usbutils
+#
# Usage:
# bash install_deps.sh
@@ -28,11 +28,21 @@ info() { echo "[INFO] $*"; }
command -v apt-get >/dev/null 2>&1 || die "This script requires apt-get (Ubuntu/Debian)."
-PACKAGES=(
+# ---------------------------------------------------------------------------
+# xPack riscv-none-elf-gcc
+# Cross-platform multilib toolchain (Linux/macOS/Windows).
+# Includes rv32imc/ilp32 (soft-float) libgcc — required for CV32E40P.
+# See: https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
+# ---------------------------------------------------------------------------
+XPACK_VERSION="15.2.0-1"
+XPACK_TARBALL="xpack-riscv-none-elf-gcc-${XPACK_VERSION}-linux-x64.tar.gz"
+XPACK_URL="https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v${XPACK_VERSION}/${XPACK_TARBALL}"
+XPACK_INSTALL_DIR="/opt/xpack-riscv-none-elf-gcc-${XPACK_VERSION}"
+XPACK_BIN="${XPACK_INSTALL_DIR}/bin"
+
+APT_PACKAGES=(
cmake
ninja-build
- gcc-riscv64-unknown-elf
- binutils-riscv64-unknown-elf
gdb-multiarch
openocd
usbutils
@@ -42,12 +52,27 @@ PACKAGES=(
info "Updating package lists ..."
sudo apt-get update -qq
-info "Installing: ${PACKAGES[*]}"
-sudo apt-get install -y "${PACKAGES[@]}"
+info "Installing apt packages: ${APT_PACKAGES[*]}"
+sudo apt-get install -y "${APT_PACKAGES[@]}"
+if [ -x "${XPACK_BIN}/riscv-none-elf-gcc" ]; then
+ info "xPack riscv-none-elf-gcc ${XPACK_VERSION} already installed at ${XPACK_INSTALL_DIR}"
+else
+ info "Downloading xPack riscv-none-elf-gcc ${XPACK_VERSION} ..."
+ wget --no-verbose "${XPACK_URL}" -O "/tmp/${XPACK_TARBALL}"
+ sudo mkdir -p "${XPACK_INSTALL_DIR}"
+ sudo tar xzf "/tmp/${XPACK_TARBALL}" -C /opt
+ rm "/tmp/${XPACK_TARBALL}"
+ info "Installed to ${XPACK_INSTALL_DIR}"
+fi
+
+info ""
+info "Add the toolchain to your PATH:"
+info " export PATH=${XPACK_BIN}:\$PATH"
info ""
info "All dependencies installed."
info ""
info "Next steps:"
info " 1. Run scripts/setup_opella.sh to configure udev rules for the Ashling Opella LD."
info " 2. (WSL only) Follow the usbipd-win instructions printed by setup_opella.sh."
+