在 MacOS 上编译 MounRiver Studio 的 OpenOCD

陪她去流浪 桃子 阅读次数:10177

不出意外的话,在 MounRiver 官方网站 上下载的为 MacOS 准备的 RISC-V 工具链的 OpenOCD 并不能使用,虽然你可能已经按照官方的 README brew 安装了 libusb。但是仍然会出现类似找不到 libusb 不可使用的问题。后来我尝试安装了 OpenOCD 官方 xPack OpenOCD,仍然不可用。然后我就意识到,这大概率又是国产厂商魔改后的版本,并且也没有跟随主线开发,当然,也没开放源代码。后来我发帖子问了沁恒(WCH)官方得知,是可以向 MounRiver Studio 发邮件索要源代码的。

虚拟机方案

笑死,你都不敢想像,在拿到源代码之前,我这两天为了搞定在 MacOS 上使用 OpenOCD 的问题,竟然用 UTM 安装了一个仅 60MB ISO 大小 Alpine (amd64) 虚拟机,通过把主机的 USB 设备挂载到虚拟机里面,然后通过 ssh 远程执行命令来完成程序的煤录与调试,工作非常稳定,并且成本也很低。具体可以参考这个 Makefile 的实现,这种临时方案我就不再花言辞过多描述了。可以使用 glibc Alpine 仍深得我爱。当然,我深爱一切小而美的事物(微信除外)。

编译 MRS 官方的 OpenOCD “魔改版”

在官方提供的 OpenOCD 目录下有一个 readme,里面提到:如果有需要,可以发送邮箱以索取源代码。我就发了,官方很快回复,并且附件中提供了源代码:riscv-openocd.zip,我不知道官方为什么没有开源,但是又允许轻易发送邮件得到。可能是不想维护开源社区?不猜测了,编译一下。

官方也没有提供官方预编译的二进制包的编译参数,几经折腾,终于编译好了:

1
./configure CPPFLAGS="-D__linux__" --enable-wlinke --enable-ch347  --disable-werror --prefix=/Users/tao/code/toolchains/openocd

看着挺奇怪,为了编译通过,我竟然定义了 __linux__,也不知道为何要 --enable-ch347,反正就是 wlinke 依赖了它。

编译完成的目录树结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
openocd → pwd
/Users/tao/code/toolchains/openocd
openocd → tree -L 2
.
├── README.md
├── bin
│   └── openocd
├── etc
│   └── wch-riscv.cfg
├── share
│   ├── info
│   ├── man
│   └── openocd
└── src
    ├── riscv-openocd
    └── riscv-openocd.zip

然后就有了修改后的 Makefile(节选):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.PHONY: flash
flash: kill
	cd "$(OPENOCD_DIR)" && ./bin/openocd -f "$(WCH_CFG)" -c init -c halt -c "flash write_image $(TMP)/$(HEX)" -c exit

.PHONY: reset
reset: kill
	cd "$(OPENOCD_DIR)" && ./bin/openocd -f "$(WCH_CFG)" -c init -c halt -c wlink_reset_resume -c exit

.PHONY: debug
debug: kill
	cd "$(OPENOCD_DIR)" && ./bin/openocd -f "$(WCH_CFG)"

末了

零售价格仅为 0.45 元的封装为 8 只脚(SOP-8) 32-bit RISC-V 单片机 CH32V003J4M6(定语加得有足够多吧?),只用了单线调试接口(即 SWDIO,包含烧录程序在内),是的,没有使用类似使用串口的方式,虽然多占用了一个 GPIO,但是胜在可以用 gdb 在线调试,还是非常爽的。代价是:这个 GPIO 默认是跟串口(USART0)复用的,所以如果一不小心把这个口复用成串口发送数据来输出调试信息了的话,芯片大概率是很难再用 SWDIO 来烧代码的,类似“成砖🧱”。

所以官方的 W-LinkE 工具有一个“重新上电并擦除整个 Flash”的组合命令。之所以要组合,是因为一定要快。 CH32V003 上电复位时会短暂地进入 SWD 模式(大概有几十个毫秒),如果有收到 SWD 指令,则 SWDIO 还是 SWDIO。否则就是串口功能了。所以即便成“砖”,也是有办法恢复了。

问题就在于,官方虽然宣传 W-LinkE 是兼容 OpenOCD 的,可是询问官方后得知,这个组合命令没开放、不给使用。我郁闷,然后我尝试在 OpenOCD 的源代码里面看看能不能发现什么,倒是有挺多跟 5V、3V3 啊之类的命令,但是无一例外,一执行就 crash,没有好结果。

成天搞的,什么玩意儿。还能怎么办啊,写个死循环用 OpenOCD 不停地烧录,然后另一只手不停复位啊。我能怎么办,我也很无奈啊🙄。

今天可是圣诞节啊,啊你怎么又在写代码?