jflash烧录教程_Jflash烧录(windows)原理分析

jflash烧录教程_Jflash烧录(windows)原理分析
在分析test_port()之前,我们⾸先对并⼝编程先进⾏⼀些介绍,我们的PC机⼀般有三个并⼝,他们的IO地址范围通常是:
0x3bc-0x3be
0x378-0x37a
0x278-0x27a
在很多电脑⾥⾯,通常连接Jtag的并⼝是以0x378为基地址的并⼝。
可以看到⼀个并⼝有三个IO地址,第⼀个是数据寄存器地址,第⼆个是控制寄存器地址,第三个是状态寄存器地址。
JTAG原理
上篇⽂章刚刚提到 test_logic_reset函数,这个函数是⽤来reset
Jtag链的,继续分析之前,还是先让我们来了解JTAG的⼯作状况。为了测试我们的PCB板的⽅便,JTA
G这个东西被搞了出来。如果想更多的了解
JTAG,⼤家可以去看看IEEE 1149.1的标准,如果只是和我⼀样,想了解⼀下的话,⼤家可以看看Mark
Zwolinski著《VHDL数字系统设计》,电⼦⼯业出版社出版了他的中⽂版。
每⼀个JTAG兼容的元件都有⼀个共⽤的测试结构,这种结构基本单元如下:
触摸调光ic1、测试存取端⼝
测试存取端⼝包括4个或5个为测试增加的引脚。这些引脚是:
TDI和TDO(测试数据输⼊和输出)。数据和指令通过扫描路径送⾄IC。没有办法从指令中区分数据,或者判断⼀系列位的⽬标是到达哪个特定的IC。因此,下⾯的引脚⽤来控制数据流向。
TMS(测试模式选择)。与TCK引脚⼀起,TMS引脚⽤来控制⼀个状态机以决定每位通过TDI到达⽬的地。
TCK(测试时钟)
TRST(测试复位),这是可选的异步复位信号,很多的JTAG电路中没有这个信号。
2、TAP控制器
TAP控制器是⼀个具有16个状态的状态机,它⽤来控制测试。状态机的输⼊是TCK和TMS,输出是其它寄存器的控制信号。下⾯链接是我在⼀个⽹站上到的他的状态图,⼤家也可以在google的图⽚⾥⾯搜索tap
controller,就可以搜索到这个状态图。
通过这个图可以看出,TMS脚上保持5个时钟周期的⾼电平,会使得状态机从任何状态进⼊Test-Logic-Reset。TAP控制器发出的控制信号⽤来启动器件中的其它寄存器。这样,如果到达TDI的位序列合适,就将被送到指令寄存器或者特别的数据寄存器。
3、测试数据寄存器(Test Data
Registers) ⼀个与边界扫描兼容的元件必须将其所有的输⼊和输出连接⾄扫描路径。⼀下描述的特殊单元⽤来实现扫描寄存器。另外,必须有⼀位的旁路寄存器,这样可以通过绕开元件的边界扫描寄存器来缩短扫描路径。另外还需要⼀些其他的寄存器,例如,⼀个IC可能需要⼀个标志寄存器,这个寄存器的内容可以通过扫描访问来确定
PCB板上是否装配了正确的IC。同样,我们可以通过边界扫描接⼝访问器件的内部扫描路径。某些可编程逻辑⽣产商允许使⽤边界扫描器件来对器件进⾏编程,因此,另⼀种可能的数据寄存器是配置寄存器。
4、指令寄存器(Instruction Register)
指令寄存器⾄少有2位,这依赖于实现的测试数⽬。它定义了测试数据寄存器的使⽤。指令寄存器还产⽣进⼀步的控制信号。
边界扫描单元有四种操作模式:
普通模式。⼀般的系统数据从In传输⾄OUT。
扫描模式。shfiterDR选择SCAN_IN引脚,ClockDR提供扫描路径时钟。ShifterDR值由Tap控制器中相似的名称的状态得来。当TAP控制器处于状态capture-DR或者shifter-DR时,断⾔ClockDR。
捕捉模式。ShiftDR选择In引脚,数据由ClockDR时钟送⼊扫描路径寄存器来对系统进⾏快照。
更新模式。在捕捉或者扫描之后,数依据通过UpdateDR⼀个时钟沿从左边沿触发送⾄OUT。
test_logic_rest函数分析
好,这⾥说了这么多的JTAG,下⾯我们继续分析源代码, test_logic_reset的代码如下:
void test_logic_reset(void)
{
putp(1,1,IGNORE_PORT);// keep TMS set to 1 force a test logic
reset
putp(1,1,IGNORE_PORT);// no matter where you are in the TAP
controller
putp(1,1,IGNORE_PORT);
putp(1,1,IGNORE_PORT);
putp(1,1,IGNORE_PORT);
putp(1,1,IGNORE_PORT);
}
这个函数的⽬的是⽤来对JTAG逻辑进⾏重置的,函数调⽤了6个putp函数。
putp函数源代码如下:
int putp(int tdi, int tms, int rp)
磁石电话机{
int tdo = -1;
// TMS is D2, TDI is D1, and TCK is D0, so construct an output by
creating a
// rising edge on TCK with TMS and TDI data set.
_outp(lpt_address, tms*4+tdi*2+8);// TCK low
_outp(lpt_address, tms*4+tdi*2+1+8);// TCK high
/
/ if we want to read the port, set TCK low because TDO is
sampled on the
// TCK falling edge.
if(rp == READ_PORT)
_outp(lpt_address, tms*4+tdi*2+8);// TCK low
if(rp == READ_PORT)
tdo = !((int)_inp(lpt_address + 1) >>
7);// get TDO data
这⾥的代码是使⽤并⼝做JTAG访问的代码,可以看出,这个函数是产⽣⼀次TCK脉冲,同时发送数据和接受数据的。tdo最后返回的是TDO的状态值,使⽤了⼀个!是因为前⾯说过最⾼位的逻辑是与信号线上相反的。知道的putp代码的作⽤,我们就可以看出
来,test_logic_reset的作⽤是让
TMS保持6个⾼电平,前⾯说过,TMS 5个电平就会使得器件进⼊重置状态。
jtag_test()函数分析
接下来,jtag_test()函数被调⽤,我们再来对他进⾏分析
void jtag_test()
{
// set all devices into bypass mode as a safe instruction
pre_IRSCAN();
if (controller_scan_code(COT_BYPASS, READ_PORT, CONTINUE) !=
0x1)防堵风压取样器
多功能按摩垫
{
error_out("Jtag test failure. Check connections and
power.\n");
}
post_IRSCAN();
printf("JTAG Test Passed\n");
}
⾸先, pre_IRSCAN()被调⽤, pre_IRSCAN()的代码如下:
void pre_IRSCAN()
{灯头盒
putp(1,0,IGNORE_PORT);//Run-Test/Idle
putp(1,0,IGNORE_PORT);//Run-Test/Idle
putp(1,0,IGNORE_PORT);//Run-Test/Idle钢球级配
putp(1,0,IGNORE_PORT);//Run-Test/Idle
putp(1,1,IGNORE_PORT);
putp(1,1,IGNORE_PORT);//select IR scan
putp(1,0,IGNORE_PORT);//capture IR
putp(1,0,IGNORE_PORT);//shift IR
}
可以看出来,TAP状态机从Run_test/IDL到Selet_DR-Scan到Select-IR-SCAN再进⼊Capture-IR,最后进⼊Shift-IR,从函数返回的时候,器件进⼊等待数据移位进⼊IR的状态
然后,controller_scan_code函数被调⽤,该函数则完成将⼀个BYPASS指令移进IR当中,然后为什么会在TDO上得到⼀个⾼电平我就不清楚了,可能这是对BYPASS命令的应答。然后Post_IRSCAN被调⽤,状态机返回到Run-Test/Idle模式。
Jtag-test完成之后,就开始真正的flash烧写过程了
昨天分析到jtag_test了,今天继续往下看
char filename[MAX_IN_LENGTH];
if(argc >= 2)
strcpy(filename,argv[1]);
else
{
printf("enter file: ");
gets(filename);
}
程序接着检查了是否有指定⽂件名,如果没有,则获取⽂件名
test_logic_reset();
再次重置Jtag逻辑,使得系统进⼊可靠状态。
id_command();
执⾏id_command,该函数⾸先使TAP控制器进⼊ShiftIR状态,然后向IR中移⼊COT_IDCODE(0x1E)指令,然后使TAP控制器进⼊shiftDR状态,往TDI信号置1,将DR值移出来,与系统的ID想⽐较,如果相应,则函数执⾏成功返回,否则就打印错误信息,退出程序。
bypass_all();
接着bypass_all()被调⽤,该函数同样通过控制TAP控制器来向器件发送COT_BYPASS(0x1F)指令,使得器件进⼊bypass_all状态。
test_logic_reset()
接着继续调⽤test_logic_reset()使系统进⼊可靠状态。
check_rom_info(&max_erase_time,
&dsize, &max_write_buffer,
&block_size, &nblocks);
该函数调⽤了⼀连串的access_rom函数,access_rom函数是完成烧写的核⼼函数,时间已经晚了,明天继续分析
昨天分析到了check_rom_info函数,提到access_rom是整个的核⼼。
其实这么说也不⼤准确,应该说access_rom
是最底层操作的函数,它⾸先将TAP控制器状态移到ShiftDR,然后把准备好的各个引脚的电平状态设置好(没怎么搞懂⾼阻态是如何动作的,也许扫描链⽐实际引脚会多⼏个脚),移⼊扫描链中,然后把TAP控制器状态移到ShiftIR,把extest指令移⼊,使器件进⼊外部逻辑测试状态,刚才为扫描链中移⼊的电平就放到了引脚上。access_rom把参数addr放到器件的地址引脚上,把数据放到数据引脚上,同时把引脚原本的引脚信号移出TDO,就可以把flash返回在数据线上信号返回。
正如代码⾥⾯的那段注释:
To read data from the Flash Memory you must first fill the
processor JTAG chain with the Address, then pump the entire chain
out.however while pumping data out you can be pumping the next
cycle's Address in Therefore the JTAG chain looks like a pipeline,
valid read data always coming
out one cycle late.
当前flash返回的数据要下⼀次扫描的时候才能返回,所以access_rom函数返回的值是上次地址读到的数据。
check_rom_info的代码⽐较长,⽽且都是⼀些通过flash的CFI(Common Flash
Interface)对flash信息简单的读取操作,这⾥就不再贴出来了。
check_rom_info成功返回之后,程序开始检查将要写进flash的⽂件的合法性,主要是⼤⼩是否合法,如果⽐flash还⼤,就返回错误信息并退出。如果成功,经过⼀些简单的界⾯交互过程之后,程序开始调⽤test_lock_flash来检查相应的块是否已经被lock,如果被锁定,则发送命令将其unlock,然后返回之后,程序调⽤erase_flash和program,函数同样是使⽤acess_rom调⽤来在flash引脚上产⽣相应的时序来完成相应的操作。⼤家可以参考相应的flash芯⽚的资料。
最后,程序再把flash⾥⾯的数据读取出来进⾏与⽂件进⾏验证,检查烧写是否成功。

本文发布于:2024-09-24 10:18:30,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/278484.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:烧录器编程器
标签:扫描   数据   寄存器   引脚   器件
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议