jtag的基本原理与调试原理

网络/协议

43人已加入

描述

  JTAG最初是用来对芯片进行测试的,基本原理是在器件内部定义一个TAP(Test Access Port?测试访问口)通过专用的JTAG测试工具对进行内部节点进行测试。JTAG测试允许多个器件通过JTAG接口串联在一起,形成一个JTAG链,能实现对各个器件分别测试。现在,JTAG接口还常用于实现ISP(In-System Programmable?在线编程),对FLASH等器件进行编程。

  JTAG编程方式是在线编程,传统生产流程中先对芯片进行预编程实现再装到板上因此而改变,简化的流程为先固定器件到电路板上,再用JTAG编程,从而大大加快工程进度。JTAG接口可对PSD芯片内部的所有部件进行编程

  简单地说,JTAG的工作原理可以归结为:在器件内部定义一个TAP(TestAccessPort,测试访问口),通过专用的JTAG测试工具对内部节点进行测试和调试。

  边界扫描

  边界扫描(Boundary-Scan)即在芯片的每个输入输出管脚上都增加一个移位寄存器单元(Boundary-Scan Register Cell),因为这些移位寄存器单元分布在芯片的边界上,所以被称为边界扫描寄存器。在JTAG 调试中,边界扫描是一个很重要的概念,当需要调试芯片时,这些寄存器将芯片与外围电路隔离,实现对芯片输入输出信号的观察和控制:对于输入管脚,可以通过与之相连的边界扫描寄存器单元把数据加载到该管脚中;对于输出管脚,可以通过与之相连的边界扫描寄存器“捕获”(CAPTURE)该管脚上的输出信号;正常运行状态下,这些边界扫描寄存器单元对芯片是透明的,所以正常的运行不会受到影响。另外,芯片输入输出管脚上的边界扫描(移位)寄存器单元可以相互连接起来,在芯片的周围形成一个边界扫描链(Boundary-Scan Chain),它可以串行的输入和输出,通过相应的时钟信号和控制信号,实现对处在调试状态下的芯片的输入和输出状态的观察和控制。

  在CPU外围,处理器内部包含了JTAG的硬件实现,并且向外界提供接口,也就是上面所说的TMS、TCK、TDI、TDO四个引脚。

  这里的CPU:是指运算处理单元,只包含了内部寄存器以及运算单元等基本部件。

  这里的处理器:是指CPU 扩展芯片,不是SoC。

 JTAG

  JTAG如何用于芯片测试呢? 其中用到的最主要部件就是边界扫描链。命名为边界扫描链,是由于它位置处于处理器的边界上。

  我们知道CPU是通过引脚与外围交流的,所有的数据都会通过引脚输入或者输出,而JTAG就是通过监控引脚的信号达到芯片测试的目的。而边界扫描链就是在引脚上的一个部件。如下图:

 JTAG

  通过边界扫描链,当有信号输入的时候,边界扫描链就能获取信号,当CPU要输出信号的时候,边界扫描链也能获取要输出的信号。另外,也可以通过边界扫描链来直接向外部输出信号。

  无论是信号的抓取还是输出,都需要有接口来保存这些信号,TDI 跟 TDO 就是做这样一些工作的。如图:

  JTAG

  本来边界扫描链保存着引脚上的信号,当通过TDI引脚输入我们自己的信号的时候,会发生沿上面红线方向的移位操作,

  TDI ——〉 边界扫描链 —— 〉 TDO

  就能从TDO获取边界扫描链上的信号,我们从TDI输入的信号也会到边界扫描链上去。

  在CPU跟外界通信的引脚上的数据无非就是 指令 跟 数据信号(包括地址跟数据) 两种。但是这两者的结合形成了一个完整的程序,能对它们进行监控就表明我们能进行程序的调试。一般的芯片都会提供几条独立的边界扫描链,对边界扫描链的控制主要是通过 TAP(Test Access Port) Controller来完成的。

  上面的只是jtag最基本的原理,要对程序更好的调试还需要控制部件,还有更多寄存器的结合等等。

  下面是一个完整的jtag调试部件:

  

  下面来讲讲arm上的jtag调试,openocd就是一个jtag的调试工具

  我们在调试程序的时候,通常需要设置断点,断点也就是指令所在的位置,

  断点分为两种:硬件断点跟软件断点

  硬件断点:指令的地址。当cpu要去某个地址取指令的时候,就暂停cpu的运行。在s3c2440上只支持两个硬件断点

  软件断点:软件断点不限制断点的个数,因此硬件断点的方法是不可用的。当我们需要在某个指令上打断点的时候,openocd会先去取得断点的地址,然后把每个断点处的值替换成某个特定的值(如deeedeee),当cpu取数据的时候得到该特定的值,就知道到达了断点地址,暂停cpu的运行,去除断点的时候再把原本的值换回去。如果没指定硬件断点的话,一般都默认是软件断点。

  另外openocd对于软件断点有特定的要求:

  1.程序必须位于它的链接地址上,即如果指定了。 = 0x30000000,那么程序必须实际上是位于0x30000000这个地方,也就是说程序必须已经重定位好,位于它的链接地址。

  2.程序必须按照某种特定的顺序排放:

  SECTIONS{

  。 = 0x30000000;

  .text :{

  head.o(.text)

  init.o(.text)

  nand.o

  *(.text)

  }

  .rodata ALIGN(4) : {*(.rodata)}

  .data ALIGN(4) : {*(.data)}

  .bss ALIGN(4) : {*(.bss) *(COMMON)}

  }

  gdb调试就是基于软件断点的调试,我们可以用gdb对程序代码的某一行进行断点设置,那么它是如何定位到某个指令的地址的?

  这就需要有调试信息,也就是在编译的时候加上 -g 给程序添加调试信息。

  eclipse对gdb进行了进一步的封装(GUI),我们可以通过对eclipse进行某些设置达到调试arm程序的目的。

  1.首先把文件加入工程

  2.设置调试配置:

  点工具栏上的小虫子

  Debug Configurations.。。

  新建一个调试配置

  选择选项卡Main,在C/C++ Application:  选项上选择要调试的elf文件

  选择选项卡Debugger,GDB debugger: 选择为arm-elf-gdb

  选择选项卡Commands, ‘Initialize’conmmands 下输入命令:

  target remote 127.0.0.1:3333    //连接openocd

  load                //加载程序到内存

  break _start            //设置断点到_start

  c        //continue继续执行

  然后Apply ,最后Debug开始调试

  3.当然,上述程序是在内存执行的,但是开发板一开始的时候内存还没初始化,是不可用的,因此我们需要先设置内存

  在openocd的命令控制台上(telnet 127.0.0.1 4444进入openocd控制台)

  halt    //暂停cpu

  load_image  init.bin  0   //加载内存初始化程序 init.bin 到 0 地址

  resume  0    //在0地址开始运行

  halt  //暂停cpu

  然后就可以Debug了

  Debug时,当运行到断点处的时候,我们可以看到某些寄存器或者变量的值,这些值在eclipse上显示:

  JTAG

  测试访问口TAP

  TAP(TestAccessPort)是一个通用的端口,通过TAP 可以访问芯片提供的所有数据寄存器(DR)和指令寄存器(IR)。对整个TAP的控制是通过TAP控制器(TAPController)来完成的。下面先 分别介绍一下TAP的几个接口信号及其作用。其中,前4个信号在IEEE1149.1标准里是强制要求的。

  TCK:时钟信号,为TAP的操作提供了一个独立的、基本的时钟信号。

  TMS:模式选择信号,用于控制TAP状态机的转换。

  TDI:数据输入信号。

  TDO:数据输出信号。

  TRST:复位信号,可以用来对TAPController进行复位(初始化)。这个信号接口在IEEE1149.1标准里并不是强制要求的,因为通过TMS也可以对TAPController进行复位。

  STCK:时钟返回信号,在IEEE1149.1标准里非强制要求。

  简单地说,PC机对目标板的调试就是通过TAP接口完成对相关数据寄存器(DR)和指令寄存器(IR)的访问。

  系统上电后,TAPController 首先进入 Test-LogicReset 状态,然后依次进入Run-Test/Idle、Selcct-DR- Scan、Select-IR-Scan、Capture-IR、Shift-IR、Exitl-IR、Update-IR状态,最后回到 Run- Tcst/Idle 状态。在此过程中,状态的转移都是通过TCK信号进行驱动(上升沿),通过TMS信号对TAP的状态进行选择转换的。其中,

  在 Capture-IR状态下,一个特定的逻辑序列被加载到指令寄存器中;

  在Shift-IR状态下,可以将一条特定的指令送到指令寄存器中;

  在 Update—IR状态下,刚才输入到指令寄存器中的指令将用来更新指令寄存器。

  最后,系统又回到Run—Test/Idle状态,指令生效,完成对指令寄存器的访问。

  当系统又返回到Run—Test/Idle状态后,根据前面指令寄存器的内容选定所需要的数据寄存器,开始执行对数据寄存器的工作。其基本原理与指令寄存器的访问完全相同,依次为seIect—DR—Scan、Capture—DR、Shift—D、Exitl一DR、Update—DR, 最后回到 Run-Tcst/Idle 状态。通过TDl和TDO,就可以将新的数据加载到数据寄存器中。经过一个周期后,就可以捕获数据寄存器中的数据,完 成对与数据寄存器的每个寄存器单元相连的芯片引脚的数据更新,也完成了对数据寄存器的访问。

  

  Keil、IAR、DS-5、ADS开发工具软件等都有一个公共的调试接口RDI,那么我们如何完成 RDI -》JTAG调试协议的转换呢?两种做法:

  在电脑上写一个服务程序,把Keil、IAR、DS-5中的RDI命令解析成相关的JTAG协议,然后通后一个物理转换接口(注意,这个转换只是电气物理层上的转换,就像RS232那样的作用)发送你的的目标板。H-JTAG就是这样的。H-JTAG的硬件就仅是一个物理电平的转换接口,所以很简单。 而电脑中装的H-JTAG软件就是前面说到的服务程序,负责协议转换的。

  做一个板,用此板直接接收来自Keil、IAR、DS-5等软件的调试命令,由此板做RDI -》 JTAG协议的转换。然后与目标板通信,这就是JLINK、ULINK2等仿真器的工作原理。

  由上可以看出,H-JTAG由于是软件作协议转换的,所以速度较慢,但是硬件简单。而第二种方法的JLINK一般带一个强劲的CPU,作硬件协议转换,把以硬件复杂,但速度快。目前,市场上的JTAG接口仿真器有14引脚和20引脚两种。其中,以20引脚为主流标准,但也有少数的目标板采用14引脚。经过简单的信号转换后,可以将它们通用。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分