JTAG调试ESP32
JTAG调试ESP32
硬件:jlink、esp32、杜邦线
先把正常的 jlink 驱动装好,插上 jlink 检查一下是不是识别到了设备
然后运行 zadig,选择 Options
List All Devices 列出所有驱动
此时效果如下,虽然显示的驱动时 jlink 的,但是这个是串口的,不是我们要的,不要改这个!
选择 BULK 这一项,点击 Replace Driver
找到 esp32 开发环境中自带的 opencod.exe 所在的路径:C:\Espressif\tools\openocd-esp32\v0.11.0-esp32-20220706\openocd-esp32\bin
然后把 esp32.cfg(C:\Espressif\tools\openocd-esp32\v0.11.0-esp32-20220706\openocd-esp32\share\openocd\scripts\target\esp32.cfg)复制到当前 openocd 目录
前面加上句:source [find interface/jlink.cfg]
运行:openocd.exe -f interface/jlink.cfg -f ./esp32.cfg 发现报错:JTAG I/O operation failed: 0x1.
找一下 jlink.cfg(C:\Espressif\tools\openocd-esp32\v0.11.0-esp32-20220706\openocd-esp32\share\openocd\scripts\interface\jlink.cfg)编辑上一行 adapter speed 9600
在执行 openocd.exe -f interface/jlink.cfg -f ./esp32.cfg 就没问题了
我们以 esp32 的示例程序 hello world 为例,找到例子中的 hello world 位置 C:\Espressif\frameworks\esp-idf-v4.4.3\examples\get-started\hello_world
打开 ESP-IDF 切换到 hello_world 路径,使用 idf.py build 将 hello_world 编译出来,然后将 ESP32 插入电脑,使用 idf.py flash 将编译成功的 hello_world 烧录到 ESP32 中
按照 ESP32 的引脚定义连接好 ESP32 的板子和 Jlink 设备上的针脚
在 hello_world 文件夹创建一个 gdbinit 文件,内容为:
target remote :3333
set remote hardware-watchpoint-limit 2
mon reset halt
flushregs
thb app_main
c
对 gdbinit 每条指令做一个解释:
target remote :3333 指定了连接的端口
set remote hardware-watchpoint-limit 2 限制 GDB 仅使用 ESP32 支持的两个硬件观察点
mon reset halt 复位芯片并使 CPU 停止运行
flushregs 一种强制 GDB 从目标获取最新状态的方法
thb app_main 在 app_main 处插入一个临时的硬件断点
c 恢复程序运行,它将会在 app_main 的断点处停止运行
使用 xtensa-esp32-elf-gdb -x gdbinit .\build\hello_world.elf 调试程序,运行起来之后输入 c 就会断在源码文件的第 17 行
我们可以通过串口工具观察整个过程,先使用 b 22 给源码的第 22 行下一个断点
然后输入 c 将会断到第 22 行,这时串口应该输出 Hello world! 这个串口信息,但不应该打印 This is xxx 这一段话,我们运行看看实际情况
到此调试是能调试了,怎么通过 opencode 提取固件呢,想要提取固件首先得知道你要提取的东西在内存中的位置与大小(其实大小也无所谓,你可以尽量大一点哈哈哈),我们看烧录过程中的日志:
然后使用命令将这一块的内存提取到 opencod 目录的 output.bin:
openocd.exe -f interface/jlink.cfg -f ./esp32.cfg -c init -c "reset halt" -c "flash read_bank 0 output.bin 0x10000 0x29c40" -c "reset" -c shutdown
我们将提取出来的与 build 编译的固件计算一下 md5 值,可以看到两者 hash 相同,证明我们完美的提取了 hello_world.bin
certutil -hashfile <filename> MD5
最后:esp32官方是有 esptool.py 能够直接提取固件的,命令如下
esptool.py --baud 115200 read_flash 0x10000 0x29c40 output.bin
效果是一样的