文章目录
一、前言
当代码出现BUG怎么办,仅凭 printf 语句来定位错误有一定的局限性,本文将介绍如何搭建JTAG调试环境,进行单步调试、设置断点、查看堆栈和线程等调试。
1.2 准备工作
硬件准备:
- ESP-Prog
- 安信可ESP32-S模组/开发板,安信可ESP-12K(或者ESP-12H)模组/开发板
- USB线
软件准备:
搭建好ESP-IDF开发环境,搭建教程见往期博文https://aithinker.blog.csdn.net/article/details/121565113
接线准备:
ESP32与ESP-Prog接线:
ESP32S2与ESP-Prog接线:
如果运行的是虚拟机,务必把ESP32/ESP32S2和ESP-Prog接入虚拟机
二、安装并运行OpenOCD
2.1 OpenOCD简介
OpenOCD是一个运行于PC上的开源调试软件,它可以控制很多JTAG硬件;我们可以将它理解为一种GDB服务程序。最初是由Dominic Rath同学还在大学期间发起的(2005年)项目。OpenOCD旨在提供针对嵌入式设备的调试、系统编程和边界扫描功能。OpenOCD的功能是在仿真器的辅助下完成的,仿真器是能够提供调试目标的电信号的小型硬件单元。仿真器是必须的,因为调试主机(运行OpenOCD的主机)通常不具备这种电信号的直接解析功能。
2.2 安装OpenOCD
ESP-IDF v4.0 以上版本运行install.sh安装脚本的时候已经默认安装了openocd
检查安装版本
openocd --version
终端会输出以下信息(实际版本号可能会更新):
Open On-Chip Debugger v0.10.0-esp32-20210902 (2021-09-02-09:38)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
检查 OPENOCD_SCRIPTS 环境变量的值,以确认 OpenOCD 配置文件的路径
进入ESP-IDF目录并运行. ./export.sh和echo $OPENOCD_SCRIPTS
cd esp-idf
. ./export.sh
echo $OPENOCD_SCRIPTS
echo $OPENOCD_SCRIPTS 打印我的 OpenOCD 路径
~/.espressif/tools/openocd-esp32/v0.10.0-esp32-20210902/openocd-esp32/share/openocd/scripts
openocd需要使用usb,需要把~/.espressif/tools/openocd-esp32/v0.10.0-esp32-20210902/openocd-esp32/share/openocd/contrib/contrib/60-openocd.rules (根据自己的实际路径修改)拷贝到 /etc/udev/rules.d ,这样openocd就有使用usb调试设备的权限了
cd ~/.espressif/tools/openocd-esp32/v0.10.0-esp32-20210902/openocd-esp32/share/openocd/contrib/contrib
sudo cp 60-openocd.rules /etc/udev/rules.d
运行openocd
进入需要调试的工程目录,以examples/get-started/blink为例
cd $IDF_PATH/examples/get-started/blink
下载需要调试的固件
idf.py flash monitor
运行idf.py openocd
idf.py openocd
运行成功如下图所示
三、安装并运行GBD
3.1 GBD简介
GDB(GNU Project Debugger),是 GNU 工具链中的调试软件。 GDB 是一款应用非常广泛的调试工具,能够用于调试 C、 C++、 Ada 等等各种语言编写的程序,它提供如下功能:
- 下载或者启动程序
- 通过设定各种特定条件来停止程序
- 查看处理器的运行状态,包括通用寄存器的值,内存地址的值等
- 查看程序的状态,包括变量的值,函数的状态等
- 改变处理器的运行状态,包括通用寄存器的值,内存地址的值等
- 改变程序的状态,包括变量的值,函数的状态等
GDB 可以用于在主机 PC 的 Linux 系统中调试运行的程序,同时也能用于调试嵌入式硬件,在嵌入式硬件的环境中,由于资源有限,一般的嵌入式目标硬件上无法直接构建 GDB 的调试环境(譬如显示屏和 Linux 系统等),这时可以通过 GDB + GdbServer 的方式进行远程 (remote) 调试,通常而言 GdbServer在目标硬件上运行,而 GDB 则在主机 PC 上运行。
3.2 运行GBD
安装python2、libpython2.7
sudo apt install python2
sudo apt install libpython2.7
打开一个新的终端会话并前往待调试的项目目录,比如:
cd esp-idf
. ./export.sh
cd examples/get-started/blink
当启动调试器时,通常需要提供几个配置参数和命令,为了避免每次都在命令行中逐行输入这些命令,您可以新建一个配置文件,并将其命名为 gdbinit:
target remote :3333
set remote hardware-watchpoint-limit 2
mon reset halt
flushregs
thb app_main
c
将此文件保存在当前目录中。
有关 gdbinit 文件内部的更多详细信息,请参阅调试器的启动命令的含义章节
启动GDB。启动前确保idf.py openocd正在运行
idf.py gdbtui
按回车键进入程序
到这里JTAG调试已经跑起来了。我一共开了三个终端,一个运行idf.py monitor查看串口日志,一个运行idf.py openocd,一个运行idf.py gdbtui,三个终端配合调试.
3.3 GDB常用调试指令
step
和next
命令(可以简写成s
和n
)单步执行代码, 这两者之间的区别是执行 “step” 命令会进入调用的子程序内部,而执行 “next” 命令则会直接将子程序看成单个源码行,单步就能将其运行结束
-
break M
:在第M行设置断点,简写b
-
continue
:继续运行,简写c
-
quit
:退出GDB,简写q
-
set
:设置变量的值 -
print
:打印值及地址,简写p
-
finish
:结束当前函数,返回到函数调用点 -
frame
:切换函数的栈帧,简写f
-
backtrace
:查看函数的调用的栈帧和层级关系,简写bt
-
display
:追踪查看具体变量值 -
delete breakpoints num
:删除第num个断点,简写d
-
info
:查看函数内部局部变量的数值,简写i
-
frame
:切换函数的栈帧,简写f
这里只描述如何快速搭建JTAG调试环境和最简单是使用例子,需要深入学习的同学请移步官方文档,建议多看几遍 几天
。
联系我们
官方官网:https://www.ai-thinker.com
开发DOCS:https://docs.ai-thinker.com
官方论坛:http://bbs.ai-thinker.com
技术支持:support@aithinker.com