一种新的嵌入式处理器在线调试方法
2010-06-13吴舜晓黄仰博孙广富
吴舜晓,张 建,黄仰博,陈 亮,孙广富
(国防科技大学电子科学与工程学院卫星导航定位研发中心,长沙410073)
1 引言
在FPGA设计中使用嵌入式处理器软核(如MicroBlaze、PicoBlaze等)构成可编程片上系统(System On Programmable Chip,SOPC),相比于 ASIC 具有更好的可修改性和可维护性,得到了普遍的应用[1]。由于ARM,MicroBlaze等大型处理器内核具备调试接口,在与之对应的调试模块配合下,调试软件可以通过JTAG接口实现:执行到断点处挂起、单步执行、查看处理器内部状态、查看和修改Memory空间中的数据等基本的在线调试功能[2-3]。上述基本的在线调试功能对嵌入式系统的调试具有重要意义。
对于PicoBlaze等占用资源少、设计开发简单的小巧型处理器,一般不具备调试接口,然而在SOPC系统设计中经常需要使用上述处理器。使用上述处理器时,由于没有调试接口,属于大型处理器的标准高效的调试机制不再能够使用,因此通过指令集仿真(ISS,Cycle-accurate Instruction Set Simulation)和利用仿真工具对含有处理器的系统进行软硬件协同仿真是确保设计正确性的重要途径[4]。然而在诸如接收机基带信号处理等系统的设计中,仿真所用的测试用例往往覆盖率不够,或者在发现故障以后很难构造出与之相应的测试用例。因此迫切需要使在线调试功能能够方便地扩展到一般的处理器上。
针对上述应用需求,这里提出的新调试方法通过引入一种通用的调试模块(Universal Debug Module,UDM)可以使没有调试接口的处理器建立起标准的调试机制。该调试模块利用处理器的中断机制实现处理器响应断点(breakpoint)的机制,利用基于双端口RAM中一种巧妙的地址映射机制实现同时对多行代码设置断点的功能,并且能够方便地实现被调试系统和调试主机之间调试信息和命令的交互。UDM还具有易于扩展的优点,当SOPC系统中有多个处理器时可以共用一个UDM。
2 在线调试的一般原理
嵌入式处理器的主流在线调试方法,目前主要有2种:后台调试模式(backgroud debug mode,BDM)技术和基于IEEE P1149.1协议的JTAG调试技术。BDM技术在Motolora微控制器中得到了大量的应用,ARM,MIPS和PowerPC等处理器都具有基于JTAG技术的在片调试功能,如ARM公司提出了基于JTAG技术的RDI调试接口标准,主要用于ARM芯片的调试[5]。处理器内核中通过增加支持调试的扩展设计,可在预留的调试接口输入简单的控制信号,以实现:处理器挂起(Halt)、输出PC值和通用寄存器值、输出和修改Memory空间中的数据等基本的原始调试操作[2-3]。通常上述调试接口的设计与指令集架构相关,如MIPS32提供如下一些调试方法[5]:①断点指令BREAK;②一些自陷指令TRAP;③特殊控制寄存器WATCH,通过编程使得特定的load/store操作以及取指操作产生特殊的例外;④一种基于TLB的MMU,通过编程使得访问任意存储器页都可以产生特定的例外。
对于没有调试接口的处理器目前主要是通过在软件和硬件设计中充分考虑可能的调试需求,再加上调试主机和被调试系统之间的通信机制来实现在线调试的。这种调试模式下,调试代码需要插入到正常程序中,将调试信息输出到调试主机,同时还能够接收调试主机发过来的命令做出各种响应。该方法的主要缺陷是针对不同的调试需求,要不断修改正常程序中的调试代码,导致标准化和通用性程度不高。此处的UDM在不对处理器内核做修改的情况下即可使这类处理器建立起方便的调试机制,是一种不同于主流大型处理器实现在线调试的方法。
3 通用调试模块(UDM)的工作原理
3.1 系统描述
使用UDM的调试系统框图如图1所示,利用与FPGA同在一块PCB板上的ARM、DSP等处理器作为辅助调试用的嵌入式处理器(下文中简称为辅助处理器),简化了UDM与调试主机之间的通信。通过辅助处理器的总线接口,UDM中的各种控制和数据寄存器被直接映射到辅助处理器的Memory空间。在辅助处理器开发工具的Memory窗口直接进行数据读写操作,就可实现对UDM的操控,如图4、图5所示。由于在一块PCB板上同时集成FPGA和嵌入式处理器芯片是很常见的设计,因此这种通信方式适用的范围很广。
图1 应用UDM的调试系统框图
UDM直接作为FPGA外部辅助调试的嵌入式处理器的外设,如果在外部处理器总线挂接多个UDM模块,就能实现同时对多个处理器进行调试。UDM通过产生调试中断(DeBug Interrupt,DI)信号,使处理器响应中断并调用调试服务程序(Debug Routine,DR)。UDM通过监测处理器的取指令地址(Instruction Address,IA)产生 DI信号。PicoBlaze在运行DR时可通过其总线接口访问UDM,从而实现调试信息的输出和对调试命令的响应。
3.2 断点设置机制
产生DI时由于处理器会立即执行DR,从而中断正常的执行流程转为为调试服务,因此决定DI产生的时机是实现断点机制的核心。DI信号是通过监测处理器的取指令地址(Instruction Address,IA)产生的。直接通过一个比较器将IA与一个数据比较一次只能设置一个断点,为了解决此矛盾采用了如下方法:在UDM中用双口RAM存储断点配置信息,使RAM中的每1bit与程序存储区的一个地址对应起来,数据为1代表设置了断点,0代表没有。将输入的IA进行地址变换后对RAM存储区寻址,使得RAM在一端输出一个正好代表输出的地址处是否设置了断点信息,再根据此数据就可生成正确的DI信号。在双口RAM的另外一端,断点设置情况可以方便地被修改。这样一来可以设置的断点个数变为主要受UDM中双口RAM容量限制了。
3.3 调试服务程序
只需在DR中保证处理器不对目标程序的内外部环境造成改变,就等效于实现了处理器的挂起功能。因此,需要将DR和目标程序的执行环境隔离开来,这可以通过对编译器进行某些设置或强制的编码规范来实现。在处理器被挂起之后,DR与外部调试主机通信,通过查询命令寄存器的方式响应调试主机发出的各种调试命令。这些命令包括:将有关的调试信息搬移到外部调试主机可以观察的缓存区中、修改Memory空间中的数据、退出DR使目标程序继续执行等。由于DR必须与目标程序使用相互隔离的资源并且小型处理器中代码容量,外部Memory空间大小等都比较受限,因此DR的设计应该尽可能占用较少的端口数、通用寄存器数和代码总行数。
4 设计实例
Xilinx公司的PicoBlaze是一种常用的小巧型处理器,它由ALU、程序计数器栈(适用于嵌套子程序)、16个8位通用寄存器、64字节RAM构成的暂存器、程序计数器和控制器以及中断支持电路构成,其代码容量为1024[4]。本节以针对PicoBlaze的应用为例,设计了一个具体的 UDM,并在 Spartan3S5000 FPGA上进行了实际验证。该UDM使用的硬件资源为1个18KB BRAM和62个Spartan-3逻辑片,软件资源为61行汇编代码,具备的功能如下:
·可同时在每一行代码处设置断点,在没有设置断点的情况下,可强制产生DI,从而运行DR 输出调试信息;
·可以观察到的调试信息为:程序计数器PC的值、s0~sb寄存器、64byte的暂存器,Memory空间中的数据,在DR运行时可以刷新上述调试信息。
4.1 硬件实现
基于PicoBlaze处理器应用的UDM硬件结构如图2所示。UDM与调试终端和PicoBlaze都有总线接口,因此其内部寄存器分为3类:仅受PicoBlaze控制,仅受辅助处理器控制以及受二者共同控制。PicoBlaze和辅助处理器分别在双口RAM的A、B端口写入数据。为了减少占用PicoBlaze的I/O端口,PicoBlaze在向双口RAM写入数据之前先向RAM寻址寄存器写入地址,然后通过写数据输出寄存器将数据写入前一操作指定的地址中。
图2 UDM的内部电路结构框图
双口RAM的B端口连接到辅助处理器的总线,数据位宽为16,可访问的地址范围为0~255,地址0~165作为交互调试数据的缓存区,地址192~255用于存储断点设置信息。每一个寄存器中存放16行代码的断点设置情况,由于PicoBlaze的代码容量为1024行,故只需占用64个寄存器,例如地址为193的数据为0x4080则表示第24和31行设置了断点。双口RAM的A端口数据位宽为8,在DR运行时用于输入调试信息,在目标程序运行时输出断点设置信息。因此在A端口有一个地址选择电路,使得输入A端口的地址在不同的情况下分别由RAM寻址寄存器和IA决定。当运行目标程序时,A端口输入的地址为IA的高7位加上偏移量0x180,输出的8bit数据再经IA的低3位寻址输出1bit数据,这样得到的数据正好反映了与IA对应的代码是否设置了断点。中断信号产生电路根据上述数据和中断信号的时序要求,产生输出给处理器的DI信号。
调试命令寄存器由PicoBlaze和辅助处理器共同控制,辅助处理器向该寄存器写不同的数代表不同的调试命令。在运行DR时通过查询该寄存器来实现对各种调试命令的响应,在响应调试命令之前PicoBlaze将调试命令寄存器清0,作为与辅助处理器的握手操作机制。当向调试命令寄存器写3时,不管是否设置了断点都会立即产生DI信号。
4.2 软件实现
在基于PicoBlaze的应用中,为了减少代码容量,DR的流程比较简单。在初始化准备之后,依次将s0~sb寄存器、64byte的内部RAM,Memory空间中的数据输出到双口RAM中,然后陷入一个等待和处理调试命令的循环中。目标程序和DR执行环境的隔离通过限制目标程序只允许修改寄存器s0~sb以及64byte的内部RAM,而DR只允许修改寄存器se~sf来实现。只有当调试命令为退出调试时,DR程序才会结束,PicoBlaze又返回到目标程序的执行。当调试命令为刷新调试信息时,PicoBlaze将重复一次初始化和调试信息输出的过程。
4.3 实际验证和使用情况
在应用UDM之前,首先通过NC-verilog对其进行了仿真,部分仿真波形如图3所示。图中反映的是当作为DI的信号pdm_int产生了之后,Pico Blaze怎样转入执行DR的,限于篇幅,验证其他各种功能的仿真波形不在此赘述。
图3 UDM的部分仿真波形
为了进一步对UDM的功能和性能进行完备的检验,在FPGA中建立了如下简单的PicoBlaze处理器系统。PicoBlaze外部只接一块252X8bit的RAM和UDM,PicoBlaze上的目标程序流程为如下的死循环:将s0~sb依次置入0~11,再反过来依次置入11~0;将64byte的RAM依次写入0~63,再反过来写入63~0;将外部的RAM依次写入0~251,再反过来写入255~4。这样的一种简单设计,可以保证从输出的调试信息直接看出处理器在哪行代码处响应了断点。
如图4所示为在调试主机上进行调试控制的界面。偏移地址0x184处的1040表明在38与44两行代码处设置了断点,事实上从地址0x180~0x1ff处都可以设置断点。地址0x200处为当前的PC值,通过向地址0x208处写1可使其更新;地址0x202处为UDM的使能位,当其为1时UDM才被使能;地址0x204为调试命令寄存器,向其写1使处理器从断点退出,写2使处理器刷新调试信息,写3使处理器强制进入DR输出调试信息;地址0x206处表示调试状态,当其为3时表明处理器在运行DR,并且调试信息已经输出完毕。
图4 使用UDM调试的控制界面
显示调试信息的界面如图5所示,地址0x00~0x0b显示寄存器s0~sb的数据,地址0x0c~0x3b显示内部64byte存储器的数据,地址0x4c~0x14b显示PicoBlaze外部Memory空间的数据。由于图5中断点正好设置在完成依次向PicoBlaze的Memory空间依次写0~251之后,因此显示的数据是递增的。当断点正好设置在完成依次向 Pico Blaze的Memory空间依次写255~4之后,所显示的数据就变为递减。在很多其他断点处显示的调试信息与断点设置的位置也符合预期的情况,因此UDM完全可以正确而高效地工作。
图5 在第44行断点处显示的调试信息
在开发一款信号处理芯片的FPGA原型设计中,跟踪处理、电文处理、整体流程控制分别由一个PicoBlaze完成,并且由于FPGA资源的限制采用大型处理器来替代上述处理器几乎不可能。由于输入PicoBlaze的数据和控制信号复杂,仿真验证不能很好地覆盖各种实际的使用情形。通过使用这里的基于PicoBlaze处理器设计的UDM,方便地实现了对上述3个PicoBlaze的在线调试,对提高开发效率发挥了重要作用。在其他使用PicoBlaze的工程应用中,上述UDM也得到了很好的推广。
5 结束语
设计了一种通用调试模块,用于辅助无调试接口的处理器建立标准的调试机制。通过该模块的使用,提出了一种通用、标准、方便的调试方法,很好地满足了在SOPC系统中对多个没有调试接口的小巧型处理器实现在线调试的迫切需求。新方法通过产生调试中断使处理器跳转到调试服务程序中的方式实现处理器的挂起,通过基于双端口RAM中一种巧妙的地址映射机制实现同时对多行代码设置断点的功能,通过调试服务程序实现数据搬移等调试命令。新方法还具有易于扩展,可以同时调试多个嵌入式处理器的优点。新的调试方法在工程实践中对提高调试效率发挥了重要作用,是一种普适的,应用价值明显的调试方法。
[1]潘松,黄继业,曾毓.SOPC技术实用教程[M].北京:清华大学出版社,2005.
[2]陈艳华.基于ARM的嵌入式系统开发与实例[M].北京:人民邮电出版社,2008.
[3]龙霞飞,李仁发.Microblaze微处理器IP Core的结构及应用[C].北京:中国计算机学会,2004.
[4]Hempel,Gerald;Hochberger, Christian.A resource optimized Processor Core for FPGA based SoCs[C].Digital System Design:Architecture,Methods and Tools(DSD),Lubeck,Germany:10th Euromicro Conference,2007.
[5]黄海林,范东睿,许彤,等.嵌入式处理器在片调试功能的设计与实现[J].计算机辅助设计与图形学学报,2006,18(7):1005 -1010.