CMake support for WCH RISC-V microcontrollers (CH32 families), modelled on
stm32-cmake. It provides a toolchain
file, find_package modules for the CMSIS device headers and the StdPeriph
(SPL) drivers, and per-device linker-script generation. Device sources are
pulled from wch_libs.
| Family (long / short) | Devices | Core | ISA / ABI | wch_libs dir(s) |
|---|---|---|---|---|
CH32V0 / V0 |
CH32V002–V007, V003 | QingKe V2 | rv32ec / ilp32e |
CH32V003, CH32V00x |
CH32V1 / V1 |
CH32V103 | QingKe V3 | rv32imac / ilp32 |
CH32V10x |
CH32V2 / V2 |
CH32V203, CH32V208 | QingKe V4B/C | rv32imac / ilp32 |
CH32V20x |
CH32V3 / V3 |
CH32V303/305/307 | QingKe V4F | rv32imafc / ilp32f (hard float) |
CH32V30x |
CH32L1 / L1 |
CH32L103 | QingKe V4C | rv32imac / ilp32 |
CH32L103 |
CH32X0 / X0 |
CH32X035 | QingKe V4C | rv32imac / ilp32 |
CH32X035 |
CH641 / CH643 are present in wch_libs but not yet wired up here (their names
don't fit the CH32<letter><digit> scheme the parser assumes).
Two RISC-V toolchains are supported; select with CH32_TARGET_TRIPLET:
riscv32-wch-elf(default) — WCH's own GCC. Understands the vendorxwISA extension, which is appended automatically (e.g.rv32imacxw_zicsr).riscv-none-elf— the generic xPack toolchain.xwis omitted (e.g.rv32imac_zicsr).
cmake -S . -B build -G Ninja # WCH GCC
cmake -S . -B build -G Ninja -DCH32_TARGET_TRIPLET=riscv-none-elf # xPack GCCcmake_minimum_required(VERSION 3.16)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/path/to/wch_cmake/cmake/wch_gcc.cmake)
project(my_firmware C ASM)
# Fetch device sources (from GitHub, or point CH32_LIBS_PATH at a local checkout)
ch32_fetch_cmsis(V2)
ch32_fetch_spl(V2) # only if you use the SPL drivers
find_package(CMSIS COMPONENTS CH32V2 REQUIRED)
find_package(SPL COMPONENTS CH32V2 RCC GPIO REQUIRED)
add_executable(my_firmware src/main.c)
target_link_libraries(my_firmware
SPL::CH32::V2::GPIO
SPL::CH32::V2::RCC
CMSIS::CH32::V203C8 # picks device, generates the linker script
CH32::Nano # newlib-nano
CH32::NoSys) # nosys syscalls stubs
ch32_print_size_of_target(my_firmware)
ch32_generate_hex_file(my_firmware)Use a local wch_libs checkout instead of fetching:
cmake -S . -B build -DCH32_LIBS_PATH=/path/to/wch_libsCMSIS::CH32::<DEVICE>— device headers, system + startup, and a generated linker script (e.g.CMSIS::CH32::V203C8,CMSIS::CH32::L103C8).CMSIS::CH32::<FAMILY|TYPE>— the underlying family/type interface libs.SPL::CH32::<NS>andSPL::CH32::<NS>::<DRIVER>— StdPeriph base + per-driver libs, where<NS>is the family (V2) or, for V0, the SDK type (V003/V00X). Drivers are the uppercased peripheral name (GPIO,RCC,SPI, …).CH32::Nano,CH32::NoSys,CH32::Nano::FloatPrint,CH32::Nano::FloatScan— spec/linker helpers.
ch32_print_size_of_target, ch32_generate_hex_file,
ch32_generate_binary_file, ch32_generate_srec_file,
ch32_get_chip_info, ch32_get_memory_info,
ch32_print_devices_by_family.
See examples/cmsis_blink (register-level) and examples/spl_blink (StdPeriph),
both of which build one target per supported family.
cmake/
wch_gcc.cmake toolchain entry point
FindCMSIS.cmake device headers + startup + linker script
FindSPL.cmake StdPeriph drivers
ch32/
common.cmake families, arch flags, memory info, helpers
devices.cmake device list + memory sizes
utilities.cmake family targets, fetch functions
linker_ld.cmake linker-script template
v0.cmake v1.cmake v2.cmake v3.cmake l1.cmake x0.cmake per-family config
Each ch32/<family>.cmake declares the family's device types, the ISA base
(ec / imac / imafc), ABI, RAM sizes, and device header stem — adding a new
family is mostly a matter of adding one such file plus a devices entry.