关于JTAG原理和sjf2410源码分析

想了解一下JTAG原理,在网上看到一篇文章,里面已经把相关内容写得非常详细了,这里分享一下:

http://www.mcuol.com/download/upfile/20080327030215_JTAG原理及sjf2410源码分析.pdf

这篇文章并没有把所有的源码列出来,我看的是windows下面的sjf2410源码,首先我并不想把源码细节全部弄懂,尤其是FLASH操作的过程和时序。我只是想了解JTAG的原理和烧写程序的工作原理。建立在已经看过比较细致的JTAG原理介绍的前提下,下面我对JTAG大致的理解:

JTAG的结构图

具有JTAG口的IC内部BSR单元与引脚关系

 

JTAG TAP 状态图:

图2.

 

TCK上升沿时TMS电平确定状态机的转换。

TCK上升沿TDI数据移入JTAG内部数据或指令寄存器

TCK下降沿时TDO数据移出到PC

不同的指令决定连接在TDI与TDO之间的寄存器。当前指令决定当前TDI与TDO之间连接的寄存器级,并且直到一下次写入新指令前连接都有效。指令输入是通过slect-ir-scan---->update-ir状态转换完成的。

边界扫描寄存器BSR是全部串行地连在一起的单元(cell)组成,每个cell连接一个引脚,一个cell能控制对应引脚的输出电平,也能读入当前引脚的电平。

sjf2410软件的工作原理就是控制连接到FLASH芯片对应引脚的cell,模拟FLASH编程时序来完成的。

所以sjf2410源码中先设置EXTEST指令,把BSR连接在TDI与TDO之间。然后串行输入各个cell的值,2410一共是426个,从TDO串行得到各个引脚的输出。当然,烧写程序只关心的是与FLASH引脚相联的那些引脚。BSR可以看成一个426bit长的寄存器。

烧写FLASH时JTAG主要工作流程如下:

状态图中 capture DR 状态时把当前引脚的值读入到边界扫描寄存器BSR中,

     shift DR状态中串行把TDI移入BSR,同时BSR移出到TDO,直到数据全部移入。

                update DR状态时才把BSR内容输出到所连接的引脚上。

程序中的对应的数据结构是这样的:

char outCellValue[S2410_MAX_CELL_INDEX+2];//保存TDO串行输出
char inCellValue[S2410_MAX_CELL_INDEX+2]; //TDI串行输入源
int  dataOutCellIndex[32];//保存TDO串行输出的32位数据,比如连接的是数据IDCODE寄存器
int  dataInCellIndex[32];//TDI串行移入的32b数据
int  addrCellIndex[27];//27位总线对应的cell

上述数组就是用一个char或者int的1与0表示对就cell的高低电平。

程序中先对所有引脚进行初始化:用SAMPLE/PRELOAD指令,读出当前426引脚值,把未用的引脚用对应读出值初始化,要用的引脚初始化为安全状态。

然后写入EXTEST指令。并使TAP进入test-idle状态。

现在就可以操作FLASH引脚时序来烧程序了!!!

每次执行一次针对FLASH的操作总是包括了以下过程:

   先设置outCellValue[]中要输出引脚。

   再通过移位操作把TDI移入(TDO接收)

 

从操作层面上整个过程可以分三层:

1)最高层是FLASH操作流程,如烧写FLASH时要先写命令80H,再写入地址(地址可能要分三次写),再写入数据,最后写如10H,烧写完毕后再读状态寄存器判断烧写成功。

2)第二层是FLASH时序流程,上述每个操作都对应一系统的时序。比如说写命令80H源码:

static void NF_CMD(U8 cmd)
{  
   
    //Command Latch Cycle
    S2410_SetPin(DATA0_7_CON ,LOW); //D[7:0]=output
    S2410_SetPin(nFCE,LOW);
    S2410_SetPin(nFRE,HIGH);
    S2410_SetPin(nFWE,LOW);

 //Because tCLS=0, CLE & nFWE can be changed simultaneously.
    S2410_SetPin(ALE,LOW);
    S2410_SetPin(CLE,HIGH);
    S2410_SetDataByte(cmd);
    JTAG_ShiftDRStateNoTdo(outCellValue);

    S2410_SetPin(nFWE,HIGH);
    JTAG_ShiftDRStateNoTdo(outCellValue);

#if 1
    S2410_SetPin(CLE,LOW); 
    S2410_SetPin(DATA0_7_CON,HIGH); //D[7:0]=input
    JTAG_ShiftDRStateNoTdo(outCellValue);
#endif
}
3)第3层就是TDI串行移入操作。如上面的JTAG_ShiftDRStateNoTdo(outCellValue); 把426个设置好的位按照captureDR-->updateDR的状态转换过程,串行移入BSR并输出到对应引脚上。

以上就是我自己对JTAG原理和烧写FLASH流程的在宏观上的理解。显然有些浮在上层,没有深入具体的各种时序和编程技术。

 

 

投 票

觉得本文不错,投一票   

评 论


验证码: 看不清?换一张