关于JTAG原理和sjf2410源码分析424257749
想了解一下JTAG原理,在网上看到一篇文章,里面已经把相关内容写得非常详细了,这里分享一下:
http://www.mcuol.com/download/upfile/20080327030215_JTAG原理及sjf2410源码分析.pdf
这篇文章并没有把所有的源码列出来,我看的是windows下面的sjf2410源码,首先我并不想把源码细节全部弄懂,尤其是FLASH操作的过程和时序。我只是想了解JTAG的原理和烧写程序的工作原理。建立在已经看过比较细致的JTAG原理介绍的前提下,下面我对JTAG大致的理解:
JTAG的结构图

JTAG TAP 状态图:

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流程的在宏观上的理解。显然有些浮在上层,没有深入具体的各种时序和编程技术。
数据正在载入中..
