CN1564136A - 基于目标机上的ejtag部件的交叉调试器实现方法 - Google Patents

基于目标机上的ejtag部件的交叉调试器实现方法 Download PDF

Info

Publication number
CN1564136A
CN1564136A CN 200410009001 CN200410009001A CN1564136A CN 1564136 A CN1564136 A CN 1564136A CN 200410009001 CN200410009001 CN 200410009001 CN 200410009001 A CN200410009001 A CN 200410009001A CN 1564136 A CN1564136 A CN 1564136A
Authority
CN
China
Prior art keywords
ejtag
instruction
register
breakpoint
return
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
CN 200410009001
Other languages
English (en)
Other versions
CN1312588C (zh
Inventor
田金兰
苏宏谋
王生原
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tsinghua University
Original Assignee
Tsinghua University
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Tsinghua University filed Critical Tsinghua University
Priority to CNB2004100090019A priority Critical patent/CN1312588C/zh
Publication of CN1564136A publication Critical patent/CN1564136A/zh
Application granted granted Critical
Publication of CN1312588C publication Critical patent/CN1312588C/zh
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Images

Landscapes

  • Debugging And Monitoring (AREA)

Abstract

本发明提出了一种利用软件有效控制和使用目标机上的EJTAG部件的方案,据此完成了基于EJTAG的交叉调试器的设计与实现。该方案的特征在于:调试器命令的处理过程全部运行于宿主机,宿主机与目标机之间只需要4~5根信号线,不需要任何额外的硬件设备。调试器以高的性能/价格比实现了运行在宿主机上的汇编级和源码级的调试功能,并且具有良好的适应性与可移植性。

Description

基于目标机上的EJTAG部件的交叉调试器实现方法
技术领域
基于目标机上的EJTAG部件的交叉调试器实现方法属于计算机系统调试工具领域。
背景技术
在开发和生产新的电子、电脑产品时,经常会面对以下几个方面的问题:(1)电路的器件布局日益复杂;(2)元器件小型化、复杂的封装、密集的管脚;和(3)电路板小型化、使用表面焊接技术等。这给产品的线路测试、故障检查以及排除带来很大的麻烦。用传统的线路检测设备已经很难,甚至无法使用。解决这个问题的一个方法是使用边界扫描技术即BST(Boundary Scan Technology)。该技术由IEEE技术委员会的联接测试行动小组(JTAG,JointTest Action Group)制定(工业标准IEEE1149.1),可用于测试电路板上的:(1)各器件本身的逻辑是否正确;(2)各器件之间的连接情况;和(3)组合起来的器件是否完成了预定的功能等。
扩展JTAG即EJTAG(Enhanced JTAG)规范是在JTAG规范基础上进行的扩展。EJTAG的操作对象是MIPS公司的MIPS微处理器或是包含MIPS核的片上系统即SOC(System-on-a-Chip)芯片组件。EJTAG提供了应用程序和核心代码软件调试的应用接口。它
具有以下一些功能:
1)设置硬件断点(Hardware Breakpoint);
2)单步执行(Single Step Excution);
3)支持测试访问端口即TAP(Test Access Port)接口:EJTAG使用TAP接口将测试数据传入或者传出CPU核心。除了支持标准的JTAG指令以外,EJTAG还具有自己新定义的指令。
4)支持软件断点指令:SDBBP(Software Debug Breakpoint)。
基于EJTAG的调试器可用于调试监控程序、操作系统,并且可以通过调试诊断程序,分析确定CPU及主板的故障,是CPU研制工作顺利进行的重要工具。我们提出了一种利用软件有效控制和使用目标机上的EJTAG部件的方案,据此完成了基于EJTAG的交叉调试器的设计与实现,大大降低了成本,并具有很好的可移植性(支持不同的微处理器只需要修改少量的代码)。
发明内容
本发明的目的在于有效控制和使用目标机上的EJTAG部件,以便捷的方式实现运行在宿主机上的汇编级和源码级的调试功能。
根据本发明实现的基于目标机上的EJTAG部件的交叉调试器的思路是:
(1)本调试器适用的目标机为MIPS系列体系结构的CPU,并且它扩展了支持EJTAG规范的部件;参见图1,非透明填充背景的部分为EJTAG增加的部分;只需要CPU可以执行基本的指令集(包括MTC0/MFC0/LUI/LW/SW/LB/SB/DERET/ADD等)就可以使用。
(2)测试访问端口TAP接口的5个JTAG信号TCK(测试时钟Test Clock信号)、TMS(测试方式选择Test Mode Select信号)、TDI(测试数据输入Test Data Input信号)、TDO(测试数据输出Test Data Output信号)和TRST*(测试复位Test Reset Input*信号)通过简单的线路与宿主机的并口相连;表1是JTAG信号和宿主机上的I/O端口数据的对应关系。
                表1JTAG信号和I/O端口数据信号对照表
JTAG信号     I/O端口 方向 比特位       DB25打印口
   针号PinNo     信号
    TMS     BASE     Out     2     4     Data2
    TCK     BASE     Out     1     3     Datal
    TDI     BASE     Out     0     2     Data0
    TDO     BASE+1     In     4     13     Select
其中BASE代表所用的并口的基地址,在PC机上其默认值是0x378。BASE+1表示并口的状态端口。表中的信号方向是从宿主机(PC)的角度看的。复位信号TRST*是可选信号,表中未列出其对应关系。
(3)汇编级调试功能运行于Windows系统,被调试目标代码的显示格式使用反汇编代码;源码级调试功能运行于Linux系统;下载到目标机的格式采用的是Motorola的S-记录即S-Record格式。
(4)调试器的基本功能涉及断点管理(增加、删除、列出断点)、信息查询(查看/修改寄存器的内容、查看/修改指定地址的数据)、执行控制(单步、继续、暂停、复位)及代码管理(装入目标代码用于本地显示、目标代码下载到目标机、显示源代码)等。
(5)调试器的工作是一个软硬件协同工作的过程。调试器启动时,将EJTAG控制寄存器即ECR寄存器中的复位标志位Rocc置0,以及EJTAG中断请求位EjtabBrk,虚拟内存段dseg(debug segment)有效位ProbEn,和调试例外向量地址控制位ProbTrap皆置1,使CPU中断正在执行的程序,进入调试模式。CPU进入调试模式后,它依次执行调试器发送过来的指令,并和调试器交换有关内容,从而完成调试工作。
(6)调试命令的交换格式采用GNU组织的GDB远程串行协议即RSP(Remote SerialProtocol,)格式,这样运行于Windows系统的汇编级调试和运行于Linux系统的高级语言级调试可以共享用于转换与处理过程的代码。
(7)高级语言级调试器的前端采用GNU组织的GDB,后端通过驱动程序和EJTAG/JTAG信号转换及处理过程接口。EJTAG驱动程序采用可装载的内核模块(loadable kernel module)的方式。
根据本发明实现的基于EJTAG的交叉调试器的基本工作过程是:
(1)调试器循环检测ECR寄存器的PrAcc位(暂停标志位,Process Access Pending),若为0,继续检测;若为1,表示处理器已经完成请求的操作而暂停,转(2);
(2)调试器根据运行的状态,决定下一步动作:
·如果是等待CPU中断,表示CPU已进入调试例外处理,等待例外处理的代码;那么把特定指令放入TAP的DATA寄存器(数据寄存器);
·如果是刚让CPU执行了load/store指令,并且操作数地址位于dseg段,那么需要提供操作数(load指令,往TAP的DATA寄存器写),或者读出数据(store指令,从TAP的DATA寄存器读);
(3)调试器把ECR的PrAcc位置为0,表示调试器就绪,CPU可以继续;
(4)转(1)。
本发明提出的利用软件有效控制和使用目标机上的EJTAG部件的方案体现在调试器命令的处理过程中。各基本调试命令的处理过程基本相似,下面以“查看寄存器的值”为例加以说明:
(1)用户通过图形用户界面GUI或者命令行输入调试请求:查看寄存器reg的内容,其命令格式假定为print $reg;
(2)分析用户的调试请求命令(print $reg);
取reg寄存器的顺序号no.of $reg;
打包命令:(request=ReadReg,index=no.of $reg,length=sizeof(int));
调用(3);
转(4);
(3)分析调试请求(ReadReg);
把该请求的处理转换成为一序列的机器指令;其主要部分如下:
MTC0 $t1,DESAVE;保存$t1寄存器
LW $t1,HIGH(dseg);dseg就是0xFF20 0000
SW no.of $reg,0($t1);内容送入TAP的DATA寄存器
MFC0 $t1,DESAVE;恢复$t1寄存器
把有关命令序列一条一条地通过TAP接口送给CPU执行,并取回寄存器内容;
打包响应:(response=success,length=sizeof(int),value=value of $reg);
返回响应;
(4)获得响应(response=success,length=sizeof(int),value=value of $reg);
响应转换成用户友好的方式:$reg=0x12345678(假设value=0x12345678);
显示结果到GUI或者命令行。
读写TAP寄存器是完成以上过程的核心步骤之一。根据EJTAG规范,TAP控制器是一个有限状态机,参见图3,它的状态是由TCK和TMS确定的。TAP控制器在TCK上升沿采样TMS信号,然后根据状态转换图进行转换。TAP状态转换图有16个状态,如图2-5所示。图中箭头边上的数字表示在TCK上升沿时,TMS信号的是处于高电平还是低电平。图3中所标识的状态含义如下:
Test-Logic-Reset状态:测试逻辑复位状态,它是初始状态,在此状态下,边界扫描测试逻辑是被禁止的;Run-Test/Idle状态:控制寄存器在两个扫描操作之间进入这种状态,并且在TMS输入为‘0’时一直保持在此状态,在此状态下,所有指令寄存器和测试数据寄存器内容保持不变;Select-DR-Scan状态:确定扫描数据寄存器状态,在此状态下,所有测试数据寄存器保持不变;Select-IR-Scan状态:确定扫描指令寄存器状态,在此状态下,所有测试数据寄存器保持不变;Capture-DR状态:对指令寄存器进行译码,确定要扫描的数据寄存器;Shift-DR状态:在这个状态下测试数据寄存器连接到TDI和TDO之间,每个时钟周期数据串行向TDO方向移动;Exit1-DR状态:是暂时的中间状态,在这个状态下数据保持不变;Pause-DR状态:在这个状态下,暂时停止测试数据在TDI和TDO之间的移动;Exit2-DR状态:在这个状态下,刷新在Shift-DR状态移位的数据寄存器;Update-DR状态:在这个状态下,在Shift-DR状态移入的数据存入由指令寄存器指定的寄存器中;Capture-IR状态:在这个状态下,指令寄存器自动装入固定向量(000012);Shift-IR状态:在这个状态下指令寄存器连接到TDI和TDO之间,每个时钟周期数据串行向TDO方向移动;Exit1-IR状态:是暂时的中间状态,在这个状态下数据保持不变;Pause-IR状态:在这个状态下,暂时停止测试数据在TDI和TDO之间的移动;Exit2-IR状态:在这个状态下,刷新在Shift-IR状态移位的指令寄存器;Update-DR状态:在这个状态下,在Shift-IR状态移入的指令生效。
TAP寄存器的读写是在Shift-DR或Shift-IR状态进行的,数据在TCK时钟下降沿串行从TDO移出,在上升沿串行从TDI移入。写TAP寄存器时忽略从TDO移出的数据,新数据从TDI移入;读TAP寄存器时保存从TDO移出的数据供返回,同时将其再从TDI移入,以避免破坏寄存器的内容。其主要流程为:
驱动TAP使其转移到Shift-IR状态
把寄存器的选择指令写入TAP的指令寄存器IR
驱动TAP使其转移到Shift-DR状态
for(循环次数=0;循环次数<数据寄存器的位数;循环次数++)
从TDO移出数据(至本地变量)
if(是读取操作)
保存该数据(到本地变量)
TDI(移入数据)=从TDO移出的数据//避免破坏寄存器的内容
else∥是写入操作
TDI(移入数据)=要写入寄存器的数据
从TDI移入数据(至选中的寄存器的最高位)
endfor
驱动TAP使其转移到Update-DR状态
if(是读取操作)
返回读出的寄存器内容
基本调试命令的完成需要与目标机CPU进行配合。本发明提出的利用软件有效控制和使用目标机上的EJTAG部件的方案中,需要目标机CPU的调试例外响应过程如下:
当发生调试例外时,CPU判断ECR(EJTAG控制寄存器)中的ProbTrap位(调试例外向量地址控制位)。如果该位是0,就跳转到0xBFC0 0480。这个地方是由监控程序或操作系统提供的调试例外程序。最后执行DERET,CPU返回正常模式,继续执行;如果该位是1,就跳转到0xFF20 0200。在调试模式下,0xFF20 0200位于实际不存在的虚拟内存段dseg(debugsegment)中。这时候,CPU把PC存入TAP的地址寄存器即ADDRESS寄存器,然后置有关的状态位,等待从TAP送过来指令然后执行。具体过程是:
(1)处理器把程序计数器即PC送到TAP的ADDRESS寄存器;
(2)处理器写TAP模块中的ECR寄存器的标志位:PrAcc=1;PRnW(暂停种类:0表示读,1表示写)=0等;
(3)处理器不停的检测PrAcc位,为1则继续等待;若为0则进入(4);
(4)把TAP的Data寄存器中的指令放到IR寄存器中,处理器按如下几种情况依次执行:
·如果是DERET指令,则转(6);
·如果不是load/store指令,直接执行,然后转(5);
·如果是load/store指令,但是操作数地址不在dseg(0xFF000000-0xFF3F0000)之内,直接执行,然后转(5);
·如果是load指令,处理流程为:
把操作数地址放入TAP的ADDRESS寄存器;
CPU暂停(置ECR的PrAcc=1,PRnW=0等),等待调试器提供操作数;
CPU循环检测ECR的PrAcc,一直到为0进入下一步;
从TAP的DATA寄存器读取操作数,执行该指令;
转(5);
·如果是store指令,处理流程为:
把操作数地址和寄存器内容分别放入TAP的ADDRESS、DATA寄存器;
CPU暂停(置ECR的PrAcc=1,PRnW=1等),等待调试器取走数据;
CPU循环检测ECR的PrAcc,一直到为0进入转(5);
(5)处理器把PC值加4,转(1);
(6)退出调试模式,继续执行原来的代码。
本发明的特征在于:调试命令的处理过程是全部在宿主PC机上运行的,它包含以下步骤:
(1)使扩展了EJTAG部件的目标机MIPS CPU中的测试访问端口即Test Access Port简称TAP接口的由IEEE技术委员会联合测试行动小组Joint Test Action Group简称JTAG制定的IEEEE1149.1工业标准中的下述5个JTAG信号通过信号线与宿主机PC的并行I/O端口相连:
TCK即测试时钟Test Clock信号,方向从宿主PC机到目标机MIPS CPU;
TMS即测试方式选择Test Mode Select信号,方向从宿主PC机到目标机MIPS CPU;
TDI即测试数据输入Test Data Input信号,方向从宿主PC机到目标机MIPS CPU;
TDO即测试数据输出Test Data Output信号,方向从目标机MIPS CPU到宿主PC机;
TRST*即测试复位Test Reset Input*信号,它是可选信号。
(2)在宿主PC机的存储器上建立以下模块:
对于运行在Windows系统下的汇编级调试器,它建有以下模块:
a.人机界面模块,采用图形用户接口GUI界面,被调试目标代码的显示格式使用反汇编代码,它通过以下函数来提供操作界面:
OnOpenDocument():把反汇编显示格式的代码读入内存,并设定以下变量之值:
存储每行代码的长度,
存储代码,
当前行特征位flag,1表示为当前行,0表示非当前行,
断点表,存储断点信息,0表示无断点,非0表示有断点,相应数字即断点类型
代码行特征位flag,1表示为代码行,0表示非代码行(注释等)
OnDownload():下载Motorola的S-记录即S-Record格式的代码到目标机指定地址开始的存储区域;
OnDraw():以不同颜色显示代码;
OnEditBrk():添加断点,向接口发出断点指令;
OnEditMem();得到并显示指定地址内存的内容;
OnEditReg();得到并显示所有寄存器的值;
OnRestart();发送重启指令,重启CPU;
OnSingleStep();发送单步操作命令,并获得单步操作后寄存器的值;
OnRemoveBreakPoint();移除断点;
Pack():根据RSP协议,为包的内容添置包头包尾,
b.调试请求处理模块,它是上层的人机界面模块和下层的EJTAG/JTAG信号转换及处理模块的应用程序API,它把人机界面的调试请求转换成为符合Remote Serial Protocol协议的数据包,发送给EJTAG/JTAG信号转换及处理模块,再接収其响应,后者设有以下9类调试命令:
Callg():读所有的寄存器,简称g,
CallG():写入所有的寄存器,简称G,
Callm():读存储器,简称m,
CallM():写存储器,简称M,
CallR():复位,发出CPU中断后执行的起始地址,简称R,
Callc():继续,发出清除单步标志后继续执行的起始地址,简称c,
Calls():单步操作,发出开始单步执行的起始地址,简称s,
Callz():插入断点,设定某一地址范围为断点,简称z,
CallZ():移除断点,取消某一地址范围的断点,简称Z;
相应地,调试请求处理模块设定以下各个调试请求所用到的函数:
CallAPI():通过EJTAG TAP接口执行从人机界面传来的调试命令,据此调试命令分别调用由下层的EJTAG/JTAG信号转换及处理模块给出的以上9类调试命令,再返回调试结果,
VerifyCommand():验证指令包是否合法,并从中提取有用部分,
GetFirstChar():提取指令的第一个字符,
StrFreeCpy():拷贝一个串;
c.EJTAG信号转换及处理模块,它把RSP格式的调试命令请求转换为JTAG信号,使得与目标机CPU的处理过程同步,并返回响应信息,相应于上述需要处理的调试命令,它对应地设有以下接口函数:
CallR():执行R指令,返回结果,
Callg():执行g指令,返回结果,
CallG():执行G指令,返回结果,
Callm():执行m指令,返回结果,
CallM():执行M指令,返回结果,
Callc():执行c指令,返回结果,
Calls():执行s指令,返回结果,
Callz():执行z指令,返回结果,
CallZ():执行Z指令,返回结果。
这些接口函数的实现用到了如下函数:
Pack():根据RSP协议,为包的内容添置包头包尾,
SetWord():通过EJTAG TAP设置一个32位EJTAG寄存器的值,返回值为0;
GetWord():通过EJTAG TAP接口取得一个32位EJTAG寄存器的值,返回寄存器的值,
IsDigit():判断一个字符是否代表一个十六进制数字,是则返回值1,非则返回值,
SendSignal():通过并口将信号发送到EJTAG TAP接口并接受反馈;
对于运行在Linux系统下的高级语言级即原码级调试器,它的前端采用GDB,后端通过下述的EJTAG驱动程序模块与上述EJTAG/JTAG信号转换及处理模块接口:
d.EJTAG驱动程序模块,实现了开始调试、结束调试、发送调试请求、读取调试响应四项功能;它与上述EJTAG/JTAG信号转换及处理模之间进行的调试命令的交换自然也是采用GDB的RSP协议格式,这使得汇编级调试器和原码级调试器共享EJTAG/JTAG信号转换及处理模块;该EJTAG驱动程序采用可装载的内核模块的方式:用insmod命令装入该模块,用rmmod命令卸载该模块;在EJTAG模块装入Linux系统以后,建立了一个设备/dev/ejtag,以符合GDB的串口调试的要求;
(3)运行于Windows系统下的汇编级调试器的执行过程:
a.通过函数OnOpenDocument()将反汇编格式的被调试目标代码装入内存,
b.通过函数OnDraw()以不同颜色显示代码,
c.若需要,通过函数OnDownload()将代码下载到目标机,
d.根据需要,通过函数OnEditBrk(),OnEditMem(),OnEditReg(),OnRestart(),OnSingleStep(),OnRemoveBreakPoint()实现添加断点,得到并显示指定地址内存的内容,得到并显示所有寄存器的值,重启CPU,发送单步操作命令并获得单步操作后寄存器的值,移除断点的操作,
e.通过GUI重复以上过程,或退出调试器;
(4)运行于Linux系统下的高级语言级调试器的执行过程:
a.用insmod命令装入EJTAG驱动程序模块,
b.通过GDB命令实现需要完成的调试操作,
c.重复步骤b,或退出GDB,
d.用rmmod命令卸载EJTAG驱动程序模块;
(5)对于运行于Windows系统下的汇编级调试器,调试请求处理模块的主函数CallAPI()对步骤(3)中遇到的调试命令的参数及调试操作构成的数据包,利用函数VerifyCommand()和GetFirstChar()对包进行校验及合法性检验,然后再根据GetFirstChar()的返回值分别调用Callxxx()所代表的EJTAG/JTAG信号转换及处理模块给出的CallR(),Callg(),CallG(),Callm(),CallM(),Callc(),Calls(),Callz(),CallZ()等函数,再返回调试结果;
(6)类似地,对于运行于Linux系统下的高级语言级调试器,连接GDB的EJTAG驱动程序模块使GDB发出的调试命令分别调用EJTAG/JTAG信号转换及处理模块给出的CallR(),Callg(),CallG(),Callm(),CallM(),Callc(),Calls(),Callz(),CallZ()等函数,再返回调试结果;
(7)对于运行于Windows系统下的汇编级调试器以及运行于Linux系统下的高级语言级调试器,二者共用的EJTAG/JTAG信号转换及处理模块给出CallR(),Callg(),CallG(),Callm(),CallM(),Callc(),Calls(),Callz(),CallZ()等函数的实现,实现过程用到上述包括Pack(),SetWord(),GetWord(),IsDigit(),SendSignal()的函数;
(8)函数CallR()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.将EJTAG控制寄存器即ECR寄存器中的复位标志位Rocc置0,以及EJTAG中断请求位EjtabBrk,虚拟内存段dseg(debug segment)有效位ProbEn,和调试例外向量地址控制位ProbTrap皆置1;
c.设置调试例外程序计数器(DEBUG Exception Program Counter)DEPC的值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回“”;
(9)函数Callg()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.通过Store指令得到32个通用寄存器的数值;
c.通过MFC0,Store指令得到27个cp0寄存器的数值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回通用寄存器和cp0寄存器的内容;
(10)函数CallG()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.通过Load,MTC0指令设置27个cp0寄存器的数值;
c.通过Load指令设置32个通用寄存器的数值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回“OK”;
(11)函数Callm()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.将内存内容Load到通用寄存器;
c.通过Store指令得到通用寄存器的数值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回内存内容;
(12)函数CallM()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.通过Load指令得到通用寄存器的数值;
c.将通用寄存器数值Store到内存中去;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回“OK”;
(13)函数Callc()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.清除Debug寄存器中的SSt位;
c.设置调试例外程序计数器DEPC的值;
d.填入DERET指令;
e.调用Callg()得到寄存器内容;
f.如b,c,d,e执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
g.返回结果;
(14)函数Calls()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.清除Debug寄存器中的SSt位;
c.设置调试例外程序计数器DEPC的值;
d.填入DERET指令;
e.调用Callg()得到寄存器内容;
f.如b,c,d,e执行过程出错(Roee被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
g.返回结果;
(15)函数Callz()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.断点对应的指令断点状态寄存器中的IBC域中的标志位ASIDuse置为0,BE置为1,若为数据断点,还需设置数据断点状态寄存器DBC域中的标志位BAL置为0,BLM置为1;
c.设置断点对应的指令断点状态寄存器中的IBA域;
d.设置断点对应的指令断点状态寄存器中的IBM域;
e.如b,c,d执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
g.返回“OK”;
(16)函数CallZ()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.断点对应的指令断点状态寄存器中的IBC域中的标志位BE置为0;
c.如b执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
d.返回“OK”;
(17)上述(8)到(16)所述的EJTAG/JTAG信号转换及处理过程把相应的调试请求转换成为一个机器指令的序列,然后通过TAP接口一条一条地送给CPU执行,并取回结果内容,进行打包后返回;根据TAP的控制流程,在调试器命令的处理过程中,TAP寄存器的读写是在Shift-DR/Shift-IR状态进行的,数据在TCK时钟下降沿串行从TDO移出,在上升沿串行从TDI移入;在写TAP寄存器时,忽略从TDO移出的数据,新数据从TDI移入;读TAP寄存器时保存从TDO移出的数据,以供返回,同时将其再从TDI移入;
(18)调试命令的完成需要与目标机CPU进行配合,其基本工作过程为:
a.调试器循环检测ECR寄存器的PrAcc位,若为0,继续检测;若为1,表示处理器已经完成请求的操作而暂停,转b;
b.调试器根据运行的状态,决定下一步动作:
·如果是等待CPU中断,表示CPU已进入调试例外处理,等待例外处理的代码;那么把特定指令放入TAP的DATA寄存器;
·如果是刚让CPU执行了load/store指令,并且操作数地址位于dseg段,那么需要提供操作数(load指令,往TAP的DATA寄存器写),或者读出数据(store指令,从TAP的DATA寄存器读);
c.调试器把ECR的PrAcc位置为0,表示调试器就绪,CPU可以继续;
d.转a;
(19)上述(8)到(16)返回结果最终会反映到用户界面,之后调试器的运行过程如(3)、(4)所述。
本发明的特点与效果
(1)国内未见有关基于EJTAG/JTAG调试器设计工作的报道
片上调试技术(主要有JTAG和BDM两类规范)的实现与CPU或其它处理器芯片的设计是不可分割的,自行研制片上调试器的工作在国内未见报道。进一步,基于EJTAG的片上调试技术只适用于MIPS系列体系结构的微处理器,然而在国内开展此类体系结构的微处理器研究工作只有清华大学的THUMP系列和中科院计算所的龙芯系列,我们研制的基于EJTAG交叉调试器是专为前者配套完成的,在CPU、开发板及系统软件的调试中发挥了很大作用。
(2)调试命令的处理与EJTAG信号相互转换部分运行于宿主机
本发明提出的利用软件有效控制和使用目标机上的EJTAG部件的方案体现在:调试器命令的处理过程全部运行于宿主机。
国外已有的基于EJTAG调试器的产品,需要在CPU和宿主机之间增加一个硬件实现的仿真器。图17是Abatron公司的BDI系列EJTAG调试器示意图。其中调试命令的处理与EJTAG信号相互转换部分是一个硬件实现的仿真设备BDI2000,它位于宿主机调试器和目标机之间,实现的功能是调试协议的转换,也就是把宿主机的调试请求转换成BDM/EJTAG格式,发送给目标机;然后接收目标机的相应信息,转换成宿主机调试器要求的格式返回给宿主机的调试器。该产品它在国内的售价为3万多人民币。相比较,在我们设计的EJTAG调试器中,调试命令的处理与EJTAG信号相互转换部分也是在宿主机完成的,这对于用户来说在性能/价格比、适应性及可移植性方面是完全不同的选择。
(3)良好的适应性
根据该方案,宿主机与目标机之间通过并口链接,只需要4~5根信号线。在开发板上只需引线插口,无需实现任何附加逻辑,因此具有良好的适应性,同时降低了成本。
相比较,在Abatron公司的方案中,宿主机与目标机之间增加了设备BDI2000。宿主机通过串口或以太网连接到BDI2000;而它在连接到目标机时,对于开发板的要求除了实现特定的EJTAG引线逻辑外,还需提供对电源供给的支持。
(4)良好的可移植性
根据该方案,调试协议的转换工作全部在宿主机端完成,支持不同的目标机系统只需要修改少量的代码,在可移植性方面明显优于现有的基于硬件仿真器的方法。
相比较,Abatron公司的BDI2000在向不同的目标系统移植时,需要更新固件,同时驱动程序和配置文件也少不了会改动,可移植性不够理想。在调研该产品时,发现其要满足我们自己的CPU研制,需要Abatron公司本部的密切配合才有可能,其在国内代理无法做到这一步。正因为此,我们才下决心开展了自主研发基于EJTAG调试器的工作。
附图说明
图1.带有EJTAG功能的CPU。
图2.调试器的体系结构。
图3.TAP状态转换图。
图4.汇编级调试用例图。
图5.调试请求处理流程图。
图6.EJTAG/JTAG信号转换及处理。
图7.R指令的处理。
图8.g指令的处理。
图9.G指令的处理。
图10.m指令的处理。
图11.M指令的处理。
图12.c指令的处理。
图13.s指令的处理。
图14.z指令的处理。
图15.Z指令的处理。
图16.源码级调试器的驱动程序体系结构。
图17.Abatron公司的BDI系列EJTAG调试器示意图。
图18本发明所述方案的各主要模块之间的调用关系(左为Windows环境下汇编级调试过程,右为Linux环境下源级调试)。
图19.图18中人机界面模块的程序流程。
图20.图19中OnOpenDocument()函数的处理流程。
图21.图19中OnDownload()函数的处理流程。
图22.图19中OnDraw()函数的处理流程。
图23.图19中OnEditBrk()函数的处理流程。
图24.图19中OnEditMem()函数的处理流程。
图25.图19中OnEditReg()函数的处理流程。
图26.图19中OnRestart()函数的处理流程。
图27.图19中OnSingleStep()函数的处理流程。
图28.图19中OnRemoveBreakPoint()函数的处理流程。
图29调试请求处理模块中使用的模块(函数)之间的调用关系。
图30图29中CallAPI()函数的处理流程。
图31图29中VerifyCommand()函数的处理流程。
图32 EJTAG模块的装载和卸载流程图:a.装载b.卸载。
具体实施方式
根据本发明实现的基于EJTAG的交叉调试器的体系结构如图2所示,其中实线方框部分表示自行实现的主要功能模块:汇编级调试器包括三个:人机界面模块、调试请求处理模块和EJTAG/JTAG信号转换及处理模块;高级语言级调试器包括两个:连接GDB的EJTAG驱动程序模块和EJTAG/JTAG信号转换及处理模块;其中,EJTAG/JTAG信号转换及处理模块为二者共用。
各模块之间的调用关系如图18所示。
各模块的主要功能、工作原理和过程分别介绍如下:
(1)汇编级调试器人机界面模块。
汇编级调试在Windows环境实现,采用GUI界面,操作容易、直观。它提供如下的操作界面(菜单、或者快捷按钮):开始调试/复位CPU、下载代码到目标机、装入源代码;设置断点、删除断点、查看断点;单步执行、继续执行;查看寄存器、修改寄存器;查看内存、修改内存等。其用例图如图4所示。
反汇编代码中有指令的地址,因此可以根据指令计数器PC(Program Counter)值定位当前行,将其显示在界面上。这也是我们使用反汇编代码而不是汇编源代码进行调试的缘故,因为汇编源代码里面没有地址信息。
(2)调试请求处理模块。
调试请求处理模块的功能通过调用下层的EJTAG/JTAG信号转换及处理模块,给人机界面提供断点管理、寄存器和内存查询修改等应用程序接口API函数。它把人机界面的调试请求转换成为符合Remote Serial Protocol协议的数据包,发送给EJTAG/JTAG信号转换及处理模块,然后接収其响应,从而完成相应的功能。其各个功能的处理流程都类似,如图5所示。
(3)EJTAG/JTAG信号转换及处理模块。
如图6的虚线以下部分所示,该模块的主要功能包括:读写CPU寄存器、读写目标机内存和读写TAP寄存器。
人机界面和调试功能处理模块向EJATAG信号转换及处理模块传递的调试命令格式如表2所示。利用EJTAGTAP接口实现调试器的9条命令(R,g,G,m,M,c,s,z,Z)的处理流程分别见图7,图8,图9,图10,图11,图12,图13,图14,图15;分别对应9个函数模块CallR,Callg,CallG,Callm,CallM,Callc,Calls,Callz和CallZ;出错代号E02表示执行过程中出错,出错代号E03表示指令格式错误。
(4)连接GDB的EJTAG驱动程序模块。高级语言级调试器的前端采用GDB,后端通过驱动程序和EJTAG/JTAG信号转换及处理模块接口。EJTAG驱动程序采用可装载的内核模块(loadable kernel module)的方式。当需要EJTAG调试的时候,用insmod命令装入该模块,不需要以后,可用rmmod命令卸载该模块,节约系统资源。EJTAG模块装入Linux系统以后,建立一个设备/dev/ejtag,它符合GDB的串口调试的要求。实现对接的主要工作包括:(1)驱动程序和操作系统的接口;和(2)符合GDB远程调试要求的接口。其驱动程序的体系结构如图16所示。
                表2向EJATAG信号转换及处理模块传递的调试命令格式
    功能     Command
    Read All regs     G
    Write all regs     Gxx(xx表示所有通用寄存器内容,按寄存器号码递增顺序排列。每个32位寄存器占4个字节,按从高位到低位顺序排列。注意:xx总共4*num个字节。)
    Read Memory     maddr,length(addr代表起始地址,length代表长度,以字节为单位,这两个值都应该是4的整数倍)
    WriteMemory     Maddr,length:xx(addr代表起始地址,length代表长度,以字节为单位,这两个值都应该是4的整数倍,xx总共4*length个字节)
    restart     Raddr(addr代表CPU中断后执行的起始地址,应为4的整数倍)
    Continue继续     caddr(addr代表清除单步标志后继续执行的起始地址,应为4的整数倍,也可缺省为空,表示从当前地址继续执行)
    Step单步     saddr(addr代表开始单步执行的起始地址,应为4的整数倍,也可缺省为空,表示从当前地址开始单步执行)
 insertbreakpoint     ztype,addr,length(type:0->指令断点#11->指令断点#22->数据断点写内存3->数据断点读内存4->数据断点读写内存该指令表示设某一地址范围为断点,addr表示起始地址,length表示范围长度,两者均应为4的整数倍)
 removebreakpoint     Ztype,addr,length(type:0->指令断点#11->指令断点#22->数据断点写内存3->数据断点读内存4->数据断点读写内存该指令表示取消某一地址范围的断点,addr表示起始地址,length表示范围长度,两者均应为4的整数倍)
各模块的结构及详细设计如下:
(1)汇编级调试器人机界面
图19中描述了程序执行流程,首先由BOOL CdebuggerDoc∷OnOpenDocument(LPCTSTR lpszPathName)读取汇编源码,再由void CDebuggerView∷OnDraw(CDC*pDC)将源码按一定格式显示出来,然后由其他函数实现各种调试功能。各模块(函数)分别说明如下:
模块(函数)说明:BOOL CDebuggerDoc∷OnOpenDocument(LPCTSTR lpszPathName)
功能描述      :将汇编源码读入内存,做一定处理,并设定以下变量之值:
int m_LineCount;∥存储每行代码的长度
char*m_charbuffer[MAXLINE];∥存储代码
int m_currentLine[MAXLINE];∥当前行flag,1表示为当前
∥行,0表示非当前行
int m_breakPoint[MAXLINE];∥断点表,存储断点信息,0表
∥示无断点,非0表示有断点,相应数字即为断点类型
int m_codeLine[MAXLINE];。∥代码行flag,1表示为代码行,
∥0表示非代码行(注释等)
参数表        :LPCTSTR lpszPathName:指向汇编文件的指针
返回值        :正常结束时返回TRUE,否则返回FALSE
处理流程:见图20
错误信息      :TRUE---读取文件成功   FALSE----读取文件失败
模块(函数)名  :void CDebuggerView∷OnDownload()
功能描述      :得到指定地址内存的内容,并将其显示
处理流程:见图21
模块(函数)说明:void CDebuggerView∷OnDraw(CDC*pDC)
功能描述      :显示代码,并根据是否当前行,是否注释,是否断点等条件显示不同的颜色
参数表        :CDC*pDC:指向当前view类的指针
处理流程:见图22
模块(函数)说明:void CDebuggerView∷OnEditBrk()
功能描述      :添加断点,向接口发出断点指令
处理流程      :见图23
模块(函数)名  :void CDebuggerView∷OnEditMem()
功能描述      :得到指定地址内存的内容,并将其显示
处理流程      :见图24
模块(函数)名  :void CDebuggerView∷OnEditReg()
功能描述      :得到所有寄存器的值,并将其显示
处理流程:见图25
模块(函数)名  :void CDebuggerView∷OnRestart()
功能描述      :发送重启指令,重启CPU
处理流程:见图26
模块(函数)名  :void CDebuggerView∷OnSingleStep()
功能描述      :单步操作,发送单步命令,并获得单步操作后寄存器的值。
处理流程:见图27
备注:此函数流程比较复杂,是由目标机的硬件特性所导致。在EJTAG标准中,如果当前行有断点,在不将断点移除的条件下,所有继续程序的指令(包括single step,continue等)都无法运行,所以进行单步前,要增加移除断点的步骤。而在正常使用程序的习惯中,断点运行过以后应该仍然存在,而不是消失,所以在单步后又在原处将断点添加,以符合人们的使用习惯。
模块(函数)名  :void CDebuggerView∷OnRemoveBreakPoint()
功能描述      :移除断点
处理流程:见图28
(2)调试请求处理模块。
图29为调试请求处理模块中使用的模块(函数)之间的调用关系。其中:Callxxx()代表CallR(),Callg(),CallG(),Callm(),CallM(),Callc(),Calls(),Callz(),CallZ()9个函数,因其执行过程大致相仿,调用函数相同(参见EJTAG/JTAG信号转换及处理模块),故写作Callxxx()便于表达。Callxxx()的处理流程在EJTAG/JTAG信号转换及处理模块中说明。其它的模块(函数),包括Callxxx()用到的模块(函数)分别说明如下:
    模块(C函数)名  :char*CallAPI(char*command)
    功能描述       :通过EJTAG TAP接口执行从人机界面传来的调试命令,
把执行结果返回给人机界面
参数表    :command:从人机界面接受的调试命令
返回值    :返回给人机界面的调试结果
处理流程:见图30
错误信息  :E00----指令包破损    E01----无法识别的指令
    模块(C函数)名  :int VerifyCommand(char* &command)
    功能描述       :验证指令包是否合法,并从指令包中提取有用部分
参数表    :command:指令包,VerifyCommand()结束后,包头包尾被去掉(如,指令包$Rbfc00000#?经VerifyCommand()后变为Rbfc00000)
返回值    :0
处理流程:见图31
处理流程:
错误信息  :-1表示指令包不合法
    模块(C函数)名  :char GetFirstChar(char* &command)
    功能描述       :取出指令的第一个字符
参数表    :command:指令,GetFirstChar()结束后,第一个字符被去掉(如,指令Rbfc00000经GetFirstChar()后变为bfc00000)
返回值    :command的第一个字符
    模块(C函数)名  :char*StrFreeCpy(char*s,int first,int length)
    功能描述       :复制串s从first开始长度为length的一个子串,并返回
参数表    :s:字符串,first:整数,length:整数
返回值    :串s从first开始长度为length的一个子串
    模块(C函数)名   :int IsDigit(char c)
    功能描述        :判断一个字符是否代表一个十六进制数字
参数表    :c:待判断的字符
返回值    :1
错误信息  :0----该字符不代表十六进制数字
    模块(C函数)名  :char*pack(char*content)
    功能描述       :打包函数,为包的内容添置包头包尾,包的格式遵从Remote Serial Protocol;(在CdebuggerView类的生成Command功能时也用到)
参数表    :content:包的内容
返回值    :打包后的内容
    模块(C函数)名  :int GetWord(int IR)
    功能描述       :通过EJTAGTAP接口取得一个32位EJTAG寄存器的值
参数表    :IR:EJTAG寄存器对应的IR
返回值    :寄存器的值
处理流程  :设置信号格式存放于字符数组中,通过SendSignal()函数从并口发送到EJTAGTAP接口
    模块(C函数)名  :int SetWord(int IR)
    功能描述       :通过EJTAG TAP接口取得一个32位EJTAG寄存器的值
参数表    :IR:EJTAG寄存器对应的IR
返回值    :0
处理流程  :设置信号格式存放于字符数组中,通过SendSignal()函数从并口发送到EJTAGTAP接口
    模块(C函数)名  :int SendSignal(int lenOfSignal,char*signal)
    功能描述       :通过并口将信号发送到EJTAG TAP接口并接受反馈
参数表    :IR:EJTAG寄存器对应的IR
返回值    :0
处理流程  :EJTAGTAP接口反馈值
注:指令执行结果及出错信息的返回值在返回人机界面前均经pack()函数打包
(3)EJTAG/JTAG信号转换及处理模块。
需处理的9条命令(R,g,G,m,M,c,s,z,Z)的处理流程分别见图7,图8,图9,图10,图11,图12,图13,图14,图15;分别对应9个函数模块CallR,Callg,CallG, Callm,CallM,Callc,Calls,Callz和CallZ;对应的函数接口定义分别为:
    模块(C函数)名  :char*CallR(char*command)
    功能描述       :执行R指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :执行成功----返回“”
处理流程:见图7
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*Callg(char*command)
    功能描述       :执行g指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :寄存器内容(通用寄存器和cp0)
处理流程  :见图8
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*CallG(char*command)
    功能描述       :执行G指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :OK
处理流程  :见图9
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*Callm(char*command)
    功能描述       :执行m指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :OK
处理流程:见图10
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*CallM(char*command)
    功能描述       :执行M指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :OK
处理流程:见图11
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*Callc(char*command)
    功能描述       :执行c指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :参见表2
处理流程:见图12
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*Calls(char*command)
    功能描述       :执行s指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :参见表2
处理流程:见图13
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*Callz(char*command)
    功能描述       :执行z指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :OK
处理流程:见图14
错误信息  :E02----执行过程中出错    E03----指令格式错误
    模块(C函数)名  :char*CallZ(char*command)
    功能描述  :执行Z指令,返回结果
参数表    :command:指令(不包括第一个字符)
返回值    :OK
处理流程:见图15
错误信息  :E02----执行过程中出错    E03----指令格式错误
(4)连接GDB的EJTAG驱动程序模块。
驱动程序实现了开始调试、结束调试、发送调试请求、读取调试响应四项功能,其处理过程如下:
(a)开始调试:
向Linux Kernel申请I/O地址范围
复位目标机
读取CPU实现的硬件断点、软件断点数量
(b)结束调试:
释放I/O地址范围
(c)发出调试请求:
校验、分析调试请求
处理调试请求
处理的结果放入结果缓冲区
(d)读取调试响应:
循环测试是否已有结果
if(已有结果)
从结果缓冲区读取处理结果
驱动程序和操作系统的接口就是EJTAG模块的装载和卸载,如图32所示。

Claims (1)

1.基于目标机上的EJTAG部件的交叉调试器实现方法,其特征在于:调试命令的处理过程是全部在宿主PC机上运行的,它包含以下步骤:
(1)使扩展了EJTAG部件的目标机MIPS CPU中的测试访问端口即Test Access Port简称TAP接口的由IEEE技术委员会联合测试行动小组Joint Test Action Group简称JTAG制定的IEEEE1149.1工业标准中的下述5个JTAG信号通过信号线与宿主机PC的并行I/O端口相连:
TCK即测试时钟Test Clock信号,方向从宿主PC机到目标机MIPS CPU;
TMS即测试方式选择Test Mode Select信号,方向从宿主PC机到目标机MIPS CPU;
TDI即测试数据输入Test Data Input信号,方向从宿主PC机到目标机MIPS CPU;
TDO即测试数据输出Test Data Output信号,方向从目标机MIPS CPU到宿主PC机;
TRST*即测试复位Test Reset Input*信号,它是可选信号;
(2)在宿主PC机的存储器上建立以下模块:
对于运行在Windows系统下的汇编级调试器,它建有以下模块:
a.人机界面模块,采用图形用户接口GUI界面,被调试目标代码的显示格式使用反汇编代码,它通过以下函数来提供操作界面:
OnOpenDocument():把反汇编显示格式的代码读入内存,并设定以下变量之值:
存储每行代码的长度,
存储代码,
当前行特征位flag,1表示为当前行,0表示非当前行,
断点表,存储断点信息,0表示无断点,非0表示有断点,相应数字即断点类型,
代码行特征位flag,1表示为代码行,0表示非代码行(注释等);
OnDownload():下载Motorola的S-记录即S-Record格式的代码到目标机指定地址开始的存储区域;
OnDraw():以不同颜色显示代码;
OnEditBrk():添加断点,向接口发出断点指令;
OnEditMem();得到并显示指定地址内存的内容;
OnEditReg();得到并显示所有寄存器的值;
OnRestart();发送重启指令,重启CPU;
OnSingleStep();发送单步操作命令,并获得单步操作后寄存器的值;
OnRemoveBreakPoint();移除断点;
Pack():根据RSP协议,为包的内容添置包头包尾,
b.调试请求处理模块,它是上层的人机界面模块和下层的EJTAG/JTAG信号转换及处理模块的应用程序API,它把人机界面的调试请求转换成为符合Remote Serial Protocol协议的数据包,发送给EJTAG/JTAG信号转换及处理模块,再接収其响应,后者设有以下9类调试命令:
Callg():读所有的寄存器,简称g,
CallG():写入所有的寄存器,简称G,
Callm():读存储器,简称m,
CallM():写存储器,简称M,
CallR():复位,发出CPU中断后执行的起始地址,简称R,
Callc():继续,发出清除单步标志后继续执行的起始地址,简称c,
Calls():单步操作,发出开始单步执行的起始地址,简称s,
Callz():插入断点,设定某一地址范围为断点,简称z,
CallZ():移除断点,取消某一地址范围的断点,简称Z;
相应地,调试请求处理模块设定以下各个调试请求所用到的函数:
CallAPI():通过EJTAG TAP接口执行从人机界面传来的调试命令,据此调试命令分别调用由下层的EJTAG/JTAG信号转换及处理模块给出的以上9类调试命令,再返回调试结果,
VerifyCommand():验证指令包是否合法,并从中提取有用部分,
GetFirstChar():提取指令的第一个字符,
StrFreeCpy():拷贝一个串;
c.EJTAG信号转换及处理模块,它把RSP格式的调试命令请求转换为JTAG信号,使得与目标机CPU的处理过程同步,并返回响应信息,相应于上述需要处理的调试命令,它对应地设有以下接口函数:
CallR():执行R指令,返回结果,
Callg():执行g指令,返回结果,
CallG():执行G指令,返回结果,
Callm():执行m指令,返回结果,
CallM():执行M指令,返回结果,
Callc():执行c指令,返回结果,
Calls():执行s指令,返回结果,
Callz():执行z指令,返回结果,
CallZ():执行Z指令,返回结果;
这些接口函数的实现用到了如下函数:
Pack():根据RSP协议,为包的内容添置包头包尾,
SetWord():通过EJTAG TAP设置一个32位EJTAG寄存器的值,返回值为0;
GetWord():通过EJTAG TAP接口取得一个32位EJTAG寄存器的值,返回寄存器的值,
IsDigit():判断一个字符是否代表一个十六进制数字,是则返回值1,非则返回值,
SendSignal():通过并口将信号发送到EJTAG TAP接口并接受反馈;
对于运行在Linux系统下的高级语言级即原码级调试器,它的前端采用GDB,后端通过下述的EJTAG驱动程序模块与上述EJTAG/JTAG信号转换及处理模块接口:
d.EJTAG驱动程序模块,实现了开始调试、结束调试、发送调试请求、读取调试响应四项功能;它与上述EJTAG/JTAG信号转换及处理模之间进行的调试命令的交换自然也是采用GDB的RSP协议格式,这使得汇编级调试器和原码级调试器共享EJTAG/JTAG信号转换及处理模块;该EJTAG驱动程序采用可装载的内核模块的方式:用insmod命令装入该模块,用rmmod命令卸载该模块;在EJTAG模块装入Linux系统以后,建立了一个设备/dev/ejtag,以符合GDB的串口调试的要求;
(3)运行于Windows系统下的汇编级调试器的执行过程:
a.通过函数OnOpenDocument()将反汇编格式的被调试目标代码装入内存,
b.通过函数OnDraw()以不同颜色显示代码,
c.若需要,通过函数OnDownload()将代码下载到目标机,
d.根据需要,通过函数OnEditBrk(),OnEditMem(),OnEditReg(),OnRestart(),OnSingleStep(),OnRemoveBreakPoint()实现添加断点,得到并显示指定地址内存的内容,得到并显示所有寄存器的值,重启CPU,发送单步操作命令并获得单步操作后寄存器的值,移除断点的操作,
e.通过GUI重复以上过程,或退出调试器;
(4)运行于Linux系统下的高级语言级调试器的执行过程:
a.用insmod命令装入EJTAG驱动程序模块,
b.通过GDB命令实现需要完成的调试操作,
c.重复步骤b,或退出GDB,
d.用rmmod命令卸载EJTAG驱动程序模块;
(5)对于运行于Windows系统下的汇编级调试器,调试请求处理模块的主函数CallAPI()对步骤(3)中遇到的调试命令的参数及调试操作构成的数据包,利用函数VerifyCommand()和GetFirstChar()对包进行校验及合法性检验,然后再根据GetFirstChar()的返回值分别调用Callxxx()所代表的EJTAG/JTAG信号转换及处理模块给出的CallR(),Callg(),CallG(),Callm(),CallM(),Callc(),Calls(),Callz(),CallZ()等函数,再返回调试结果;
(6)类似地,对于运行于Linux系统下的高级语言级调试器,连接GDB的EJTAG驱动程序模块使GDB发出的调试命令分别调用EJTAG/JTAG信号转换及处理模块给出的CallR(),Callg(),CallG(),Callm(),CallM(),Callc(),Calls(),Callz(),CallZ()等函数,再返回调试结果;
(7)对于运行于Windows系统下的汇编级调试器以及运行于Linux系统下的高级语言级调试器,二者共用的EJTAG/JTAG信号转换及处理模块给出CallR(),Callg(),CallG(),Callm(),CallM(),Callc(),Calls(),Callz(),CallZ()等函数的实现,实现过程用到上述包括Pack(),SetWord(),GetWord(),IsDigit(),SendSignal()的函数;
(8)函数CallR()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.将EJTAG控制寄存器即ECR寄存器中的复位标志位Rocc置0,以及EJTAG中断请求位EjtabBrk,虚拟内存段dseg(debug segment)有效位ProbEn,和调试例外向量地址控制位ProbTrap皆置1;
c.设置调试例外程序计数器(DEBUG Exception Program Counter)DEPC的值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回“”;
(9)函数Callg()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.通过Store指令得到32个通用寄存器的数值;
c.通过MFC0,Store指令得到27个cp0寄存器的数值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回通用寄存器和cp0寄存器的内容;
(10)函数CallG()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.通过Load,MTC0指令设置27个cp0寄存器的数值;
c.通过Load指令设置32个通用寄存器的数值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回“OK”;
(11)函数Callm()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.将内存内容Load到通用寄存器;
c.通过Store指令得到通用寄存器的数值;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回内存内容;
(12)函数CallM()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.通过Load指令得到通用寄存器的数值;
c.将通用寄存器数值Store到内存中去;
d.如b,c执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
e.返回“OK”;
(13)函数Callc()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.清除Debug寄存器中的SSt位;
c.设置调试例外程序计数器DEPC的值;
d.填入DERET指令;
e.调用Callg()得到寄存器内容;
f.如b,c,d,e执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
g.返回结果;
(14)函数Calls()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.清除Debug寄存器中的SSt位;
c.设置调试例外程序计数器DEPC的值;
d.填入DERET指令;
e.调用Callg()得到寄存器内容;
f.如b,c,d,e执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
g.返回结果;
(15)函数Callz()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.断点对应的指令断点状态寄存器中的IBC域中的标志位ASIDuse置为0,BE置为1,若为数据断点,还需设置数据断点状态寄存器DBC域中的标志位BAL置为0,BLM置为1;
c.设置断点对应的指令断点状态寄存器中的IBA域;
d.设置断点对应的指令断点状态寄存器中的IBM域;
e.如b,c,d执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
f.返回“OK”;
(16)函数CallZ()的处理过程:
a.检查指令格式是否正确,若不正确则返回,并置出错标志;
b.断点对应的指令断点状态寄存器中的IBC域中的标志位BE置为0;
c.如b执行过程出错(Rocc被置为1,处理器未处于预期的暂停状态),则返回,并置出错标志;
d.返回“OK”;
(17)上述(8)到(16)所述的EJTAG/JTAG信号转换及处理过程把相应的调试请求转换成为一个机器指令的序列,然后通过TAP接口一条一条地送给CPU执行,并取回结果内容,进行打包后返回;根据TAP的控制流程,在调试器命令的处理过程中,TAP寄存器的读写是在Shift-DR/Shift-IR状态进行的,数据在TCK时钟下降沿串行从TDO移出,在上升沿串行从TDI移入;在写TAP寄存器时,忽略从TDO移出的数据,新数据从TDI移入;读TAP寄存器时保存从TDO移出的数据,以供返回,同时将其再从TDI移入;
(18)调试命令的完成需要与目标机CPU进行配合,其基本工作过程为:
a.调试器循环检测ECR寄存器的PrAcc位,若为0,继续检测;若为1,表示处理器已经完成请求的操作而暂停,转b;
b.调试器根据运行的状态,决定下一步动作:
·如果是等待CPU中断,表示CPU已进入调试例外处理,等待例外处理的代码;那么把特定指令放入TAP的DATA寄存器;
·如果是刚让CPU执行了load/store指令,并且操作数地址位于dseg段,那么需要提供操作数(load指令,往TAP的DATA寄存器写),或者读出数据(store指令,从TAP的DATA寄存器读);
c.调试器把ECR的PrAcc位置为0,表示调试器就绪,CPU可以继续;
d.转a;
(19)上述(8)到(16)返回结果最终会反映到用户界面,之后调试器的运行过程如(3)、(4)所述。
CNB2004100090019A 2004-04-02 2004-04-02 基于目标机上的ejtag部件的交叉调试器实现方法 Expired - Fee Related CN1312588C (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CNB2004100090019A CN1312588C (zh) 2004-04-02 2004-04-02 基于目标机上的ejtag部件的交叉调试器实现方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CNB2004100090019A CN1312588C (zh) 2004-04-02 2004-04-02 基于目标机上的ejtag部件的交叉调试器实现方法

Publications (2)

Publication Number Publication Date
CN1564136A true CN1564136A (zh) 2005-01-12
CN1312588C CN1312588C (zh) 2007-04-25

Family

ID=34477762

Family Applications (1)

Application Number Title Priority Date Filing Date
CNB2004100090019A Expired - Fee Related CN1312588C (zh) 2004-04-02 2004-04-02 基于目标机上的ejtag部件的交叉调试器实现方法

Country Status (1)

Country Link
CN (1) CN1312588C (zh)

Cited By (21)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN100392617C (zh) * 2005-04-13 2008-06-04 威盛电子股份有限公司 片上系统与应用于其中的测试/除错方法
CN100452056C (zh) * 2007-06-25 2009-01-14 威盛电子股份有限公司 解析存储器内容的系统及方法
CN101840368A (zh) * 2010-03-26 2010-09-22 中国科学院计算技术研究所 多核处理器的jtag实时片上调试方法及其系统
CN101989222A (zh) * 2010-11-22 2011-03-23 连云港杰瑞深软科技有限公司 一种龙芯仿真器终端
CN102231128A (zh) * 2011-07-06 2011-11-02 青岛海信信芯科技有限公司 在线调试方法及调试主机
CN102567196A (zh) * 2010-12-27 2012-07-11 北京国睿中数科技股份有限公司 一种处理器仿真调试方法及装置
CN102981952A (zh) * 2012-11-06 2013-03-20 无锡江南计算技术研究所 基于目标机器的程序性能分析方法
CN101553792B (zh) * 2006-12-06 2013-11-27 微软公司 虚拟化环境中的经优化的中断传递
CN103488607A (zh) * 2013-09-07 2014-01-01 安徽华东光电技术研究所 嵌入式linux平台下SOC处理器与FPGA芯片的通信系统、方法
WO2015035761A1 (zh) * 2013-09-10 2015-03-19 成都品果科技有限公司 一种对iOS系统进行汇编级动态调试的方法及装置
CN105808423A (zh) * 2016-02-04 2016-07-27 天津橙子科技有限公司 构建基于web工程测试用例编程语言的执行引擎的方法
CN107885652A (zh) * 2016-09-30 2018-04-06 电信科学技术研究院 一种进行软件测试的方法和调试器
CN104899144B (zh) * 2015-06-18 2018-06-15 深圳市新格林耐特通信技术有限公司 一种基于串口中断的调试方法
CN108829591A (zh) * 2018-05-31 2018-11-16 北京理工大学 一种基于Web的协同调试系统及方法
CN109240902A (zh) * 2017-05-27 2019-01-18 腾讯科技(深圳)有限公司 一种获取电子设备的固件代码的方法和装置
CN109891395A (zh) * 2016-10-25 2019-06-14 赛灵思公司 调试系统和方法
CN111555810A (zh) * 2020-04-22 2020-08-18 青岛海信宽带多媒体技术有限公司 一种光模块以及数据传输方法
CN111881636A (zh) * 2020-07-07 2020-11-03 广芯微电子(广州)股份有限公司 一种基于risc-v芯片的仿真调试方法及装置
CN113342649A (zh) * 2021-05-31 2021-09-03 上海创景信息科技有限公司 基于真实目标机实现单元测试的系统、方法、介质和设备
CN114090440A (zh) * 2021-11-21 2022-02-25 广州链安科技有限公司 一种基于安卓操作系统的一体化免源码调试方法
CN114487758A (zh) * 2022-04-18 2022-05-13 江苏邑文微电子科技有限公司 半导体设备的测试方法、测试系统

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101510179B (zh) * 2009-03-17 2013-01-16 中兴通讯股份有限公司 信号传输装置及方法

Family Cites Families (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6145100A (en) * 1998-03-04 2000-11-07 Advanced Micro Devices, Inc. Debug interface including timing synchronization logic
US6367032B1 (en) * 1999-10-21 2002-04-02 Sony Corporation Of Japan Method and system for debugging a microprocessor core
JP2004038464A (ja) * 2002-07-02 2004-02-05 Renesas Technology Corp デバッグ機能内蔵マイクロコンピュータ
CN1243307C (zh) * 2003-06-19 2006-02-22 Ut斯达康(中国)有限公司 通过jtag对单板进行测试的方法以及设备

Cited By (31)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN100392617C (zh) * 2005-04-13 2008-06-04 威盛电子股份有限公司 片上系统与应用于其中的测试/除错方法
CN101553792B (zh) * 2006-12-06 2013-11-27 微软公司 虚拟化环境中的经优化的中断传递
CN100452056C (zh) * 2007-06-25 2009-01-14 威盛电子股份有限公司 解析存储器内容的系统及方法
CN101840368A (zh) * 2010-03-26 2010-09-22 中国科学院计算技术研究所 多核处理器的jtag实时片上调试方法及其系统
CN101840368B (zh) * 2010-03-26 2013-01-16 中国科学院计算技术研究所 多核处理器的jtag实时片上调试方法及其系统
CN101989222A (zh) * 2010-11-22 2011-03-23 连云港杰瑞深软科技有限公司 一种龙芯仿真器终端
CN101989222B (zh) * 2010-11-22 2012-10-03 连云港杰瑞深软科技有限公司 一种龙芯仿真器终端
CN102567196A (zh) * 2010-12-27 2012-07-11 北京国睿中数科技股份有限公司 一种处理器仿真调试方法及装置
CN102231128A (zh) * 2011-07-06 2011-11-02 青岛海信信芯科技有限公司 在线调试方法及调试主机
CN102981952A (zh) * 2012-11-06 2013-03-20 无锡江南计算技术研究所 基于目标机器的程序性能分析方法
CN102981952B (zh) * 2012-11-06 2015-05-20 无锡江南计算技术研究所 基于目标机器的程序性能分析方法
CN103488607A (zh) * 2013-09-07 2014-01-01 安徽华东光电技术研究所 嵌入式linux平台下SOC处理器与FPGA芯片的通信系统、方法
WO2015035761A1 (zh) * 2013-09-10 2015-03-19 成都品果科技有限公司 一种对iOS系统进行汇编级动态调试的方法及装置
CN104899144B (zh) * 2015-06-18 2018-06-15 深圳市新格林耐特通信技术有限公司 一种基于串口中断的调试方法
CN105808423A (zh) * 2016-02-04 2016-07-27 天津橙子科技有限公司 构建基于web工程测试用例编程语言的执行引擎的方法
CN105808423B (zh) * 2016-02-04 2018-11-13 天津橙子科技有限公司 构建基于web工程测试用例编程语言的执行引擎的方法
CN107885652A (zh) * 2016-09-30 2018-04-06 电信科学技术研究院 一种进行软件测试的方法和调试器
CN109891395B (zh) * 2016-10-25 2023-02-14 赛灵思公司 调试系统和方法
CN109891395A (zh) * 2016-10-25 2019-06-14 赛灵思公司 调试系统和方法
CN109240902A (zh) * 2017-05-27 2019-01-18 腾讯科技(深圳)有限公司 一种获取电子设备的固件代码的方法和装置
CN109240902B (zh) * 2017-05-27 2021-03-19 腾讯科技(深圳)有限公司 一种获取电子设备的固件代码的方法和装置
CN108829591A (zh) * 2018-05-31 2018-11-16 北京理工大学 一种基于Web的协同调试系统及方法
CN111555810A (zh) * 2020-04-22 2020-08-18 青岛海信宽带多媒体技术有限公司 一种光模块以及数据传输方法
CN111555810B (zh) * 2020-04-22 2023-08-08 青岛海信宽带多媒体技术有限公司 一种光模块以及数据传输方法
CN111881636B (zh) * 2020-07-07 2021-05-04 广芯微电子(广州)股份有限公司 一种基于risc-v芯片的仿真调试方法及装置
CN111881636A (zh) * 2020-07-07 2020-11-03 广芯微电子(广州)股份有限公司 一种基于risc-v芯片的仿真调试方法及装置
CN113342649A (zh) * 2021-05-31 2021-09-03 上海创景信息科技有限公司 基于真实目标机实现单元测试的系统、方法、介质和设备
CN113342649B (zh) * 2021-05-31 2023-11-14 上海创景信息科技有限公司 基于真实目标机实现单元测试的方法、介质和设备
CN114090440A (zh) * 2021-11-21 2022-02-25 广州链安科技有限公司 一种基于安卓操作系统的一体化免源码调试方法
CN114487758A (zh) * 2022-04-18 2022-05-13 江苏邑文微电子科技有限公司 半导体设备的测试方法、测试系统
CN114487758B (zh) * 2022-04-18 2022-08-16 江苏邑文微电子科技有限公司 半导体设备的测试方法、测试系统

Also Published As

Publication number Publication date
CN1312588C (zh) 2007-04-25

Similar Documents

Publication Publication Date Title
CN1564136A (zh) 基于目标机上的ejtag部件的交叉调试器实现方法
CN100338568C (zh) 开发片上系统用的开发环境的生成方法
CN1279449C (zh) 微处理器
CN1768275A (zh) 测试摸拟装置、测试模组模拟装置以及记录此程式的记录媒体
CN1240005C (zh) 将生产测试接口接至全局串行总线的方法和装置
CN1605058A (zh) 关于嵌入式字段可编程门阵列核心的接口结构
CN1932776A (zh) 嵌入式操作系统中接口测试的自动化运行方法
CN1875345A (zh) 在编译过程中表示和检查程序组件的一致性的可扩展类型系统
CN1472646A (zh) 适应性强具备最佳化功能的编译装置
CN1073276A (zh) 语言的中性对象
CN1647082A (zh) 集成电路的开发方法和存储了集成电路的开发方法的程序存储媒体、以及asic和可编程逻辑器件同时开发系统、开发程序和开发方法
CN1073540A (zh) 管理类方法名
CN1498367A (zh) 信息处理装置、存储器管理装置、存储器管理方法及信息处理方法
CN1809812A (zh) 用于源代码检测源代码中弱点的方法和装置
CN1270348A (zh) 用于结构仿真的动态优化目标码翻译器和翻译方法
CN1244052C (zh) 非易失性存储器微机芯片及其测试方法
CN1991798A (zh) 半导体存储装置
CN1776621A (zh) 程序变换方法
CN1577291A (zh) 程序调试装置、程序调试方法及程序
CN1296825C (zh) 模拟器及模拟方法
CN1198147C (zh) 半导体测试装置及其监视装置
CN1491383A (zh) 使用协处理器的数据处理
CN1293475C (zh) 用指令替换实现单片机仿真的方法及其装置
CN1320650C (zh) 半导体器件、使用其的系统装置及制造半导体器件的方法
CN1529846A (zh) 在以过程语言开发的计算机软件应用程序中的导航

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C14 Grant of patent or utility model
GR01 Patent grant
C19 Lapse of patent right due to non-payment of the annual fee
CF01 Termination of patent right due to non-payment of annual fee