A community QEMU fork supports CH32V003/V103/V203/V303/V305/V307/V317/V407 and CH32H417, enabling firmware validation, network emulation, and CI/CD without hardware.
A community-driven QEMU fork now provides system-level emulation for WCH QingKe RISC-V microcontrollers. Instead of flashing every test build to real hardware, developers can compile a CH32V firmware ELF, drop it into QEMU, and immediately see serial output, interact with an RT-Thread shell, ping a virtual Ethernet interface, or step through code with GDB. This is especially useful for early logic verification, protocol-stack debugging, and CI/CD pipelines where keeping a board farm connected is impractical.
The emulator is built around standard QEMU TCG plus WCH-specific extensions. It accepts the actual firmware ELF produced by MounRiver Studio or riscv32-wch-elf-gcc, boots it through the same reset vector used on silicon, and models enough peripherals that many EVT examples run unmodified.
Verified use cases include:CH571/573, CH581/582/583, CH584/585, CH591/592, CH643/645, and CH32X033/X035 can also be tested by selecting the closest core machine. Bluetooth and wireless radios are not emulated, so those stacks still need real hardware.
Build QEMU with the bundled script and then run a firmware image:
./build-wch-qemu.sh -j$(nproc) qemu-system-riscv32 -M ch32v317 -serial stdio -kernel your-app.elfSerial output is routed directly to the terminal, so a simple printf loop becomes visible immediately.
The fork implements WCH's non-standard QingKe extensions inside QEMU TCG:
Create a TAP interface on the host and start QEMU with a NIC:
sudo ip tuntap add tap0 mode tap user $(whoami) sudo ip link set tap0 up sudo ip addr add 192.168.1.1/24 dev tap0 qemu-system-riscv32 -M ch32v317 -serial stdio \ -nic "tap,ifname=tap0,script=no,downscript=no" \ -kernel OrayOS-Tiny-qemu.elfAfter the guest finishes booting, the host can ping the guest address configured in the firmware, and TCP/HTTP services running inside QEMU are reachable from the host.
QEMU exposes a built-in GDB stub. Start QEMU with the CPU halted:
qemu-system-riscv32 -M ch32v317 -serial stdio \ -kernel your-app.elf -s -SThen connect from a second terminal:
riscv32-wch-elf-gdb your-app.elf (gdb) target remote :1234 (gdb) break main (gdb) continue (gdb) info registers (gdb) x/10i $pcThis is often faster than JTAG for inspecting register state and stepping through startup code.
If you are evaluating WCH CH32V003, CH32V208, CH32V307, CH32V317, CH32V407, or CH32H417 for a new design, this emulator can shorten the first weeks of bring-up dramatically.