ESP32 JTAG 调试

news/2024/9/22 3:29:13 标签: 单片机

前言

  1. 个人邮箱:zhangyixu02@gmail.com
  2. 本人使用的是 Ubuntu 环境,采用 GDB 方式进行调试。
  3. 对于新手,我个人还是建议参考ESP32S3学习笔记(0)—— Vscode IDF环境搭建及OpenOCD调试介绍进行图形化的方式调试。
  4. 如果是希望在 Windows 环境下进行 GDB 调试,可以参考 Windows 环境下,使用 ESP32-S3 USB 接口进行 JTAG 调试的流程。

GDB 介绍

两种调试方式

  1. ESP32 提供了两种调试方式,一种是利用串口进行日志打印。这种方式是常用的,我们可以根据日志信息知道程序的运行信息。
  2. 但是在一些特殊场景,例如我需要让程序在某个时刻停下来进行调试,日志打印的方式就并不那么好用了。我们此时就可以使用 JTAG 调试的方式进行。

在这里插入图片描述

GDB 和 Openocd 介绍

  1. 电脑端,我们需要先运行 Openocd 充当调试代理用于与目标硬件进行直接通讯,他提供一个 GDB 服务器接口(通常在TCP端口 :3333 上),GDB 可以通过该接口与 OpenOCD 通信。 GDB 会向 OpenOCD 发送调试命令,例如设置断点、查看寄存器、单步执行等。当 OpenOCD 接收到来自 GDB 的命令后,负责将这些命令转换成特定的硬件指令,并执行到目标设备上
  2. GDB 是一个高层的调试器,用户通过它来编写和管理调试会话。GDB本身不直接与硬件通信,它通过GDB服务器(如OpenOCD提供的)与设备进行交互。
  3. 如下为 电脑端 <—> 调试器 <—> ESP32C3 的方式进行调试。调试器为 FT2232/FT232 芯片。

在这里插入图片描述

  1. 这种外置调试器的方法相对麻烦,还需要自行准备调试芯片,后面乐鑫将调试器集成到了芯片内部。

在这里插入图片描述

  1. 我们可以通过乐鑫官方选型网站得知哪些芯片内部集成了 JTAG 调试接口。

在这里插入图片描述

  1. 如果当前使用的芯片内部没有 JTAG 调试接口,我们可以购买 ESP-Prog 进行调试。

环境准备

打开 Openocd

  1. 通过上面的内容我们知道,要进行 GDB 调试 ESP32-S3 的话,需要先打开 Openocd 提供一个接口。我们可以输入如下命令进行开启 Openocd。
openocd -f board/esp32s3-builtin.cfg
  1. 这个 cfg 文件在如下目录中,我们可以在该目录中选择合适的文件打开 Openocd。

注:随着版本更新,你可能并不是 v0.12.0-esp32-20230921。

~/.espressif/tools/openocd-esp32/v0.12.0-esp32-20230921/openocd-esp32/share/openocd/scripts/board
  1. 这个时候肯定就会有人要说了,我怎么知道应该选择哪个 cfg 文件呢?
  • 如果是内部集成了 JTAG 接口,一般选择 builtin 名称的 cfg 文件。
  • 如果是使用的 ESP-Prog 调试器,那么就选择 bridge 名称的 cfg 文件。
  • 如果你发现上述做法都不对,那就找到对应的芯片前缀名,然后一个一个的试吧。(哭笑)
  1. 在 Ubuntu 环境中,你打开 Openocd 发现如下报错,那么说明当前用户没有足够的权限访问 USB 设备
Error: libusb_open() failed with LIBUSB_ERROR_ACCESS
Error: esp_usb_jtag: could not find or open device!
  1. 此时你需要创建一个 udev 规则文件添加规则。
sudo vim /etc/udev/rules.d/99-openocd.rules
  1. 添加如下内容。
SUBSYSTEM=="usb", ATTR{idVendor}=="303a", ATTR{idProduct}=="1001", MODE="0666"
  1. 重新加载 udev 规则。
sudo udevadm control --reload-rules
sudo udevadm trigger

进入 GDB 调试

  1. 我们需要在项目根目录中创建 gdbinit 文件,并且在该文件中加入如下内容。

tui enable 命令能够在终端中增加一个 UI 界面方便我们知道当前调试的位置,如果觉得这个 UI 界面看的不舒服,可以将这一行给删除

# 告诉 GDB 连接到运行在本地(即当前计算机)上的 OpenOCD 服务,监听端口 3333
target remote :3333
# 设置硬件观察点限制
set remote hardware-watchpoint-limit 2
# 重置并停止目标设备
mon reset halt
# 刷新寄存器状态
flushregs
# 在 app_main 函数处设置临时断点
thb app_main
# 继续执行程序
c
# 使能 UI 界面
tui enable
  1. 此时我们需要再打开一个终端,输入如下命令即可进入 GDB 调试界面。

注:当前 elf 文件应该是你烧录到芯片时,生成的 elf 文件! 调试过程中,工程代码建议不要修改。

xtensa-esp32s3-elf-gdb -x gdbinit build/gatt_client_demo.elf
  1. 不同的芯片/架构使用的 GDB 调试器不同,具体参考如下:
架构/芯片命令
Xtensa ESP32xtensa-esp32-elf-gdb
Xtensa ESP32-S2xtensa-esp32s2-elf-gdb
Xtensa ESP32-S3xtensa-esp32s3-elf-gdb
RISC-Vriscv32-esp-elf-gdb

GDB 命令

控制命令

运行命令

命令作用
continue/c运行程序,直到遇到断点才停止
next/n单步执行, 跳过函数调用
next/n count运行多步, 跳过函数调用(count 要跳过运行的步骤次数)
step/s单步调试,进入函数调用
step/s count多步调试,进入函数调用(count 要跳过运行的步骤次数)
finish继续执行,直到当前函数返回
until num运行到指定行号(num 行号)
jump/j num直接跳转到指定行数代码,相当于 C 语言的 goto 语句
monitor reset halt复位开发板

set 命令

命令作用
set 变量名=num将指定变量设置为指定值(num 数值)
set $变量名=num设置一个 GDB 的内部变量,此方法可以用于进行特定的调试计算。具体参考ESP32 JTAG Debug 14: GDB Set 命令的第 6 min
set print address off/on打印数据时,关闭/开启 打印对应数据地址
set style address foreground 设置内存地址的前景色(字体颜色)
set style address background 设置内存地址的背景色

信息查看命令

命令作用
list/l列出当前位置往下10列源代码
backtrace/bt查看函数调用信息
where查看当前程序运行到了哪里
info locals查看当前作用域的局部变量信息
info registers/reg显示所有寄存器的值
info registers/reg 显示指定寄存器的值

print 命令

命令作用
print 变量名/数组/字符串/结构体查看指定变量的值
print /x 变量名以 16 进制形式打印变量值
print /d 变量名以 10 进制形式打印变量值
print /u 变量名以无符号 10 进制形式打印变量值
print /o 变量名以 8 进制形式打印变量值
print /t 变量名以 2 进制形式打印变量值
print /a 变量名以地址格式打印变量值
print /c 变量名以字符形式打印变量值
print /f 变量名以浮点数形式打印变量值
print /s 变量名以字符串形式打印变量值
print 函数名 :: 变量名打印指定函数中,指定变量的数据
print ‘指定文件路径’ :: 变量打印不同文件中变量的信息
print pretty on启动 “漂亮打印”(pretty-printing)功能,这将允许 GDB 以更可读的格式输出复杂数据结构(如结构体、类、数组等),使得调试时的输出更加清晰易懂

display 命令

命令作用
display 变量名持续监视某个变量
display /x 变量名以 16 进制形式持续监视某个变量
info display查看 display 列表
disable display num失能 display 列表中指定监视
enable display num使能 display 列表中指定监视
undisplay num删除 display 列表中指定监视
delete display num删除 display 列表中指定监视

地址信息打印命令

格式 :

x/<count><format><size> <address>
  • <count>:要显示的内存单元的数量(可选,默认值为 1)。
  • <format>:指定输出格式,可以是以下之一:
    • x:十六进制(hexadecimal)
    • d:十进制(decimal)
    • u:无符号十进制(unsigned decimal)
    • o:八进制(octal)
    • t:二进制(binary)
    • c:字符(character)
    • f:浮点数(float)
    • s:字符串(string)
    • i:指令(instruction)
  • <size>:指定每个单元的大小,可以是以下之一:
    • b:字节(byte)
    • h:半字(halfword,2 bytes)
    • w:字(word,通常为 4 bytes)
    • g:巨字(giant word,通常为 8 bytes)
  • <address>:要查看的内存地址,可以是变量名、指针或具体的内存地址。

断点命令

添加断点

命令作用
break/b ngdb 运行到的当前文件中的某一行设置断点(n : 当前文件行号)
break/b filename: n向指定文件的指定行设置断点(filename : 指定)
break/b func在指定函数开头设置断点(func : 函数名)
tbreak n/func设置临时断点,在设置之后只起作用一次(n : 当前文件行号 func : 函数名)

断点控制

命令作用
disable n失能指定断点号断点 (n : 断点号)
enable n使能指定断点号断点 (n : 断点号)
delete/d删除所有断点
delete/d n删除指定断点号断点 (n : 断点号)
clear n清除行 n 上面的所有断点

查看断点信息

命令作用
info break/b查看所有断点信息
info break/b n查看指定断点号断点信息 (n : 断点号)

观察断点

命令作用
watch 变量名给指定变量名设置一个观察断点,所有与该变量名发生变化的地方进行打断,在运行到发生修改地方时,会停止并且打印该变量的原来值修改之后的值。在相同的地方,如果只有第一次该变量发生变化,那么该地方只有第一次会被打断
info watch查看观察断点相关信息
watch 表达式给一个表达式观察断点,例如表达式 i+j,如果变量 i 不发生变化,j 发生变化,依旧会在 j 发生变化的地方进行打断

其他命令

命令作用
shell clear调用 shell 清屏命令
quit/q退出 gdb 调试
define my_command自定义命令,能够进行自定义调试,具体用法参考ESP32 JTAG Debug 15: GDB Define 命令

TUI 使用

命令作用
上下左右箭头向上/下/左/右向滚动代码
PgUP/PgDn向上/下翻页
update回到当前运行的位置
list/l num查看指定行号信息(num 行号)
layout asm查看汇编代码
layout regs显示寄存器相关信息
layout src回到源代码

参考

  1. Windows 环境下,使用 ESP32-S3 USB 接口进行 JTAG 调试的流程
  2. B站:ESP32 JTAG Debug 01: JTAG接口简介
  3. 利用 Guru Meditation 错误打印定位问题
  4. GDB常用命令大全 GDB 命令详细解释
  5. gdb调试常见命令详细总结(附示例操作)

http://www.niftyadmin.cn/n/5669587.html

相关文章

C++中string类的使用

目录 1.auto和范围for 1.1auto关键字 1.2范围for 2.string类常用接口说明 2.1默认成员函数 2.1.1构造函数(constructor) 2.1.2赋值运算符重载(operator()) 2.2string类对象的访问及遍历操作(Iterators and Element access) 2.3string类对象的容量操作(Capacity) 2.3.1…

基于ARM与FPGA的高速多轴嵌入式运动控制器设计流程

一、项目概述 本课题旨在设计一款具备良好扩展性和高速处理能力的嵌入式运动控制器&#xff0c;主要实现基本的伺服控制功能。针对双惯量谐振系统的速度控制&#xff0c;研究了相应的伺服控制算法。通过采用松下A5N驱动器&#xff0c;结合嵌入式架构以及网络通讯模式&#xff…

MATLAB在无线通信系统仿真中的应用:从理论到实践

无线通信技术是现代通信领域的核心&#xff0c;其发展推动了自动驾驶汽车、智能工厂和远程医疗等新技术的应用。MATLAB作为一种强大的数学软件&#xff0c;提供了一整套工具箱&#xff0c;使得工程师和研究人员能够高效地进行无线通信系统的建模、仿真、测试和优化。本文将详细…

iPhone 上丢失了重要的联系人?如何恢复已删除的 iPhone 联系人

丢失 iPhone 上的联系人可能会带来灾难。无论是一份很棒的新工作机会、潜在的恋爱对象&#xff0c;还是您一直想打电话的老朋友&#xff0c;如果您打开“联系人”应用时看到空白&#xff0c;这绝不是好事。不过&#xff0c;一切并非全无&#xff0c;仍然可以通过备份或专业软件…

2023北华大学程序设计新生赛部分题解

时光如流水般逝去&#xff0c;我已在校园中奋战大二&#xff01;(≧▽≦) 今天&#xff0c;静静回顾去年的新生赛&#xff0c;心中涌起无尽感慨&#xff0c;仿佛那段青春岁月如烟花般绚烂。✧&#xff61;(≧▽≦)&#xff61;✧ 青春就像一场燃烧的盛宴&#xff0c;激情澎湃&…

【CSS Tricks】如何做一个粒子效果的logo

效果展示 代码展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>粒子效果Logo</title>…

Cisco Catalyst 9000 Series Switches, IOS XE Release 17.15.1 ED

Cisco Catalyst 9000 Series Switches, IOS XE Release 17.15.1 ED 思科 Catalyst 9000 交换产品系列 IOS XE 系统软件 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-catalyst-9000/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&…

GDBus.Error.org.bluez.Error.Failed: br-connection-unknown

The error you’re seeing, GDBus.Error.org.bluez.Error.Failed: br-connection-unknown, is typically related to issues with the Bluetooth stack or the pairing process on the Raspberry Pi. Here’s a step-by-step troubleshooting guide to help resolve this issue…