调试框架图
- PC色块代表运行在PC环境。
- Software色块代表运行于PC之上的软件协议。
- HardWare色块代表硬件电路板以及JTAG适配器。
- 绿色色块代表各模块之间的通讯协议。
openocd简介
开放片上调试器(OpenOCD)旨在为嵌入式目标设备提供调试、系统内编程和边界扫描测试。它在调试适配器的帮助下完成了这一点,调试适配器是一个小型硬件模块,帮助为被调试的目标提供正确的电信号。这些都是必需的,因为调试主机(运行OpenOCD的主机)通常不支持这样的信号,或者不支持连接到目标所需的连接器。这种调试适配器支持一个或多个传输协议,每个传输协议都涉及不同的电信号(并在该信令之上使用不同的消息传递协议)。调试适配器有很多类型,但它们的名称几乎没有一致性。(在产品命名上也有差异。)这些适配器有时被打包成离散的加密狗,通常被称为硬件接口狗。一些开发板也直接集成了它们,这可能会让开发板通过USB直接连接到调试主机(有时也可以通过USB为其供电)。 引用自《openocd.pdf》-“ what is openocd”
openocd的安装
分为linux版本和windows版本的安装,本章介绍windows版本的安装
- 安装包下载
openocd windows版下载链接
- 下载解压完成后有以下三个文件夹
bin:存放的是openocd.exe可执行文件,可以通过power shell命令行启动;
drivers:存放了各种调试Adapter的驱动
share:存放里已经写好的针对各种适配器以及各种芯片的配置文件,主要存放在scripts文件夹下。 - 这里重点介绍几个常用的配置文件夹
interface:存放针对各种调试适配器的配置文件,如Jlink、ST-Link、JTAG等等。
target:存放针对调试目标芯片的配置文件,如stm32、zynq-7000、xilinx_zynqmp等。
board:存放针对各种开发板的配置文件。 - 设置环境变量
为了方便启动openocd,可以将openocd.exe所在的bin目录添加至环境变量,具体windows的环境变量设置可以网上搜索,这里不展开。 - 启动openocd服务
在根目录下打开power shell输入以下指令获取openocd的使用方法:openocd.exe -h
-f:指定配置文件
-c:运行命令,注意命令需要包含在双引号“”中,多条命令可以通过分号;隔开。openocd.exe -f .\share\openocd\scripts\interface\ftdi\digilent_jtag_smt2.cfg -f .\share\openocd\scripts\target\xilinx_zynqmp.cfg
openocd.exe -f .\share\openocd\scripts\interface\ftdi\digilent_jtag_smt2.cfg -f .\share\openocd\scripts\target\xilinx_zynqmp.cfg -c "adapter speed 1000;transport select jtag"
openocd配置的高级使用方法
openocd的内部集成了Jimtcl(简化版TCL)的解释器,所以配置脚本都是使用tcl写的,上述在命令行中的参数过长,我们可以创建一个单独的脚本,把openocd的命令包含在tcl脚本里,启动时指定创建的脚本即可,这里创建一个uscale_a53.cfg的脚本,如下图:
#specify jtag debugger driver config
source [find interface/ftdi/digilent_jtag_smt2.cfg]
#specify target config
source [find target/xilinx_zynqmp.cfg]
#specify jtag debugger speed
adapter speed 1000
#specify debug interface, ex: jtag swd jlink
transport select jtag
openocd.exe -f .\uscale_a53.cfg
- 运行结果如下图:
常见错误解决方法
-
JTAG适配器驱动未安装导致识别不到适配器。
Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED Error: unable to open ftdi device with description '*', serial '*' at bus location '*'
解决方法:
-
进入driver目录运行UsbDriverTool.exe如下图
选择要安装的驱动,根据适配器不同选择不同的驱动,笔者这里使用的是Digilent Jtag
安装完成后如下图:
-
JTAG-DP STICK ERROR导致GDB Client无法连接A53,无法进行调试
For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : Hardware thread awareness created core_up Info : Listening on port 6666 for tcl connections Info : Listening on port 5555 for telnet connections Info : clock speed 1000 kHz Info : TAP uscale.tap does not have valid IDCODE (idcode=0x28e22126) Info : JTAG tap: uscale.ps tap/device found: 0x14711093 (mfg: 0x049 (Xilinx), part: 0x4711, ver: 0x1) Info : JTAG tap: uscale.tap tap/device found: 0x5ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x5) Info : JTAG tap: uscale.ps tap/device found: 0x14711093 (mfg: 0x049 (Xilinx), part: 0x4711, ver: 0x1) Error: JTAG-DP STICKY ERROR Warn : target uscale.a53.0 examination failed Info : gdb port disabled Info : starting gdb server for uscale.a53.0 on 3333 Info : Listening on port 3333 for gdb connections
解决方法:
参考《arm_debug_interface_v5_2_architecture_specification.pdf》B1.2了解
JTAG-DP STICKY ERROR的描述。
直接使用以下配置脚本:
uscale_a53.cfg
使用上述脚本启动openocd以后结果如下
使用GDB调试A53步骤
-
将需要调试的fsbl.elf文件和应用程序复制到同一个文件夹下
由于芯片上电后,CSU只初始化了OCM(参考ug1085 v2.3.2 Page221),此时DDR等其他外设并未初始化,如果应用程序的连接地址在OCM的地址空间中,则可以直接下载调试应用程序,如果应用程序链接地址位于DDR中,则需要先运行FSBL(默认运行于OCM中)初始化DDR,后下载调试应用程序,否则load下载不成功。
fsbl.elf以及应用程序在编译过程中要增加-g的编译选项,本文使用的是vitis工具编译好的fsbl以及应用程序,vitis默认已经开启了-g3选项,编译出来的程序已经包含了调试信息。 -
在该文件下启动GDB Client命令行
aarch64-none-elf-gdb
-
读取fsbl程序的符号表
file fsbl.elf
也可以在启动GDB Client是直接运行 aarch64-none-elf-gdb fsbl.elf,则省略此步骤
-
GDB Client连接openocd服务
target extended-remote 192.168.155.119:3333
其中192.168.155.119为运行openocd服务的PC,如果openocd服务与gdb client运行于同一台PC上,则通过命令target remote localhost:3333连接,端口号3333可以通过配置文件指定,具体参考openocd官方命令手册的gdb_port命令。
-
下载fsbl.elf至芯片
load fsbl.elf
-
在XFsbl_StartApp处打断点
b XFsbl_StartApp
GDB断点相关的命令:
info breakpoints: 查看所有的断点
delete 断点号: 删除指定的断点
delete breakpoints: 删除所有的断点
b 函数名/地址: 在指定函数或者地址处增加断点 -
输入c或者continue运行程序至断点处
-
Ctrl+C暂停运行
此时程序进入XFsbl_Loop循环,需要通过Ctrl+C暂停
-
查看fsbl中当前的断点并且删除,如果不删除可能无法正常跳转到应用程序。
-
下载应用程序
load lwip_echo_server.elf
-
读取应用程序的符号表
file lwip_echo_server.elf
-
在main函数处打断点
b main
-
输入c或者continue运行程序至断点处
-
通过常用的GDB命令开始调试应用程序
参考资料
《ug1085-zynq-ultrascale-trm.pdf》V2.3.1
《openocd.pdf》
《IHI0031G_debug_interface_v5_2_architecture_specification.pdf》
Xilinx官方wiki Debugging+Guest+Applications+with+QEMU+and+GDB
Xilinx官方wiki Creating+FSBL+PMUFW+from+XSCT+2018.3+for+ZCU111+and+boot+over+JTAG