4. GDB基础

调试器是连接 OpenOCD 和目标芯片的桥梁。市面上常见的调试器种类很多,但配置思路其实有章可循。我个人习惯把调试器分成两类:一类是通用 USB 转 JTAG/SWD 方案(比如 FTDI 系列),另一类是专用调试器(比如 J-Link、ST-Link)。下面我们逐个来看。

核心要点: 无论哪种调试器,OpenOCD 配置都围绕三个要素——接口驱动(adapter driver)、传输协议(JTAG/SWD)、目标芯片(target)。搞懂这个框架,换调试器只是改几行配置的事。
调试器配置知识结构 OpenOCD 配置 adapter driver transport target FTDI/FT2232 CMSIS-DAP J-Link ST-Link 配置本质:告诉 OpenOCD 用什么硬件接口、走什么协议、连什么芯片 换调试器只需改 adapter driver 和对应初始化脚本,target 部分可复用

4.1 FTDI/FT2232 配置

FTDI 的 FT2232H 芯片是我最早接触的调试方案。它本质是一个 USB 转双通道串行引擎,通过 MPSSE 模式可以模拟 JTAG/SWD 时序。说白了,就是用一颗通用芯片干专用调试器的活。

配置 FT2232 时,OpenOCD 需要知道两件事:USB VID/PID 和 引脚分配。不同的开发板,FT2232 的引脚连接可能不一样。我记得有一次帮客户调一块板子,JTAG 死活没反应,折腾了半天才发现是 TCK 和 TMS 接反了。

我的习惯: 拿到一块新板子,先看原理图,确认 FT2232 的 ADBUS0~ADBUS3 分别连到了目标芯片的哪几个引脚。然后对照 OpenOCD 的 ftdi_layout_init 参数,确保一一对应。

一个典型的 FT2232 配置脚本长这样:

# interface/ft2232h_breakout.cfg
adapter driver ftdi

# FT2232H 默认 VID/PID
ftdi vid_pid 0x0403 0x6010

# 引脚配置:data 0x0f0b, output 0x0b0b
# 低字节对应 ADBUS0-7,高字节对应 BDBUS0-7
ftdi layout_init 0x0f0b 0x0b0b

# 信号映射
ftdi layout_signal nTRST -data 0x0010
ftdi layout_signal nSRST -data 0x0020

# 选择通道 A(默认)
ftdi channel 0

# 设置 JTAG 时钟
adapter speed 1000

这里有个坑:ftdi layout_init 的两个十六进制数,第一个是数据方向(1 表示输出),第二个是初始电平。我刚开始用的时候,把这两个数搞反了,结果 JTAG 信号一直拉不起来。你想想看,方向都没设对,信号怎么可能出来?

参数 含义 常见值
ftdi vid_pid USB 设备标识 0x0403 0x6010(FT2232H)
ftdi layout_init 引脚方向与初始电平 0x0f0b 0x0b0b
ftdi channel 选择通道 A 或 B 0(A)/ 1(B)
adapter speed JTAG/SWD 时钟(kHz) 1000 ~ 6000
注意: FT2232 的 JTAG 时钟不建议超过 6MHz。我曾经试过拉到 10MHz,结果调试器间歇性断开,后来查资料才知道 FT2232H 的 MPSSE 引擎在高频下会丢数据。

4.2 CMSIS-DAP 配置

CMSIS-DAP 是 ARM 官方定义的调试接口标准。它的好处是跨平台、免驱(Windows 上需要安装驱动,Linux/macOS 直接识别)。很多开发板自带的调试器,比如 NXP 的 LPC-Link2、TI 的 XDS110,底层都是 CMSIS-DAP。

配置 CMSIS-DAP 比 FT2232 简单得多。因为标准统一了,OpenOCD 只需要知道 VID/PID 就行:

# interface/cmsis_dap.cfg
adapter driver cmsis-dap

# 常见的 CMSIS-DAP VID/PID
cmsis_dap vid_pid 0x0d28 0x0204

# 选择传输协议:SWD 或 JTAG
transport select swd

# 设置 SWD 时钟(kHz)
adapter speed 1000

# 可选:指定序列号(多设备时有用)
# cmsis_dap serial 123456789

我个人觉得 CMSIS-DAP 最大的优点是一致性。不管用什么厂家的芯片,只要调试器支持 CMSIS-DAP,配置基本一样。我在项目中用过好几个不同品牌的 CMSIS-DAP 调试器,脚本几乎可以通用,省了不少事。

小技巧: 如果系统里有多个 CMSIS-DAP 设备,可以用 cmsis_dap serial 指定序列号来区分。在 OpenOCD 启动时加上 -c "cmsis_dap serial YOUR_SERIAL" 就行。

不过 CMSIS-DAP 也有短板——速度上限。大部分实现只能跑到 1~2MHz,比 J-Link 慢不少。如果你要调试高频芯片或者下载大固件,可能会觉得有点慢。

4.3 J-Link 配置

J-Link 是 Segger 公司的产品,也是我目前用得最多的调试器。它的速度快、稳定、支持芯片多。虽然价格贵了点,但项目里省下来的时间早就值回票价了。

J-Link 的 OpenOCD 配置是所有调试器里最简单的:

# interface/jlink.cfg
adapter driver jlink

# J-Link 会自动识别 VID/PID,一般不需要指定
# 但如果系统里有多个 J-Link,可以指定序列号
# jlink serial 123456789

# 选择传输协议
transport select swd

# 设置时钟
adapter speed 4000

# J-Link 特有:配置 SWD 电压(可选)
# jlink config 0  # 自动检测电压

为什么这么简单?因为 J-Link 的固件已经处理了大部分底层细节。OpenOCD 只需要告诉它「用 SWD 还是 JTAG」「速度多少」就行。我记得第一次用 J-Link 时,配置完直接就能连上,那种顺畅感让我觉得之前调 FT2232 的日子简直是在浪费时间。

特性 J-Link FT2232 CMSIS-DAP
配置复杂度 低 高 中
最大速度 15~50 MHz ~6 MHz ~2 MHz
芯片支持 极广 取决于引脚配置 ARM Cortex 系列
价格 高 低 中
避坑: J-Link 有 EDU 版和商用版之分。EDU 版便宜,但速度被限制在 1MHz 以下。我有个朋友买了 EDU 版想调试高速芯片,结果发现速度上不去,最后只能退货换商用版。如果你做商业项目,直接买商用版,别省那点钱。

4.4 ST-Link 配置

ST-Link 是 ST 官方为 STM32 系列设计的调试器。它其实分两代:ST-Link/V2 和 ST-Link/V3。V3 速度快了不少,但配置方式基本一样。

ST-Link 的 OpenOCD 配置也很简单:

# interface/stlink.cfg
adapter driver stlink

# ST-Link 版本自动检测,不需要 VID/PID
# 但可以指定版本(可选)
# stlink device_version 2

# 选择传输协议
transport select swd

# 设置时钟
adapter speed 2000

# ST-Link 特有:串口调试功能(可选)
# stlink serial 0

这里有个细节:ST-Link/V2 的 SWD 时钟建议不要超过 4MHz,V3 可以到 24MHz。我刚开始用 V2 时设了 4.5MHz,结果经常出现 CRC 校验失败。后来降到 2MHz,稳如老狗。

我的经验: 如果你用 ST-Link 调试 STM32,建议在 target 配置里加上 reset_config srst_only。因为 ST-Link 的 nSRST 和 nTRST 是分开的,只接 SWD 时用 srst_only 更可靠。我曾经因为没加这行,导致复位时序不对,芯片死活连不上。

ST-Link 最大的优势是便宜且易得。买一块 STM32 开发板,基本都自带 ST-Link。对于 STM32 用户来说,这是最省心的选择。

4.5 调试器配置对比总结

四种调试器各有千秋。我个人的选择标准很简单:

  • 项目预算有限,且芯片是 STM32 → 用 ST-Link,免费又好用
  • 需要高速调试,不差钱 → 上 J-Link,省心省力
  • 自己画板子,想集成调试器 → 用 FT2232,灵活但配置麻烦
  • 跨平台、免驱、通用性 → 选 CMSIS-DAP,标准统一

最后说一句:不管用哪种调试器,先确认接线。我见过太多人花几小时调配置,最后发现是杜邦线松了。嗯,我自己也干过这种事。