Welcome to the PlatformIO CH32V Documentation!
The PlatformIO CH32V project intends to provide an easy way for developing firmwares for various W.CH RISC-V based chips. It easily integrates into VSCode and other IDEs thanks to PlatformIO and can be used cross-platform.
Note
This project is under active development.
Contents
Installation
This guide shows how to install the CH32V development environment. Note that this also overlaps with official documentation such as Getting started with VSCode + PlatformIO.
Install VSCode
Download and install VSCode from https://code.visualstudio.com/.
Install PlatformIO
Open the “Extensions” sidebar, search for “PlatformIO” and hit “install”.

Install CH32V Platform
Expand the PlatformIO sidebar (ant icon) and click “PIO Home”.

In the resulting PIO Home window, click on the “Platforms” sidebar and chose “Advanced Installation”

You will be asked for a repistory. Enter the URL and press “Install”.
https://github.com/Community-PIO-CH32V/platform-ch32v.git

The platform should now be successfully installed.
Experienced PlatformIO CLI users can also use the short-hand command
pio pkg install -g -p https://github.com/Community-PIO-CH32V/platform-ch32v.git
Install Drivers / Rules
Windows Driver Installation
Flashing development boards via a WCH-Link(E) probe (and SWCLK and/or SWDIO connection) requires that W.CH’s USB drivers for that are installed.
Download the WCHLink Driver Windows package
Unpack it
Run
WCHLink\SETUP.EXE
and follow installation instructionsRun
WCHLinkSER\SETUP.EXE
and follow installation instructions
If successful, once you plug in the WCH-Link(E) device, you should have a “serial port” and “interface”-type device in the Windows device manager.

Flashing development boards via their built-in USB bootloader requires that WinUSB drivers are loaded for that device.
Download Zadig
Start Zadig and activate Options → List All Devices
Put your development board into bootloader mode
for most: BOOT0 to 3.3V, BOOT1 to GND
or hold marked “BOOT” button
Plug development board into computer
Select the “USB Module” device in Zadig
Select “WinUSB” on the right side
Click “Replace driver”
It should now look like this:

Note
Some devices like the CH5xx chips seem to have a timeout on the USB bootloader, which complicates things. When you hear the USB eject sound, quickly replug the device while holding down the BOOT button of it, then driver installation should go through.
Linux udev Rules
In Linux, for regular non-sudo users to be able to access certain USB devices, like the WCH-Link(E) debugging probe or the USB bootloader device, you need to set up udev rules.
First all, make sure PlatformIO’s udev rules are installed per Documentation.
Then, assuming a Debian-like system with a “plugdev” group, append the following content to /etc/udev/rules.d/99-platformio-udev.rules
:
SUBSYSTEM=="usb", ATTR{idVendor}="1a86", ATTR{idProduct}=="8010", GROUP="plugdev"
SUBSYSTEM=="usb", ATTR{idVendor}="4348", ATTR{idProduct}=="55e0", GROUP="plugdev"
SUBSYSTEM=="usb", ATTR{idVendor}="1a86", ATTR{idProduct}=="8012", GROUP="plugdev"
Restart your system after applying these changes.
Note
If you are running a different type system, replace the GROUP
value as needed, e.g., with uucp
.
Quick Start for Development Boards
Instructions on how to easily get started with known popular development boards.
Board Selection
Building
Uploading
Via Debug Adapter (OpenOCD)
Via USB Bootloader (wchisp)
Via Serial Bootloader
This method is currently unsupported. Looking for a tool that implements this.
Debugging
Hardware setup
WCH-Link
WCH-LinkE
Configuration
Example
General Build Options
FPU / Hard Float
The CH32V30x series of chips has a QingKe V4F core that’s capable of native floating point instructions. This is by-default not used.
To activate it, please change the march
(default: rv32imacxw
, affects generating FPU instructions) and mabi
(default: ilp32
, affects the calling convention and passing of arguments via registers) as follows in the platformio.ini
:
board_build.march = rv32imafcxw
board_build.mabi = ilp32f
Please refer to https://www.sifive.com/blog/all-aboard-part-1-compiler-args for more details.
Linker Script
The linker script can be manually set by using
board_build.ldscript = path/to/linkerscript.ld
None OS SDK
When building with framework = noneos-sdk
, several build options are available for the platformio.ini
.
Link Time Optimization (LTO)
To activate LTO in the compiling and linking stage, use
board_build.use_lto = yes
Startup File
By default, a slightly modified startup file (e.g., startup_ch32v30x_D8.S
) will be used.
If you want to use a startup file that you explicitly placed in the project, turn off the compilation of the built-in one using
board_build.use_builtin_startup_file = no
System / Startup Code
By default, the built-in system_ch32v<series>.c
will be used (example). This file contains the clock setup code and by-default uses the HSE as clock source,
thus needing an external crystal oscillator connected to the chip to function correctly.
If you want to use a system file that you explicitly placed in the project that has the correct settings, turn off the compilation of the built-in one using
board_build.use_builtin_system_code = no
Debug Code
By default, the built-in debug.c
will be compiled in the project (example).
The code in this file contains
delay functions
UART initialization functions
_write
implementation (for making e.g.printf
work, writes data forstdout
to actual UART registers)_sbrk
implementation (needed formalloc
andfree
functions to allocate new memory)
While this is convenient as default, in your project you might want to have full control over these implementations.
To turn off the compilation of the built-in debug implementation, use
board_build.use_builtin_debug_code = no
C++ Support
By default, C++ support is disabled.
To be able to use C++ properly, meaning that constructors of global objects are called etc.,
one would usually need to do adaptions to the startup file (calling __libc_init_array
) and add a _fini
and _init
implementation.
To make things easier, we have already done these modifications in an activatable way. To turn on C++ support, simple use
board_build.cpp_support = yes
This technically defines __PIO_CPP_SUPPORT__
which the built-in startup file will react to
and also compiles our cpp_support.c
file with _weak
overridable _fini
and _init
functions.