CH32 Environment Setup
The RISC-V toolchain situation for the CH32 series is quite chaotic. The following two options are recommended:
The official riscv-wch-elf bundled with MRS: Supports WCH's rv32imafcxw extended instruction set, but has incomplete C++ standard library support, making it incompatible with libraries like Eigen.- Upstream riscv32-unknown-elf: Does not support WCH's extended instruction set, but provides complete C++ standard library support. On Windows, that means using MSYS2, which can be a bit of a hassle.
For quick compilation, you can use the Docker image provided by this project.
CMake Configuration
An additional option needs to be configured: LIBXR_CH32_CONFIG_FILE, which specifies the path to the CH32 peripheral library configuration file, such as: ch32v30x_conf.h.
set(LIBXR_SYSTEM FreeRTOS)
set(LIBXR_DRIVER ch)
set(LIBXR_CH32_CONFIG_FILE "ch32v30x_conf.h")
add_subdirectory(libxr)
...
CH32 Driver Library
WCH’s official peripheral drivers have (but are not limited to) the following bugs:
- Multiple
extern "C"definitions, causing header include errors under C++. - USB peripheral source and header files exist but are not actually referenced.
- FreeRTOS
mstatus-related bits are set incorrectly, leading to abnormal task switching and priority handling. - Definitions for non-existent peripheral groups.
All of the above have been fixed in the sample project.
In addition, for LibXR’s time base to work, you must manually add the following code to the SysTick interrupt handler:
void SysTick_Handler( void )
{
extern void libxr_systick_handler(void);
libxr_systick_handler();
......
}
Flash Issues
- The flash write clock frequency must be less than 60 MHz.
- After an erase, if no write is performed, although the flash contents should be 0xFF, the actual value read back is a magic number (
0xE339u). - Many models include “bonus” flash whose speed is roughly two orders of magnitude slower than the normal flash.
- When using the extra flash, you need to add the
wch_riscv unfreezecommand to OpenOCD for programming to work properly.
Reference OpenOCD Commands
"openOCDLaunchCommands": [
"init",
"wch_riscv unfreeze"
],