安信可开发经验分享 | 在 ESP32-S/ESP-12K 模组上实现 JTAG调试,方便二次开发。

一、前言

当代码出现BUG怎么办,仅凭 printf 语句来定位错误有一定的局限性,本文将介绍如何搭建JTAG调试环境,进行单步调试、设置断点、查看堆栈和线程等调试。

1.2 准备工作

硬件准备:

  1. ESP-Prog
  2. 安信可ESP32-S模组/开发板,安信可ESP-12K(或者ESP-12H)模组/开发板
  3. 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 等等各种语言编写的程序,它提供如下功能:

  1. 下载或者启动程序
  2. 通过设定各种特定条件来停止程序
  3. 查看处理器的运行状态,包括通用寄存器的值,内存地址的值等
  4. 查看程序的状态,包括变量的值,函数的状态等
  5. 改变处理器的运行状态,包括通用寄存器的值,内存地址的值等
  6. 改变程序的状态,包括变量的值,函数的状态等

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常用调试指令

  1. stepnext 命令(可以简写成 sn)单步执行代码, 这两者之间的区别是执行 “step” 命令会进入调用的子程序内部,而执行 “next” 命令则会直接将子程序看成单个源码行,单步就能将其运行结束

在这里插入图片描述

  1. break M:在第M行设置断点,简写b

  2. continue:继续运行,简写c

  3. quit:退出GDB,简写q
    在这里插入图片描述

  4. set:设置变量的值

  5. print:打印值及地址,简写p

  6. finish:结束当前函数,返回到函数调用点

  7. frame:切换函数的栈帧,简写f

  8. backtrace:查看函数的调用的栈帧和层级关系,简写bt

  9. display:追踪查看具体变量值

  10. delete breakpoints num:删除第num个断点,简写d

  11. info:查看函数内部局部变量的数值,简写i

  12. frame:切换函数的栈帧,简写f

这里只描述如何快速搭建JTAG调试环境和最简单是使用例子,需要深入学习的同学请移步官方文档,建议多看几遍 几天

联系我们

官方官网:https://www.ai-thinker.com
开发DOCS:https://docs.ai-thinker.com
官方论坛:http://bbs.ai-thinker.com
技术支持:[email protected]

猜你喜欢

转载自blog.csdn.net/Boantong_/article/details/121520707