Chinaunix首页 | 论坛 | 博客
  • 博客访问: 325207
  • 博文数量: 81
  • 博客积分: 1810
  • 博客等级: 上尉
  • 技术积分: 725
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-25 17:38
文章分类

全部博文(81)

文章存档

2016年(4)

2015年(11)

2014年(16)

2013年(37)

2012年(11)

2011年(2)

我的朋友

分类:

2013-12-27 12:49:40

协议

JTAG JOINT TEST ACTION GROUP(联合测试行动组织)的简称。IEEE 1149.1 标准就是由JTAG 这个组织最初提出的,最终由IEEE 批准并且标准化的。所以,这个IEEE 1149.1 这个标准一般也俗称JTAG 调试标准。本章主要介绍ARM JTAG 调试的基本原理,主要是对TAP (TEST ACCESS PORT) BOUNDARY-SCAN ARCHITECTURE 的介绍。

JTAG的结构图如图3.1,主要包括四部分:测试访问端口(TAP)、TAP控制器、指令寄存器及译码逻辑以及测试数据寄存器组。

TAPJTAG5个管脚;TAP控制器的作用是在JTAG管脚的控制下在JTAG状态机的不同状态下进行切换;测试数据寄存器组及指令寄存器都是JTAG结构特有的寄存器组,用于存取指令和数据,通过这两组寄存器还可以控制CPU的所有管脚。

如图所示,JTAG的根本原理就在于:将我们需要的指令寄存器或测试数据寄存器置于TDITDO之间,而后通过JTAG状态机时序来读写这些寄存器的内容

3.1 JTAG结构示意

在讨论JTAG的四个部分之前,先来介绍JTAG中很重要的一个概念:边界扫描。

边界扫描技术的基本思想是在靠近芯片的输入输出管脚上增加一个移位寄存器单元。因为这些移位寄存器单元都分布在芯片的边界上(周围),所以被称为边界扫描寄存器(Boundary-Scan Register Cell)。当芯片处于调试状态的时候,这些边界扫描寄存器可以将芯片和外围的输入输出隔离开来。通过这些边界扫描寄存器单元,可以实现对芯片输入输出信号的观察和控制。对于芯片的输出管脚,可以通过与之相连的边界扫描寄存器单元把信号(数据)加载倒该管脚中去;对于芯片的输入管脚,也可以通过与之相连的边界扫描寄存器捕获CAPTURE)该管脚上的输入信号。在正常的运行状态下,这些边界扫描寄存器对芯片来说是透明的,所以正常的运行不会受到任何影响。这样,边界扫描寄存器提供了一个便捷的方式用以观测和控制所需要调试的芯片。另外,芯片输入输出管脚上的边界扫描(移位)寄存器单元可以相互连接起来,在芯片的周围形成一个边界扫描链(Boundary-Scan Chain)。一般的芯片都会提供几条独立的边界扫描链,用来实现完整的测试功能。边界扫描链可以串行的输入和输出,通过相应的时钟信号和控制信号,就可以方便的观察和控制处在调试状态下的芯片。边界扫锚链也是上面说的测试数据寄存器之一。

如图3.2,假设图中6个小方框处为某款CPU(如S3C2440)的6I/O口,支持JTAG协议的CPU都会在其附近增加一个边界扫描寄存器。通过后面说的TAP状态机,我们可以将TDI的数据通过6IO口的任何一个输出,也可以将6IO口的任何一个的电平通过TDO输出。

3.2 边界扫描

下面,让我们开始讨论JTAG系统中的四大部分。

(TAP)

TAPJTAG相关的引脚,有四个基本端口和一个可选端口:

l         Test Clock Input (TCK)

TCK TAP 的操作提供了一个独立的、基本的时钟信号,TAP 的所有操作都是通过这个时钟信号来驱动的。TCK IEEE 1149.1 标准里是强制要求的。

l         Test Mode Selection Input (TMS)

TMS 信号用来控制TAP 状态机的转换。通过TMS 信号,可以控制TAP 在不同的状态间相互转换。TMS 信号在TCK 的上升沿有效。TMS IEEE 1149.1 标准里是强制要求的。

l         Test Data Input (TDI)

TDI 是数据输入的接口。所有要输入到特定寄存器的数据都是通过TDI 接口一位一位串行输入的(由TCK 驱动)。TDI信号在TCK 的上升沿有效。TDI IEEE 1149.1 标准里是强制要求的。

l         Test Data Output (TDO)

TDO 是数据输出的接口。所有要从特定的寄存器中输出的数据都是通过TDO 接口一位一位串行输出的(由TCK 驱动)。所有的输出 TDO 都是在TCK的下降沿进行的。TDO IEEE 1149.1 标准里是强制要求的。

l         Test Reset Input (TRST)

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

注意:在上面提到的寄存器指的是JTAG的指令寄存器或测试数据寄存器组。

控制器

TAP 控制器是一个有限状态机,此状态机有16个状态,如图3.2。测试访问状态机的目的是选择指令寄存器或数据寄存器使其连接到TDI TDO 之间。在图中,每个六边形表示一个状态,六边形中标有该状态的名称和标识代码。图中的箭头表示了TAP Controller 内部所有可能的状态转换流程。状态的转换是由TMS 控制的,所以在每个箭头上有标有tms = 0 或者 tms = 1。在TCK 的驱动下,从当前状态到下一个状态的转换是由TMS 信号决定。

这个状态机看似很复杂,其实理解以后会发现这个状态机其实很直接、很简单。观察图3.3,我们可以发现,除了Test-Logic Reset Test-Run/Idle 状态外,其他的状态有些类似。例如Select-DR-Scan Select-IR-Scan 对应,Capture-DR Capture-IR 对应,Shift-DR Shift-IR对应,等等。在这些对应的状态中,DR 表示Data RegisterIR 表示Instruction RegisterJTAG的寄存器分为两大类,数据寄存器和指令寄存器。其中标识有DR 的这些状态是用来访问数据寄存器的,而标识有IR 的这些状态是用来访问指令寄存器的。

Test-Logic Reset

系统上电后,TAP Controller 自动进入该状态。在该状态下,测试部分的逻辑电路全部被禁用,以保证芯片核心逻辑电路的正常工作。通过TRST 信号也可以对测试逻辑电路进行复位,使得TAP Controller 进入Test-Logic Reset 状态。前面我们说过TRST 是可选的一个信号接口,这是因为在TMS 上连续加5 TCK 脉冲宽度的“1”信号也可以对测试逻辑电路进行复位,使得TAP Controller 进入Test-Logic Reset 状态。在该状态下,如果TMS 一直保持为“1”TAP Controller将保持在Test-Logic Reset 状态下;如果TMS “1”变为“0”(在TCK 的上升沿触发),将使TAP Controller 进入Run-Test/Idle 状态。

Run-Test/Idle

这个是TAP Controller 在不同操作间的一个中间状态。这个状态下的动作取决于当前指令寄存器中的指令。有些指令会在该状态下执行一定的操作,而有些指令在该状态下不需要执行任何操作。在该状态下,如果TMS 一直保持为“0”TAP Controller 将一直保持在Run-Test/Idle 状态下;如果TMS “0”变为“1”(在TCK 的上升沿触发),将使TAPController 进入Select-DR-Scan 状态。

3.3 TAP状态机

Select-DR-Scan

这是一个临时的中间状态。如果TMS “0” (在TCK 的上升沿触发),TAP Controller进入Capture-DR 状态,后续的系列动作都将以数据寄存器作为操作对象;如果TMS “1” (在TCK 的上升沿触发),TAP Controller 进入Select-IR-Scan 状态。

Capture-DR

TAP Controller 在这个状态中,在TCK 的上升沿,芯片输出管脚上的信号将被捕获到与之对应的数据寄存器的各个单元中去。如果TMS “0” (在TCK 的上升沿触发),TAP Controller 进入Shift-DR 状态;如果TMS “1” (在TCK 的上升沿触发),TAPController 进入Exit1-DR 状态。

Shift-DR

在这个状态中,由TCK 驱动,每一个时钟周期,被连接在TDI TDO 之间的数据寄存器将从TDI 接收一位数据,同时通过TDO 输出一位数据。如果TMS “0” (在TCK的上升沿触发),TAP Controller 保持在Shift-DR 状态; 如果TMS “1” (在TCK 的上升沿触发),TAP Controller 进入到Exit1-DR 状态。假设当前的数据寄存器的长度为4。如果TMS 保持为0,那在4 TCK 时钟周期后,该数据寄存器中原来的4 位数据(一般是在Capture-DR 状态中捕获的数据)将从TDO 输出来;同时该数据寄存器中的每个寄存器单元中将分别获得从TDI 输入的4 位新数据。

Update-DR

Update-DR 状态下,由TCK 上升沿驱动,数据寄存器当中的数据将被加载到相应的芯片管脚上去,用以驱动芯片。在该状态下,如果TMS “0”TAP Controller 将回到Run-Test/Idle 状态;如果TMS “1”TAP Controller 将进入Select-DR-Scan 状态。

Select-IR-Scan

这是一个临时的中间状态。如果TMS “0” (在TCK 的上升沿触发),TAP Controller进入Capture-IR 状态,后续的系列动作都将以指令寄存器作为操作对象;如果TMS “1”(在TCK 的上升沿触发),TAP Controller 进入Test-Logic Reset 状态。

Capture-IR

TAP Controller 在这个状态中,在TCK 的上升沿,一个特定的逻辑序列将被装载到指令寄存器中去。如果TMS “0” (在TCK 的上升沿触发),TAP Controller 进入Shift-IR状态;如果TMS “1” (在TCK 的上升沿触发),TAP Controller 进入Exit1-IR 状态。

Shift-IR

在这个状态中,由TCK 驱动,每一个时钟周期,被连接在TDI TDO 之间的指令寄存__器将从TDI 接收一位数据,同时通过TDO 输出一位数据。如果TMS “0” (在TCK的上升沿触发),TAP Controller 保持在Shift-IR 状态; 如果TMS “1” (在TCK 的上升沿触发),TAP Controller 进入到Exit1-IR 状态。假设指令寄存器的长度为4。如果TMS 保持为0,那在4 TCK 时钟周期后,指令寄存器中原来的4bit 长的特定逻辑序列(在Capture-IR 状态中捕获的特定逻辑序列)将从TDO 输出来,该特定的逻辑序列可以用来判断操作是否正确;同时指令寄存器将获得从TDI 输入的一个4bit 长的新指令。

Update-IR

在这个状态中,在Shift-IR 状态下输入的新指令将被用来更新指令寄存器。

上面的讲述可能有点抽象,更具体的实例大家有兴趣的话可以参看《ARM JTAG 调试原理》的2.2节。

IEEE 1149.1 标准当中,规定了一些指令寄存器、公共指令和相关的一些测试数据寄存器。对于特定的芯片而言,芯片厂商一般都会在IEEE 1149.1 标准的基础上,扩充一些私有的指令和数据寄存器,以帮助在开发过程中进行方便的测试和调试。在这一小节,我将简单介绍ARM920支持的一些常用的指令及其相关的寄存器。

指令寄存器

指令寄存器允许特定的指令被装载到当中,用来选择需要执行的测试,或者选择需要访问的测试数据寄存器。每个支持JTAG 调试的芯片必须包含一个指令寄存器。

BYPASS 指令和Bypass 寄存器

Bypass 寄存器是一个一位的移位寄存器,通过BYPASS 指令,可以将bypass 寄存器连接到TDI TDO 之间。在不需要进行任何测试的时候,将bypass 寄存器连接在TDI TDO之间,在TDI TDO 之间提供一条长度最短的串行路径。这样允许测试数据可以快速的通过当前的芯片送到开发板上别的芯片上去。

IDCODE 指令和Device Identification 寄存器

Device identification 寄存器中可以包括生产厂商的信息,部件号码,和器件的版本信息等。使用IDCODE指令,就可以通过TAP 来确定器件的这些相关信息。例如,Jflash程序可以自动识别当前调试的是什么片子,其实就是通过IDCODE 指令访问Device Identification 寄存器来获取的。

INTEST 指令和Boundary-Scan 寄存器

Boundary-Scan 寄存器就是我们前面例子中说到的边界扫描链。通过边界扫描链,可以进行部件间的连通性测试。当然,更重要的是可以对测试器件的输入输出进行观测和控制,以达到测试器件的内部逻辑的目的。

INTEST 指令是在IEEE 1149.1 标准里面定义的一条很重要的指令:结合边界扫描链,该指令允许对开发板上器件的系统逻辑进行内部测试。在ARM JTAG 调试当中,这是一条频繁使用的测试指令。

EXTEST指令

EXTEST指令也是JTAG标准里面非常重要的指令。结合边界扫描链,该指令允许对开发板上器件的输入输出口进行外部测试。与INTEST指令不同的是:该指令主要用于捕获和控制外部IO口的电平。在Jflash源码中使用最多的就是该指令。

除了上面这些指令中,S3C2440支持的JTAG指令总共有表3.1中的10个,其中JTAG接口标准要求芯片支持的基本指令有: EXTESTINTESTSAMPLE/PRELOADBYPASSIDCODEHIGHZ。其余的是arm920t私有的指令。

3.1 S3C2440支持的指令集

指令

二进制代码

说明

EXTEST

0000

将之前指定的扫描链置为 外部测试 模式

SAN_N

0010

将指定的扫描链连接到TDITDO之间。重启JTAG后,默认第三条扫描链被连接到TDITDO之间。该指令必须配合有 扫描链选择寄存器。

INTEST

1100

将之前指定的扫描链置为 内部测试 模式

IDCODE

1110

连接ID寄存器到TDITDO之前,以获取芯片的ID

BYPASS

1111

连接一个1bit的移位寄存器到TDITDO之间,所有扫描单元置为普通操作模式

CLAMP

0101

连接一个1bit的移位寄存器到TDITDO之间

HIGHZ

0111

连接一个1bit的移位寄存器到TDITDO之间。在该命令下,且选中扫描链0时,所有输出被置为高阻态

CLAMPZ

1001

连接一个1bit的移位寄存器到TDITDO之间

SAMPLE/PRELOAD

0011

将之前指定的扫描链的所有扫描单元置为 普通操作模式。在INTESTEXTEST指令前必须用此命令配合已知数据来预装载边界扫描寄存器

RESTART

0100

重启CPU并从debug状态退出

 

我们前面说过,寄存器分为两大类:指令寄存器和数据寄存器。在上面提到的Bypass 寄存器、Device Identification 寄存器和Boundary-scan 寄存器(边界扫描链),都属于数据寄存器。在调试当中,边界扫描寄存器(边界扫描链)最重要,使用得也最为频繁。

BSDL文件

S3C2440的测试数据寄存器包括了Bypass寄存器、ID寄存器、边界扫描寄存器、扫描链选择寄存器等。其中在Jflash中最重要的当属第3条边界扫描链。

该边界扫锚链对应了该款CPU所有的管脚以及一些测试信号,我们可以在JTAG信号的控制下通过该边界扫锚链去存取CPU的所有管脚,也即完成对CPU所有管脚的操作。有读者可能就要问了:那我从哪里知道这条边界扫锚链的信息呢?

其实,每个支持JTAGCPU厂商都会提供一个BSDL文件,该文件描述了CPU的第几条边界扫锚链具有上述功能,该边界扫描链的长度以及CPU每个管脚在该链上的索引。以下是摘自xjtag网页对BSDL的描述:

Boundary Scan Description Language (BSDL) is a subset of VHDL that is used to describe how JTAG (IEEE 1149.1) is implemented in a particular device. For a device to be JTAG compliant, it must have an associated BSDL file.

These files are often available for download from manufacturers' websites (see below).

JTAG systems such as XJTAG use the information contained in a BSDL file to work out how to access a device in the JTAG chain.

BSDL files contain the following elements:

·       Entity Description: Statements naming the device or a section of its functionality.

·       Generic Parameter: A value such as a package type. The value may come from outside the current entity.

·       Port Description: Describes the nature of the pins on the device (input, output, bidirectional, linkage).

·       Use Statements: References external definitions (such as IEEE 1149.1).

·       Pin Mapping(s): Maps logical signals in the device to physical pins.

·       Scan Port Identification: Defines the pins used on the device to access the JTAG capabilities (TDI, TDO, etc - the Test Access Port).

·       Instruction Register Description: The signals used for accessing JTAG device modes.

·       Register Access Description: Which register is placed between TDI and TDO for each JTAG instruction.

Boundary Register Description: List of the boundary scan cells and their functionality.

若要对BSDL文件的格式有个初步了解,也可参考《JTAG原理及sjf2410源码分析》。

JTAG操作相关代码都可以在附件中找到,这里先以JTAG_RunTestldleState 函数为例,讨论如何控制JTAG信号使其从 Test-Logic Reset状态进入Run-Test/Idle状态。

/********************************************************************

 * 功能:     Enter Run-Test/Idle mode

********************************************************************/

void JTAG_RunTestldleState( void )

{

       JTAG_Reset(); //TMS=1, 5*TCK Snychronous Reset 进入 Test-Logic Reset 状态

       JTAG_SET(TDI_H | TMS_L | TCK_L);JTAG_DELAY();   // Why 3 times?

       JTAG_SET(TDI_H | TMS_L | TCK_H);JTAG_DELAY();   // Run-Test/Idle Status

       JTAG_SET(TDI_H | TMS_L | TCK_L);JTAG_DELAY();

       JTAG_SET(TDI_H | TMS_L | TCK_H);JTAG_DELAY();   // Run-Test/Idle Status

       JTAG_SET(TDI_H | TMS_L | TCK_L);JTAG_DELAY();

       JTAG_SET(TDI_H | TMS_L | TCK_H);JTAG_DELAY();   // Run-Test/Idle Status

}

为了确保进入 Run-Test/Idle状态,程序在进入Test-Logic Reset 状态的基础上连续三个周期从TDI输入高电平。

其次,我们以发送命令给Nand Flash为例,讨论如何利用TAP状态机及JTAG管脚来实现将命令发给Nand Flash

static void NF_CMD(U8 cmd)

{   

       S3C_SetPin(DATA0_7_CON, LOW);   //HIGH=input, LOW=output; 设置D[7:0]为输出

       S3C_SetPin(nFCE, LOW);    // 使能Nand Flash

       S3C_SetPin(nFRE, HIGH);    //

       S3C_SetPin(nFWE, LOW);   // 使能写

       S3C_SetPin(ALE, LOW);      // 使能CLE,非能ALE

       S3C_SetPin(CLE, HIGH);

       S3C_SetDataByte(cmd);              // 通过IO口送入命令

       JTAG_ShiftDRStateNoTdo(outCellValue);    // 通过TAP状态机将刚刚设置的管脚动作实现

       S3C_SetPin(nFWE, HIGH);

       JTAG_ShiftDRStateNoTdo(outCellValue);

#if 1

       S3C_SetPin(CLE, LOW);

       S3C_SetPin(DATA0_7_CON, HIGH);   //D[7:0]=input

       JTAG_ShiftDRStateNoTdo(outCellValue);

#endif

}

 

在软件上我们设置了一个大小为 473 的数组以与边界扫描链3 对应(其有471个边界扫描单元)。上文的S3C_SetPin  函数只是将管脚对应的数组元素设为对应的数值,并没有真正将硬件上的管脚设置为对应值。而JTAG_ShiftDRStateNoTdo 函数其实就是通过TAP状态机的控制来将硬件的管脚设置为对应值。

举个例子来说:我们需要将 nFWE 脚设置为高电平。则先通过 S3C_SetPin(nFWE, HIGH) 将对应数组元素设为1;而后在TAP状态机的 Shift-DR 阶段通过471个周期将数组中471个元素都移位到对应的边界扫描单元中,也就是说 471个周期后 nRWE 管脚对应的BSC 的值为 1;最后,在 Update-DR 阶段,BSC单元中的数值将通过CPU管脚输出。

到本章结束,我们已经知道:可以通过S3C2440JTAG调试系统来监控其所有管脚,进而实现对K9F1208的读写控制。那现在就剩下最后一个问题了:用什么来控制JTAG的几个引脚?

对于一般的工业MCU,我们可以通过其IO管脚连接JTAG引脚,以控制JTAG时序;对于PC机,一般就只有USB、串口以及并口三种外部总线。USB及串口只有两条数据线,要用来控制JTAG引脚的话,必须再经过一层转换;一般PC并口有25针,其中既有输入,也有输出,刚好适合用来控制JTAG引脚。

下一章我们将讨论JTAG系统的最后一个部分:并口。

阅读(11871) | 评论(0) | 转发(0) |
0

上一篇:UTC, TAI, GPS

下一篇:git资料收集

给主人留下些什么吧!~~