引言
在一些常见的嵌入式系统的开发当中,硬件的调试接口是极其重要的,但是一些传统的调试方法往往存在一些可能致命的问题。比如串口调试虽然简单容易使用,但是实时性较差,不够精确。单步执行的话,虽然精确度高,但是又存在操作复杂的问题。传统的调试方法往往受到速度、准确性和调试精度的限制。
为了解决这些问题,JTAG(联合测试行动组,Joint Test Action Group)和SWD(Serial Wire Debug)作为两种主要的调试协议,广泛应用于嵌入式开发中。它们提供了高效的硬件调试手段,不仅能够实现单步执行、断点设置、变量监控等常规调试功能,还能够深入底层硬件,进行更复杂的系统级调试。
JTAG 和 SWD
JTAG(联合测试行动组)
大多说人可能听过JTAG,并且用它给MCU或者FPGA烧录过程序,或者对开发板进行过调试,JTAG 最初是为了解决硬件板级测试问题而提出的,它是一种标准化的调试接口,那什么是标准化的调试接口呢?比如说在PCB板上存在三种厂家的芯片,那如果想对三个芯片都进行测试的话就需要一个适应所有芯片的代码,会非常的庞大且单一性较强,所以才有了像JTAG这些标准化的调试接口。
JTAG 协议基于一个串行通信接口,由四个主要的信号线(上图中的实线部分)和一个复位引脚组成(虚线部分)主要通过四个信号引脚进行数据传输:
· TDI(Test Data In):测试数据输入,用于接收数据到目标设备。
· TDO(Test Data Out):测试数据输出,用于输出从目标设备获取的数据。
· TMS(Test Mode Select):测试模式选择,通过该信号来选择不同的工作模式。
· TCK(Test Clock):测试时钟,提供时钟信号以驱动数据传输。
通过这四个信号,JTAG 能够控制和访问目标设备的各个寄存器、内存以及执行控制流程。
我们在使用JTAG进行调试时,一般不会在我们写好的代码当中去调用JTAG的接口,而是通过JTAG调试器来与硬件进行交互。一般会与我们的开发环境进行配合,比如我们常见的GDB调试工具。下面我举了一个简单的例子来使用JTAG进行调试。
下面我将对上面的C语言程序使用GDB和JTAG进行调试
1. 编译程序,为了使用 GDB 和 JTAG 进行调试,我们需要编译程序并生成调试信息。使用 -g 参数编译程序,这样 GDB 才能读取符号信息
2. 假设已经连接了一个 JTAG 调试器(如 ST-Link 或 J-Link),可以使用 OpenOCD 启动调试服务器。这个服务器会通过 JTAG 接口与目标硬件通信。在 OpenOCD 启动命令行中指定调试器接口和目标设备
执行结束后会启动OpenOCD,对GDB调试命令进行监听。
3. 启动GDB并且加载好编译的文件
4. 连接GDB到OpenOCD在 GDB 中,连接到运行 OpenOCD 的调试服务器
GDB 会连接到 OpenOCD,后者通过 JTAG 连接到目标设备。
1. 设置断点并且调试
l 设置断点:可以设置断点在 main 函数或任何其他地方(例如,刚刚插入的 __asm("bkpt #0"))。
l break main:会在main函数的开头设置一个断点
l 运行程序:使用 continue 命令运行程序,GDB 会在断点处暂停。
l 单步执行:当程序在断点处暂停时,可以单步执行代码:(step 进入函数 next 执行下一行,不进入函数)
l 查看寄存器:可以查看 CPU 寄存器的内容,例如查看程序计数器 PC(info registers)
l 查看变量值:还可以查看某个变量的值,例如查看 i(print i)
l 退出 GDB:调试结束后,你可以退出 GDB。
2. 调试器和JTAG的交互
l 当程序运行到 __asm("bkpt #0") 断点时,JTAG 调试器会暂停程序的执行,GDB 会接管控制。
l 你可以通过 GDB 调试命令来执行单步调试、查看寄存器和内存内容、设置更多断点等。
l TAG 在这个过程中负责与硬件进行交互,GDB 通过 JTAG 通道控制程序执行。
以上就是JATG的基本使用方法。那下面我们再来说一下SWD
SWD(Serial Wire Debug)调试技术
SWD是我们在学习STM32过程中最常见的烧录接口SWD是由ARM公司为其处理器(特别是Cortex系列)开发的一种串行调试接口。它的设计目的是为了在有限的引脚资源下提供高效、低功耗的调试解决方案,尤其适用于嵌入式应用和资源受限的系统。
SWD是一个2线(或4线)接口,相比JTAG节省了许多硬件资源,典型的接口信号有:
l SWDIO(Serial Wire Debug Input/Output):串行数据输入/输出
l SWCLK(Serial Wire Clock):时钟信号
l NRST(可选,复位信号):目标设备的复位信号
SWD提供了与JTAG类似的调试功能,但采用串行方式进行数据传输,相对占用更少的引脚。
如果想进行SWD的实际调试,只需要将上面示例中的JTAG更换成SWD即可
JTAG和SWD在系统调试中的应用
以上示例就是JTAG和SWD的简单使用,那在实际的应用开发当中,这两种调试方法我们应该如何去选择呢?这就需要了解一下两种技术的优缺点
首先,JTAG技术具有广泛的硬件支持,很多嵌入式的芯片和处理器都提供了JTAG接口,JATG接口通常提供了丰富的调试功能,包括读取和写入寄存器、访问内存、硬件断点等。因为JTAG提供了更多的控制和功能,所以更适用于比较复杂的嵌入式操作系统。但是由于它的并行性和较多的控制线,硬件实现会更加复杂。
SWD的硬件设计更为简化,只需要少量的引脚,所以在资源受限的系统中更加容易执行,但是提供的功能不如JTAG丰富。
那JTAG vs. SWD:如何选择?
在选择JTAG还是SWD时,应考虑以下因素:
1、硬件支持
首先,检查目标芯片是否支持所需的调试接口。如果芯片只支持其中一种接口,选择已支持的接口是明智的。
2、性能需求
如果你需要更高的通信速度和较低的功耗,那么SWD可能是更好的选择。但如果你需要丰富的调试功能,可能需要使用JTAG。
3、系统复杂性
对于较复杂的系统,特别是涉及多个处理器核心或FPGA的系统,JTAG通常更适用,因为它提供了更多的控制和功能。
4、成本考虑
考虑硬件成本和复杂性。SWD通常更简单,因此在资源有限的系统中可能更经济实惠。
5、开发工具
确保你的开发工具和调试器支持你选择的接口。大多数现代调试工具都同时支持JTAG和SWD。
结论
JTAG和SWD都是重要的嵌入式系统调试接口,各自具有优势和劣势。选择哪种接口取决于项目需求、硬件支持和性能要求。对于复杂的系统,可能需要使用JTAG以获得更多的控制和功能,而对于资源有限的系统,SWD可能更适合。综合考虑这些因素,可以帮助你做出明智的选择,以便更有效地进行嵌入式系统开发和调试。