最近在把玩一块Risc-V的开发板,使用开发板调试时,需要用到专门的下载器和OpenOCD进行调试。
为了连接这个板子,费了九牛二虎之力。
这里简单记录一下自己的折腾经过吧。
0x00 环境准备
0x0001 调试背景
系统:Virtual Box + Ubuntu 20.04.5 LTS
调试器:蜂鸟调试器(实际上只要兼容的调试器都可以)
这里假设基本的Lib都已经安装了,如果没有安装,对应apt install
下就好,这里就不多说了。
0x0002 环境配置
首先下载支持Risc-V,最新版本的OpenOCD,直接去官网下载即可。
链接:芯来工具链_芯来科技 - 专业RISC-V处理器IP及解决方案公司
由于我们要在Linux系统上跑,因此下载Linux版本。如果需要Win下运行,则下载Win版本就好了。
一般来说,官网的OpenOCD会比较新,可能会有更多的器件设备支持。但是也不排除部分厂商会对OpenOCD进行定制,具体采用哪个版本根据实际情况决定。
安装OpenOCD的同时,同步在虚拟机上解压安装交叉编译工具链,.bashrc
配置PATH
变量然后source
一下,这个就不用我多说了吧。
0x0003 硬件连接
把仿真器连接到电脑,另一端连接到板子的JTAG口。
虚拟机上做好USB端口映射,让虚拟机能够通过USB访问仿真器:
如果还有问题,大概率是由于没有打开USB支持导致的。
关闭虚拟机,在USB设置上选择如下操作,允许USB3.0/2.0的支持后重新映射USB即可:
最后sudo lsusb
,不出意外可以看到仿真器的连接情况:
这里最好记住一下仿真器设备的PID和VID,后续配置仿真器的时候会用到。例如这里是
0403:6010
那么硬件连接基本完成。
0x01 OpenOCD配置
OpenOCD实际上只是一个调试工具,这个工具通过什么接口连接开发板,连接时的一些参数(通信速率、操作配置等)等信息,需要通过配置告诉OpenOCD。
接下来我们就来简单讲解一下。
0x0101 OpenOCD的配置逻辑
首先先来讲一下OpenOCD的配置逻辑:
一般来说,OpenOCD的操作都是通过命令形式执行的,类似下面这样:
openocd.exe --command "adapter speed 9600" --command "adapter driver cmsis-dap" --command "transport select jtag" --command "jtag newtap riscv cpu -irlen 5" --command "target create riscv.cpu riscv -chain-position riscv.cpu" --command "riscv.cpu configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1"
上述命令中,用多个Command参数设置了通信速率、调试接口和目标等信息。
实际上,
—command
命令也可以用-c
来进行缩写。
当然,我们也可以把这些命令用Script的方式保存,并使用openocd -f [脚本1] -f [脚本2] ...
的方式在执行时指定这些脚本,OpenOCD会自动按照顺序执行这些脚本。
更方便的方式是将这些脚本写成OpenOCD的配置文件openocd.cfg
,并在该目录下直接执行openocd即可。
0x0102 配置文件讲解
用个例子简单讲解一下OpenOCD的常用命令。
这些命令可以在https://openocd.org/doc-release/html/Command-and-Driver-Index.html看到。
# 配置调试器的速度和接口
adapter speed 1000
adapter driver ftdi
# 配置调试器的USB PID和VID,这个可以在lsusb里看到
ftdi_vid_pid 0x0403 0x6010
ftdi_oscan1_mode off
# 配置命令
transport select jtag
ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
ftdi_layout_signal TCK -data 0x0001
ftdi_layout_signal TDI -data 0x0002
ftdi_layout_signal TDO -input 0x0004
ftdi_layout_signal TMS -data 0x0008
ftdi_layout_signal JTAG_SEL -data 0x0100 -oe 0x0100
# 配置芯片和操作,主要是新增target
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
# 后续省略...
我们可以看到,这里的代码是对调试器的接口、连接目标、寄存器和操作进行了配置。
不同的芯片、平台和调试器的配置方法不一样,需要结合实际情况修改上述命令。
例如,使用cmsis-dap
的JTAG接口,就需要对应配置adapter driver
和transport select
等命令。
如果不出意外的话,直接在配置文件目录下执行openocd连接就好了。
0x02 GDB连接OpenOCD
上述命令成功执行的情况下(且没有其他Error
级别的输出)会有如下关键Log输出:
Info : starting gdb server for riscv.cpu on 3333
Info : Listening on port 3333 for gdb connections
这时候说明调试器和板子已经建立了通信,并且启动了gdb server监听3333端口。
这时候,另起一个终端,执行交叉编译工具中的gdb工具,会进入gdb环境。
使用命令target remotr localhost:3333
连接本机的端口,如果没有报错,就可以进行调试、下载等工作。
0x03 遇到问题和解决方法
接下来说说我在配置过程中遇到的一些问题。
出错的时候,要注意观察输出的Log,一般Error里都包含了错误的信息和解决方法。
0x0301 all ones错误
错误信息如下图所示:
这种情况一般是电脑到调试器的通路是正常的,但是调试器到板卡的通路有异常。
解决方法很简单,正如错误Log中显示的,这种情况是调试器连接不到目标板卡。一般是检查JTAG的接口配置、时序、目标板是否上电、JTAG到目标板连接是否正常等。
我遇到这个问题的时候排查下来发现是线接反了,根据电路图重新连接之后就没有这个错误了。
0x0302 Unknown flash device
错误信息如图:
这种情况是仿真器连接正常,但是使用OpenOCD连接仿真器操作Flash的时候,OpenOCD不兼容这个Flash,因此无法进一步操作。
解决方法:换OpenOCD。我这边测试的情况是从芯片厂商提供的版本更换到了最新版OpenOCD后,能正常识别到Flash并进行烧录。
但是也可能会有反例,例如最新版OpenOCD没有支持芯片平台的Flash导致报错,这种情况下如果芯片平台自己做了驱动,这时候就要从最新版OpenOCD更换到芯片平台提供的调试工具了。
如果换OpenOCD也不行,那就要考虑是不是要自己下载源码,修改+编译OpenOCD了。
0x04 总结
简单总结一下。
OpenOCD是一个开源的调试工具,可以用这个工具通过不同的调试器对嵌入式平台进行调试。
但是针对不同的芯片平台和调试器,需要使用不同的配置。这个需要结合仿真器和目标芯片平台的信息来调整。
后续如果在调试过程中还遇到什么其他的问题,也会继续整理更新。