bsp, hil: flash WCH boards with the unified OpenOCD fork (#3791)

bsp, hil: flash with the unified OpenOCD fork

https://github.com/hathach/openocd (branch tinyusb) is mainline plus every
config these boards need: RPi RP2350, ADI max32/max78, the MounRiver WCH
configs, and the wlinke adapter on mainline's riscv target. It is a superset
of the vendor forks, so one 'openocd' covers all boards; -DOPENOCD=/OPENOCD=
still select another, msdk's when MAXIM_PATH is set.

Drops family_flash_openocd_wch and the OPENOCD_WCH pair, dedups
family_flash_openocd_adi, aligns ch583's work area, and points hil at the
flasher's own config instead of generating one per probe.

Verified: HIL green on all four WCH boards and max32666fthr.
This commit is contained in:
Ha Thach
2026-07-28 12:50:28 +07:00
committed by GitHub
parent 72f95d7d61
commit 1d915b6b59
15 changed files with 47 additions and 90 deletions

View File

@ -4,7 +4,7 @@
<debugger kind="GDB" isBundled="true" />
<env />
</debugger>
<gdbserver dir="$CMakeProjectDir$" exe="$USER_HOME$/app/riscv-openocd-wch/src/openocd" args="-f hw/bsp/ch32v20x/wch-riscv.cfg">
<gdbserver dir="$CMakeProjectDir$" exe="openocd" args="-f target/wch-riscv.cfg">
<env />
</gdbserver>
<console enabled="true" port="4444" />

View File

@ -93,6 +93,6 @@ function(family_configure_example TARGET RTOS)
# Flashing
family_add_bin_hex(${TARGET})
family_flash_openocd_wch(${TARGET})
family_flash_openocd(${TARGET})
#family_flash_uf2(${TARGET} ${UF2_FAMILY_ID})
endfunction()

View File

@ -49,5 +49,5 @@ INC += \
FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V
OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
OPENOCD_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
flash: flash-openocd-wch

View File

@ -125,7 +125,7 @@ function(family_configure_example TARGET RTOS)
# Flashing
family_add_bin_hex(${TARGET})
family_flash_openocd_wch(${TARGET})
family_flash_openocd(${TARGET})
family_flash_wlink_rs(${TARGET})
#family_flash_uf2(${TARGET} ${UF2_FAMILY_ID})
endfunction()

View File

@ -63,6 +63,6 @@ INC += \
FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V
OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
OPENOCD_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
flash: flash-wlink-rs
#flash: flash-openocd-wch

View File

@ -115,6 +115,6 @@ function(family_configure_example TARGET RTOS)
# Flashing
family_add_bin_hex(${TARGET})
family_flash_openocd_wch(${TARGET})
family_flash_openocd(${TARGET})
family_flash_wlink_rs(${TARGET})
endfunction()

View File

@ -62,5 +62,5 @@ LD_FILE ?= $(FAMILY_PATH)/linker/ch32v30x.ld
# For freeRTOS port source
FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V
OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
OPENOCD_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
flash: flash-openocd-wch

View File

@ -104,5 +104,5 @@ function(family_configure_example TARGET RTOS)
# Flashing
family_add_bin_hex(${TARGET})
family_flash_openocd_wch(${TARGET})
family_flash_openocd(${TARGET})
endfunction()

View File

@ -52,7 +52,7 @@ INC += \
LD_FILE ?= $(FAMILY_PATH)/linker/ch582.ld
OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
OPENOCD_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
flash: flash-openocd-wch
# For freeRTOS port source

View File

@ -9,7 +9,7 @@ sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME
$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 0x8000 -work-area-backup 1
$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0

View File

@ -130,20 +130,18 @@ flash-pyocd: $(BUILD)/$(PROJECT).hex
#pyocd reset -t $(PYOCD_TARGET)
# --------------- openocd -----------------
# OPENOCD can name another build, e.g. one of the vendor forks, though
# https://github.com/hathach/openocd branch tinyusb covers every board here
OPENOCD ?= openocd
OPENOCD_OPTION ?=
flash-openocd: $(BUILD)/$(PROJECT).elf
openocd $(OPENOCD_OPTION) -c "program $< verify reset exit"
$(OPENOCD) $(OPENOCD_OPTION) -c "program $< verify reset exit"
# --------------- openocd-wch -----------------
# wch-linke is not supported yet in official openOCD yet. We need to either use
# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or
# 2. compiled from https://github.com/hathach/riscv-openocd-wch or
# https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz
# with ./configure --disable-werror --enable-wlinke --enable-ch347=no
OPENOCD_WCH ?= /home/${USER}/app/riscv-openocd-wch/src/openocd
OPENOCD_WCH_OPTION ?=
# WCH parts need an openocd built with the wlinke adapter. The image is written
# without verify: WCH code flash is not readable back over the debug bus.
flash-openocd-wch: $(BUILD)/$(PROJECT).elf
$(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit
$(OPENOCD) $(OPENOCD_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit
# --------------- wlink-rs -----------------
# flash with https://github.com/ch32-rs/wlink

View File

@ -688,7 +688,9 @@ function(family_flash_stflash TARGET)
endfunction()
# Add flash openocd target
# Add flash openocd target.
# The default 'openocd' should be https://github.com/hathach/openocd (branch tinyusb): which is mainline plus
# every config the rig needs (RP2350, MAX32/MAX78, WCH) and a drop-in superset of the vendor (downstream) forks
function(family_flash_openocd TARGET)
if (NOT DEFINED OPENOCD)
set(OPENOCD openocd)
@ -715,38 +717,20 @@ function(family_flash_openocd TARGET)
#set_property(TARGET ${TARGET}-openocd PROPERTY FOLDER ${TARGET}-group)
endfunction()
# Add flash openocd-wch target
# compiled from https://github.com/hathach/riscv-openocd-wch or https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz
function(family_flash_openocd_wch TARGET)
if (NOT DEFINED OPENOCD)
set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd)
# Add flash openocd adi (Analog Devices) target using the openocd included
# with msdk (MAXIM_PATH), otherwise the default openocd
function(family_flash_openocd_adi TARGET)
# use openocd from msdk if MAXIM_PATH is set, as cmake variable or in the
# environment. Normalize the latter since msdk can be Windows (MinGW) or Linux
if (NOT DEFINED MAXIM_PATH AND DEFINED ENV{MAXIM_PATH})
file(TO_CMAKE_PATH "$ENV{MAXIM_PATH}" MAXIM_PATH)
endif ()
family_flash_openocd(${TARGET})
endfunction()
# Add flash openocd adi (Analog Devices) target
# included with msdk or compiled from release branch of https://github.com/analogdevicesinc/openocd
function(family_flash_openocd_adi TARGET)
if (DEFINED MAXIM_PATH)
# use openocd from msdk with MAXIM_PATH cmake variable first if the user specified it
set(OPENOCD ${MAXIM_PATH}/Tools/OpenOCD/openocd)
set(OPENOCD_OPTION2 "-s ${MAXIM_PATH}/Tools/OpenOCD/scripts")
elseif (DEFINED ENV{MAXIM_PATH})
# use openocd from msdk with MAXIM_PATH environment variable. Normalize
# since msdk can be Windows (MinGW) or Linux
file(TO_CMAKE_PATH "$ENV{MAXIM_PATH}" MAXIM_PATH_NORM)
set(OPENOCD ${MAXIM_PATH_NORM}/Tools/OpenOCD/openocd)
set(OPENOCD_OPTION2 "-s ${MAXIM_PATH_NORM}/Tools/OpenOCD/scripts")
else()
# compiled from source
if (NOT DEFINED OPENOCD_ADI_PATH)
set(OPENOCD_ADI_PATH $ENV{HOME}/app/openocd_adi)
if (MAXIM_PATH)
if (NOT DEFINED OPENOCD)
set(OPENOCD ${MAXIM_PATH}/Tools/OpenOCD/openocd)
endif ()
set(OPENOCD ${OPENOCD_ADI_PATH}/src/openocd)
set(OPENOCD_OPTION2 "-s ${OPENOCD_ADI_PATH}/tcl")
set(OPENOCD_OPTION2 "-s ${MAXIM_PATH}/Tools/OpenOCD/scripts")
endif ()
family_flash_openocd(${TARGET})

View File

@ -28,6 +28,8 @@ elseif (PICO_PLATFORM STREQUAL "rp2350-arm-s" OR PICO_PLATFORM STREQUAL "rp2350"
set(OPENOCD_TARGET rp2350)
elseif (PICO_PLATFORM STREQUAL "rp2350-riscv")
set(JLINK_DEVICE rp2350_riscv_0)
# rp2350-riscv.cfg needs the raspberrypi/openocd fork: mainline's riscv
# target does not take the -dap/-ap-num the config uses
set(OPENOCD_TARGET rp2350-riscv)
endif()

View File

@ -24,10 +24,11 @@
# Host setup (required: a missing tool fails its test rather than skipping it):
# - System packages: sudo apt install mtools libmtp9 alsa-utils iperf
# mtools - read_disk_file (device/cdc_msc, device/msc_dual_lun)
# libmtp9 - pymtp ctypes load (device/mtp); Debian 13 uses libmtp9t64
# alsa-utils - arecord (device/audio_test_freertos)
# iperf - throughput tests (device/net_lwip_*)
# mtools read_disk_file (device/cdc_msc, device/msc_dual_lun)
# libmtp9 pymtp ctypes load (device/mtp); Debian 13 uses libmtp9t64
# alsa-utils arecord (device/audio_test_freertos)
# iperf throughput tests (device/net_lwip_*)
# openocd unified openocd from https://github.com/hathach/openocd (branch tinyusb) for wch, rp2040/rp2350, analog max32
# - device/usbtest: usbtest kernel module + testusb binary (kernel tools/usb/testusb.c) on PATH,
# plus sudo for modprobe / sysfs writes
# - Python packages: pip install -r requirements.txt
@ -377,25 +378,6 @@ def cmd_stdout_text(out: Any) -> str:
return out.decode('utf-8', errors='ignore')
return str(out)
WCH_RISCV_CONTENT = """
adapter driver wlinke
adapter speed 6000
transport select sdi
wlink_set_address 0x00000000
set _CHIPNAME wch_riscv
sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME
$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0
echo "Ready for Remote Connections"
"""
MSC_README_TXT = \
b"This is tinyusb's MassStorage Class demo.\r\n\r\n\
@ -662,24 +644,15 @@ def reset_openocd(board):
def flash_openocd_wch(board, firmware):
flasher = board['flasher']
f_wch = f"wch-riscv_{board['uid']}.cfg"
if not os.path.exists(f_wch):
with open(f_wch, 'w') as file:
file.write(WCH_RISCV_CONTENT)
ret = run_cmd(f'openocd_wch -c "adapter serial {flasher["uid"]}" -f {f_wch} '
f'-c "program {firmware}.elf reset exit"')
ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "telnet_port disabled" '
f'-c "adapter serial {flasher["uid"]}" {flasher.get("args", "")} -c "program {firmware}.elf reset exit"')
return ret
def reset_openocd_wch(board):
flasher = board['flasher']
f_wch = f"wch-riscv_{board['uid']}.cfg"
if not os.path.exists(f_wch):
with open(f_wch, 'w') as file:
file.write(WCH_RISCV_CONTENT)
ret = run_cmd(f'openocd_wch -c "adapter serial {flasher["uid"]}" -f {f_wch} -c "program reset exit"')
ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "telnet_port disabled" '
f'-c "adapter serial {flasher["uid"]}" {flasher.get("args", "")} -c "init; reset run; exit"')
return ret

View File

@ -147,7 +147,7 @@
"dual": false
},
"flasher": {
"name": "openocd_adi",
"name": "openocd",
"uid": "E6614C311B597D32",
"args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg"
}
@ -465,7 +465,7 @@
"flasher": {
"name": "openocd_wch",
"uid": "EBCA8F0670AF",
"args": ""
"args": "-f target/wch-riscv.cfg"
}
},
{
@ -480,7 +480,7 @@
"flasher": {
"name": "openocd_wch",
"uid": "BC4954081051",
"args": ""
"args": "-f target/wch-riscv.cfg"
}
},
{
@ -499,7 +499,7 @@
"flasher": {
"name": "openocd_wch",
"uid": "BC5DA47360D0",
"args": ""
"args": "-f target/wch-riscv.cfg"
}
},
{
@ -514,7 +514,7 @@
"flasher": {
"name": "openocd_wch",
"uid": "7FD88F0604B5",
"args": ""
"args": "-f target/wch-riscv.cfg"
}
},
{