Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions cmake/riscv32-unknown-elf-rv32imc.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# /***************************************************************************
# * 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 CORE-V MCU (CV32E40P, RV32IMC)
#
# 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.
#
# 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.
#
# Install both toolchains with: bash scripts/install_riscv.sh
#
# 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))

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}")

# Dedicated riscv32 bare-metal toolchain (riscv-collab riscv32-elf release).
set(CMAKE_C_COMPILER riscv32-unknown-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-unknown-elf-g++)
set(AS riscv32-unknown-elf-as)
set(AR riscv32-unknown-elf-ar)
set(OBJCOPY riscv32-unknown-elf-objcopy)
set(OBJDUMP riscv32-unknown-elf-objdump)
set(SIZE riscv32-unknown-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")
78 changes: 2 additions & 76 deletions cmake/riscv64-gcc-rv32imc.cmake
Original file line number Diff line number Diff line change
@@ -1,76 +1,2 @@
# /***************************************************************************
# * 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.
# *
# * 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. The human contributor has
# * reviewed and verified that the code is correct.
# *
# * SPDX-License-Identifier: MIT and CC0-1.0
# ***************************************************************************/

# CMake toolchain file for CORE-V MCU (CV32E40P, RV32IMC)
#
# Uses the riscv64-unknown-elf-gcc cross-compiler to produce rv32imc/ilp32
# bare-metal firmware. The riscv-collab toolchain (installed to /opt/riscv by
# scripts/install_riscv.sh) is used by default. The Ubuntu package
# gcc-riscv64-unknown-elf also works and can be installed via install_deps.sh.
#
# Note: the riscv-collab toolchain is built without multilib, so it does not
# ship an rv32/ilp32 libgcc. The CORE-V MCU BSP provides a weak __clzsi2
# fallback in bsp/clz.c to satisfy any __builtin_clz() calls without relying
# on libgcc.
#
# 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))

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}")

# Toolchain binaries: riscv64-unknown-elf-gcc cross-compiler.
# The riscv-collab toolchain (scripts/install_riscv.sh → /opt/riscv/bin) is the
# preferred choice. The Ubuntu package (gcc-riscv64-unknown-elf, install via
# install_deps.sh) is also supported. Both are searched via PATH so whichever
# comes first is used; ensure /opt/riscv/bin precedes /usr/bin if you want the
# riscv-collab toolchain.
set(CMAKE_C_COMPILER riscv64-unknown-elf-gcc)
set(CMAKE_CXX_COMPILER riscv64-unknown-elf-g++)
set(AS riscv64-unknown-elf-as)
set(AR riscv64-unknown-elf-ar)
set(OBJCOPY riscv64-unknown-elf-objcopy)
set(OBJDUMP riscv64-unknown-elf-objdump)
set(SIZE riscv64-unknown-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")
# This file is a compatibility alias. Use riscv32-unknown-elf-rv32imc.cmake.
include(${CMAKE_CURRENT_LIST_DIR}/riscv32-unknown-elf-rv32imc.cmake)
27 changes: 15 additions & 12 deletions ports/risc-v32/gnu/example_build/core_v_mcu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,18 @@ Or install individually:

| Tool | Minimum version | Notes |
|------|----------------|-------|
| `riscv64-unknown-elf-gcc` | 13.x | `apt install gcc-riscv64-unknown-elf binutils-riscv64-unknown-elf` |
| `riscv32-unknown-elf-gcc` | 15.x | riscv-collab `riscv32-elf` release — run `bash scripts/install_riscv.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 `riscv64-unknown-elf-gdb` |
| GDB | any multiarch | `apt install gdb-multiarch` — Ubuntu does not ship `riscv32-unknown-elf-gdb` |

> **Note:** There is no `riscv32-unknown-elf-gcc` package required. The
> `riscv64-unknown-elf-gcc` compiler generates RV32 code when passed
> `-march=rv32imc_zicsr -mabi=ilp32`, as configured by the toolchain file.
> **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.

---

Expand Down Expand Up @@ -221,19 +224,19 @@ build/demo_threadx.map — linker map
```bash
THREADX_ROOT=$(realpath ../../../../..)
cmake -B build -G Ninja \
-DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv64-gcc-rv32imc.cmake" \
-DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake" \
.
cmake --build build
```

### Toolchain file

`${THREADX_ROOT}/cmake/riscv64-gcc-rv32imc.cmake` sets:
`${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake` sets:

```
CMAKE_C_COMPILER riscv64-unknown-elf-gcc
CMAKE_ASM_COMPILER riscv64-unknown-elf-gcc
CMAKE_OBJCOPY riscv64-unknown-elf-objcopy
CMAKE_C_COMPILER riscv32-unknown-elf-gcc
CMAKE_ASM_COMPILER riscv32-unknown-elf-gcc
CMAKE_OBJCOPY riscv32-unknown-elf-objcopy
CMAKE_C_FLAGS -march=rv32imc_zicsr -mabi=ilp32 -mcmodel=medlow
```

Expand Down Expand Up @@ -285,7 +288,7 @@ port 3333 (GDB) and 4444 (telnet).
In a second terminal:

```bash
riscv64-unknown-elf-gdb --command=gdb_init
riscv32-unknown-elf-gdb --command=gdb_init
```

`gdb_init` connects to OpenOCD, loads the ELF, sets a breakpoint at `main`, and
Expand Down Expand Up @@ -485,7 +488,7 @@ bash deploy.sh --debug
```

The script starts OpenOCD in the background, waits for it to become ready,
then drives `riscv64-unknown-elf-gdb` to load the ELF. OpenOCD is always
then drives `riscv32-unknown-elf-gdb` to load the ELF. OpenOCD is always
stopped on exit (including Ctrl-C).

---
Expand Down
2 changes: 1 addition & 1 deletion ports/risc-v32/gnu/example_build/core_v_mcu/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
THREADX_ROOT="${SCRIPT_DIR}/../../../../.."
cmake -B "${SCRIPT_DIR}/build" \
-G Ninja \
-DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv64-gcc-rv32imc.cmake" \
-DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake" \
"${SCRIPT_DIR}"
cmake --build "${SCRIPT_DIR}/build"