2.2 嵌入式软件的调试技术
嵌入式系统的调试器和被调试的程序往往在不同的机器上,而且应用程序最终必须在目标硬件上运行。为了向开发人员提供灵活方便的调试界面,调试器仍运行在通用的PC的操作系统环境中,而被调试的程序则运行在嵌入式操作系统环境中。
2.2.1 调试技术介绍
嵌入式系统的调试有4种基本方法:
■ 模拟调试。
■ 软件调试。
■ BDM/JTAG调试。
■ 全仿真调试。
(1)模拟调试
调试工具和待调试的嵌入式软件都在主机上运行,由主机提供一个模拟的目标运行环境,可以进行语法和逻辑上的调试。
优点:简单方便,不需要目标板,成本低。
缺点:功能非常有限,无法实时调试。
大多数调试工具都提供模拟调试功能。
(2)软件调试
主机和目标板通过某种接口连接,主机上提供调试界面,待调试软件下载到目标板上运行。
这种方式的先决条件是要在Host和Target之间建立起通信联系。
优点:纯软件,价格较低,简单,软件调试能力较强。
缺点:需要事先烧制目标板,而且目标板工作正常,功能有限,特别是硬件调试能力较差。
(3)BDM/JTAG调试
这种方式有一个硬件调试体,该硬件调试体与目标板通过BDM、JTAG等调试接口相连,与主机通过串口、并口、网口或USB口相连。待调试软件通过BDM/JTAG调试器下载到目标板上运行。
优点:方便、简单,无需制作目标板,软硬件均可调试。
缺点:需要目标板,且目标板工作基本正常,仅适用于有调试接口的芯片。
(4)全仿真调试
这种方式用仿真器完全取代目标板上的MCU,因而目标系统对开发者来说是完全透明的、可控的。仿真器与目标板通过仿真头连接,与主机有串口、并口、网口或USB口等连接方式。由于仿真器自成体系,调试时既可以连接目标板,也可以不连接目标板。
优点:功能非常强大,软硬件均可做到完全实时在线调试。
缺点:价格昂贵。
2.2.2 基于JTAG的ARM系统调试
JTAG(Joint Test Action Group)是IEEE 1149.1标准。JTAG的建立使得集成电路固定在PCB上,只通过边界扫描便可以被测试。这使得复杂的嵌入式处理器的板级调试成为可能。
JTAG技术最初用于边界扫描测试,但因其灵活高效的特性逐步发展用于支持其他功能。扩充JTAG指令并在处理器内部增加支持片上调试功能的逻辑,使得JTAG技术能够用于调试。
(1)边界扫描(Boundary2Scan)
边界扫描技术的基本思想是在靠近芯片的I/O引脚上增加一个移位寄存器单元,也就是边界扫描寄存器(Boundary2Scan Register)。
当芯片处于调试状态时,边界扫描寄存器可以将芯片和外围的输入/输出隔离开来。通过边界扫描寄存器单元,可以实现对芯片输入/输出信号的观察和控制。对于芯片的输入引脚,可以通过与之相连的边界扫描寄存器单元把信号加载到该引脚中去;对于芯片的输出引脚,也可以通过与之相连的边界扫描寄存器捕获该引脚上的输出信号。在正常的运行状态下,边界扫描寄存器对芯片来说是透明的,所以正常的运行不会受到任何影响。这样,边界扫描寄存器提供了一种便捷的方式用于观测和控制所需调试的芯片。另外,芯片I/O引脚上的边界扫描寄存器单元可以相互连接起来,在芯片的周围形成一个边界扫描链(Boundary2Scan Chain)。边界扫描链可以进行输入和输出,通过相应的时钟信号和控制信号,就可以方便地观察和控制处在调试状态下的芯片。
(2)测试访问端口TAP(Test Access Port)
■ 测试数据输入TDI(Test Data Input):JTAG指令和数据的串行输入端口,在TCK上升沿时被采样。
■ 测试数据输出TDO(Test Data Output):JTAG指令和数据的串行输出端口,在TCK下降沿时输出。
■ 测试时钟TCK(Test Clock):为寄存器和TAP控制器提供输入时钟。
■ 测试模式选择TMS(Test Mode Select):用于TAP控制器的状态切换,在TCK上升沿时被采样。
■ TRST(Test Reset):JTAG电路的复位输入信号,低电平有效。
(3)TAP控制器
TAP控制器的作用是产生控制信号。一种是选链信号,即选择指令寄存器或某条数据寄存器;另一种是扫描控制信号,控制选中的寄存器进行移位和读写的工作。TAP控制器的核心部件是一个16状态的状态机。各个状态之间的转换由TCK、TMS和TRST这三个输入信号决定。
(4)指令寄存器和译码逻辑
指令寄存器的长度一般等于指令的长度,指令通过TDI逐位移入指令寄存器,在译码逻辑的作用下产生译码信号。译码信号主要用于数据寄存器的选择,也可根据特殊需要定义新的译码信号。
(5)数据寄存器组
JTAG电路必须提供至少两个数据寄存器:旁路寄存器和扫描链寄存器。除此之外,用户可根据需要自行添加相应的扫描链来实现额外的功能。
(6)JTAG指令
JTAG指令分为公共指令和私有指令两种。公共指令是可供用户使用的JTAG指令,私有指令只能由芯片制造商使用。