对于第一个问题,这个报错log指出gdb源码中的gdb_init()访问了ch32v307所没有的寄存器。造成这个现象的原因有很多。1>.可能沁恒在ch32中没有按RISCV Spec中那样,定义所有的CSR。
2>.也可能是MRS提供的GDB是由其他RISCV厂商维护的,他们定义了一些自己独有的CSR,这种CSR肯定不会存在于ch32中。
RISCV太过自由了,可能将来也会导致RISCV的生态比较混乱。。。目前MRS以二进制形式提供toolchain,所以这个问题在他们开源之前,无从下手。
对于第二个问题,你需要对断点的实现方式有一定理解。调试断点的实现分成soft和hard两种。
1>.soft的实现机制很简单,GDB把你想要停下的地址上的那条指令替换成ebreak(riscv)即可。根据指令集不同,他可能是32位宽的ebreak,也可能是16位宽的c.ebreak。不过无论是哪一个,都要求GDB对这块存储具备字节编程能力。而我们知道,对FLASH编程,需要先将其擦除成FF。出于成本考虑,几乎不存在支持按字节擦除的FLASH。这意味着你想要设置断点的地址周围的数条指令也会被一起擦除。所以通常GDB会把flash中的代码段当作只读区域。对于FLASH代码段下断点,也会默认采用hard的方式实现。当然了,想要实现对FLASH下断点,也不是不可能的,只是需要对openocd的源码进行一些改动。据我所知乐鑫的ESP32做了这方面的工作。
2>.hard方式实现的断点,你可以从RISCV-Debug Spec中了解到(https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf)Page.88。这种断点的实现依赖于芯片内部DebugModule所支持的Triggers。Triggers的数量是有限的,所以hard断点的数量也是有限的,我没有深入阅读过沁恒的相关文档,不确定他们支持多少个Triggers。通常STM32支持最多6个Triggers。
3>.如果你只是想忽略这个log,你可以在wch-riscv.cfg中增加一句 gdb_breakpoint_override hard。除此之外,你也可以修改lds链接文件,把.text段链接到RAM中。
最后的最后,我还是要好好冲一下MRS和WCH。一边享受着openocd的好处,一边不把自己关于wlink的改动提交上游分支。甚至连开源都不开,这样子怎么可能在爱好者当中推起来。芯来也是,闭源的很,而且那颗用了所谓芯来内核的GD32VF103能用openocd读出台湾晶芯的IDCODE ,各位自由发挥想象。 😆