English / 日本語

Gregory J. Durnan, PhD, CEng, FIMarEST

Free Embedded Coding 5 — RISC-V with the CH32V003
San Diego, CA, USA · Contact · durnan.org

RISC-V with the CH32V003 — A Refined Win10/11 Toolchain, No PowerShell Required

Aside: this is the first article in a new series, Free Embedded Coding — real firmware on real, cheap, genuinely capable hardware, using nothing but free and open-source tools, on an ordinary Windows 10/11 machine. It's numbered 5 because four more foundational ones are still queued up behind it (they're coming) — I wanted to get this one down while the whole toolchain was still fresh in my hands.

Where jMiniNEC above is decades-old BASIC ported faithfully into modern Java, this is the opposite kind of project: brand-new silicon. The chip is WCH's CH32V003 — a 32-bit RISC-V microcontroller that costs pennies — and it's fully supported by an open-source toolchain: no vendor IDE, no licence dance, no "community edition" nag screens. Just GCC, Make, and a USB debug probe called the WCH-LinkE. The goal of this article is getting from an unboxed WCH-LinkE to a one-click build-and-flash workflow inside an editor you may already use for other chips, with as little Windows friction along the way as I could manage.

What You Need

The Package

Everything drops into two folders side by side: CH32_SDK (register headers, linker scripts, Makefiles, and a full set of runnable examples for every WCH CH32V-family chip) and WCH_CH32V003_programmer (the USB flashing/debugging tool itself, plus a small setup helper that installs both the Windows driver and the RISC-V GCC toolchain — no PowerShell scripts, no separate downloads).

CH32_SDK and WCH_CH32V003_programmer folders side by side in Windows Explorer
Everything you need, in two folders
Credit where it's due: both folders are a cleaned-up, consistently-renamed fork of two excellent open-source projects — cnlohr/ch32fun (the SDK) and its companion minichlink (the programmer), by Charles Lohr and contributors. The renaming is purely cosmetic; all the real engineering underneath is theirs. The bundled toolchain is the unmodified Windows build of xpack-riscv-none-elf-gcc from the xPack project.

Wiring It Up

The WCH-LinkE talks to the CH32V003 over a single-wire debug protocol on pin PD1. Three wires do the whole job — power, ground, and PD1 (SWIO) — no separate clock line needed in 1-wire mode.

WCH-LinkE wired to a CH32V003 board on a breadboard
Red = VDD, black = GND, blue = PD1 (SWIO)

Windows and the Unsigned-Driver Problem

Here's the one genuinely annoying part of Windows and RISC-V debug probes: by default, recent Windows 10/11 builds refuse to install an unsigned WinUSB driver, which is exactly the kind of driver a cheap debug probe like the WCH-LinkE needs. Run a driver installer manually on a locked-down machine and it's easy to hit a wall.

Windows rejecting the unsigned WinUSB driver install
Before: Windows refuses the unsigned driver
The setup tool successfully installing the driver
After: the setup tool's one-time policy fix

The fix is a one-time Windows driver-signing policy change, and the bundled setup tool now does it for you. Open WCH_CH32V003_setup.exe (it asks for administrator rights — expected, driver installation always needs them) and choose "Install WCH-LinkE driver." Unplug and replug the probe once so Windows re-enumerates it under the new driver, and it's done for good, on that machine.

Proving the Programmer Can See the Chip

Before installing anything else, it's worth confirming the WCH-LinkE and the CH32V003 are actually talking:

wch_ch32v003_programmer.exe

Found WCH Link
WCH Programmer is LinkE version 2.18
Detected CH32V003
Flash Storage: 16 kB
Part UUID: 1d-ff-ab-cd-86-14-bc-48
Part Type: 00-30-05-00
Read protection: disabled
Interface Setup

That's a real conversation with the chip — exact silicon, flash size, unique part UUID, and read-protection state. If you see this, the hard part is over.

Bundling the Toolchain Instead of Downloading It

This is the part I actually set out to fix. The old approach was a PowerShell script that pulled GCC from a third-party mirror at install time — and mirrors go down, get deprecated, or get blocked by a company firewall. Nothing to download here: the full Windows build of xpack-riscv-none-elf-gcc (GCC 14.2.0) and a small make/busybox bundle ship inside the package already.

Setup tool copying the bundled RISC-V toolchain and updating PATH
One menu option: copy the toolchain, update PATH, done
Aside: this bundled-not-downloaded approach costs disk space — about 1.4 GB unpacked, since it's the full, unpruned xpack distribution rather than a trimmed-down build. In exchange, this article (and the package) keeps working exactly the same way in five years, even if the original xpack release is long gone from GitHub. Given how little a few gigabytes of disk costs today, that trade felt easy.

Building and Flashing From the Command Line

With the toolchain on PATH, building a real example from CH32_SDK is one command:

cd CH32_SDK\examples\blink
make build

Memory region     Used Size  Region Size  %age Used
  FLASH:               688 B      16 KB      4.20%
  RAM:                   0 B       2 KB      0.00%
make build compiling blink.c from the command line
688 bytes for a working blink, in a 16 kB flash

Flashing the result is one more command:

wch_ch32v003_programmer.exe -w blink.bin 0x08000000

0x08000000 is the CH32V003's flash base address. "Image written" means the chip is now running your code — if you wired up an LED, it should already be blinking.

Teaching Geany a Second Architecture

Command-line make build and a flash command is already a workable loop. But if you already use Geany for something else — mine is set up with SDCC for 8051 work — it's worth five minutes wiring RISC-V into it too, without touching that existing setup.

The key idea: Geany's global build commands apply to every .c file you ever open — that's the one place not to touch. Instead, open the RISC-V folder as its own Geany project, and set build commands at the project level via Project → Properties → Build. Project settings override the global ones only while that project is open.
Geany Project Properties Build tab showing unset, grey default commands
Before: Geany's inherited defaults (plain gcc)
Geany Project Properties Build tab with make build and the flash command filled in
After: project-level Build and Flash commands

Three fields, typed directly into that dialog: Compile and Build both set to make build, and an Execute command (I relabelled it "Flash (WCH-LinkE)") set to the full path of wch_ch32v003_programmer.exe followed by -w "%e.bin" 0x08000000. Geany's own cppcheck-based Lint stays untouched — it's architecture-agnostic, so there's no reason to.

A shortcut that didn't pan out: my first attempt was a hand-authored .geany project file with the build commands pre-filled, so the whole project could be dropped onto a fresh machine ready to go. In practice Geany didn't reliably load that section from a hand-written file. Typing the three commands straight into Project Properties → Build, as above, is the version that always works.

Proof: Watch the LED Change Speed

The real test isn't a clean compile — it's the chip visibly doing something different. With blink.c open under the RISC-V project, Build then Flash from Geany's own menu runs exactly the same compile-and-program sequence as the command line did, one click each. For a proof that rules out a stale binary or a cached build, edit the LED toggle delay to a clearly different value, Build, Flash, and watch the blink rate actually change. Log messages can lie; a physically faster or slower blink can't.

CH32V003 board on a breadboard with an LED lit at a changed blink rate
Same board, new blink rate — build and flash both really happened

Wrapping It Up

That's a complete, free, from-scratch path from an unboxed WCH-LinkE to a one-click RISC-V build-and-flash workflow inside an editor you may already use for other architectures — no vendor IDE, no downloads that can rot, and nothing that disturbs a toolchain you've already got set up for other chips. Windows will often refuse an unsigned WinUSB driver by default; bundling the toolchain trades a bit of disk space for something that keeps working regardless of any particular download mirror; and Geany's project-level Build settings are the right tool for adding a second architecture without disturbing an existing editor setup.

The full package — CH32_SDK, the renamed programmer tool, the setup helper, and the bundled RISC-V toolchain — is available on request.

#RISCV #EmbeddedSystems #CH32V003 #WCH #EmbeddedC #Microcontrollers #OpenSourceTools #Geany #FirmwareDevelopment #GregoryJDurnan #DurnanOrg #GregDurnanRF #RFEngineering #MicrowaveSystems