JTAGER User Manual
(中文版)
版本:0.1.0
Rongkai
Zhan(詹荣开) 2003-11-1
JTAGER是一个运行在主机端(Host Side)的简易嵌入式系统调试器。通过JTAGER,我们可以:(1)读写嵌入式目标板(target
board)上的CPU core状态(比如,cpu寄存器);(2)读写编址在统一内存空间的外部设备寄存器;(3)读写目标机上的RAM;(4)读写目标机上的固态存储设备,比如:Flash。
+-------+
+-----------+ +--------+ | | |
| | | | Debug
| -------> | Protocol
| -------> | Debug
| | Host | <------- | Converter |
<------- | Target | | | |
| | | +-------+
+-----------+ +--------+ |
| |
| V V The
host running For example, Multi-ICE, the debug toolkits Wiggler-compatible
JTAG (such as JTAGER) dongle,
etc. Figure 1 A typical
embedded debug system
|
为了调试目标板,在主机和目标机之间通常需要一个协议转换器(protocol converter)来传输信号与数据。一个典型的调试系统如图1所示.
(1)
目标机CPU类型
l
ARM7TDMI core。
(2)
支持的JTAG协议转换器设备类型
l
Wiggler JTAG
dongle。
(3)
支持的Flash芯片类型
l
SST39LF/VF160。
l
SST39LF/VF512,
SST39LF/VF010, SST39LF/VF020, SST39LF/VF040.
l
SST28SF/VF040A
l
AM29F040
由于安装和运行JTAGER程序需要root权限,因此首先我们假定您已经取得root权限。
假设用户已经将包jtager-0.1.0.tar.gz放到目录/tmp下,那么首先按照下列步骤将jtager包解开:
#cd /tmp
#tar zxvf jtager-0.1.0.tar.gz
#cd jtager-0.1.0
然后,进行配置并编译:
#configure
--prefix=/usr/local/jtager
#make all
最后,将JTAGER安装到配置时指定的安装目录下(这里是/usr/local/jtager):
#make install
安装完毕后,在shell提示符中输入”/usr/local/jtager/bin/jtager” 就可以运行JTAGER程序,如下:
#/usr/local/jtager/bin/jtager
JTAGER是一个由命令驱动的程序。当用户在shell中运行jtager程序后,JTAGER将打印它自己的命令提示符“JTAGER:> ”,以提示用户输入JTAGER命令。
所有的JTAGER命令、选项以及命令参数均不区分大小写,命令、选项以及非选项参数之间以空格字符相隔。
每一个JTAGER命令都拥有GNU风格的长名字选项,也即,每一个命令选项均以字符串“--”(两个“-”字符)开头。例如:
JTAGER:> ice --list
JTAGER命令选项后面也可以带有参数值,则该选项后面紧接着一个“=”字符,参数值则紧接在字符“=”的后面。注意:它们之间不能有空格字符。例如:
JTAGER:> mem --read --start-address=0x01c80000
JTAGER命令也可以带有非选项参数。对于整数形式的非选项参数,其表示方法与整数形式的选项参数相同。比如,在下列命令中,“0x111”就是一个非选项参数:
JTAGER:> reg --name=r0 0x111
JTAGER参数值表示规则:参数值可以是一个字符串,也可以是个整数。对于整数形式的参数值,可以采用16进制的表示方法,也可以采用10进制的表示法。比如:“0x0ff0、0Xff0、ff0H、ff0h”都是JTAGER可以识别的16进制表示法。如果没有显示地采用16进制表示法,所有整数形式的参数值都被视为10进制数。
所有的JTAGER命令被分为两组:(1)基本命令组(basic commands group);(2)调试命令组(debug commands group)。
基本命令组包括如下5命令:
l
reset命令:该命令复位JTAG接口,将目标机的TAP控制器带到Run-Test/Idle状态。
l
help命令:显示JTAGER命令的帮助信息,或者打印所有的JTAGER命令列表。
l
idcode命令:读取目标机CPU的IDCODE值。
l
exit/quit命令:退出JTAGER程序。
调试命令组包括如下命令:
l
halt命令:向目标机的CPU发出调试请求(DBGRQ)。如果命令执行成功,则在该命令执行结束后,目标机将被置于调试状态下。否则,它将打印一条简单错误描述信息。
l
restart命令:结束当前的调试状态,使目标机的CPU从上次被halt命令中断的那个地址处继续运行。如果执行成功,则在该命令结束后,目标机将处于正常的系统运行状态下。
l
ice命令:读写目标机CPU内的EmbeddedICE-RT logic的寄存器值。
l
reg命令:读写目标机CPU core的寄存器值。
l
mem命令:读写目标机上某个指定的内存区域。
l
flash命令:读写目标机上某个指定的Flash内存区域。
JTAGER reset命令用来复位Host与Target之间的JTAG连接,并将目标机的TAP控制器带到Run-Test/Idle状态下。关于TAP控制器的状态可以参考IEEE Standard 1149.1-1990, <<IEEE Standard Test
Access Port and Boundary-Scan Architecture>>。命令reset没有任何选项和参数,其调用语法如下:
reset
JTAGER help命令用来显示某个指定的JTAGER命令的帮助信息,或者打印一个可用的JTAGER命令列表。其调用语法如下:
help [cmdname]
非选项参数cmdname可以是任何一个JTAGER命令名。如果不指定cmdname的值,则help命令将打印一张所有JTAGER命令的清单列表,这个清单列表分为两列,其间由制表符’\t’相隔开。第一列是命令名,第二列是该命令的简单描述。
比如,使用“help help”命令将得到help命令的帮助信息:
USAGE:
help [cmdname]
DESCRIPTION:
Show the list of
all available JTAGER commands, or show the
verbose information of the
specified JTAGER command.
PARAMETERS:
cmdname The spcified JTAGER command name.
JTAGER idcode命令用来读取目标机CPU的IDCODE值。所有带有JTAG测试支持的CPU都有一个唯一的32位的IDCODE值。按照JEDEC标准和<<IEEE Std 1149.1>>标准,IDCODE值的bit[0]必须总是为1,bit[11:1]表示唯一的制造商ID,bit[27:12]表示产品ID,bit[31:28]表示版本ID。不同的CPU有不同的IDCODE值,参考您特定CPU的BSDL文件通常可以知道其IDCODE值。
JTAGER idcode命令不带有任何参数,其调用语法如下:
idcode
JTAGER idcode命令的另一个用途就是用来检验Host、JTAG仿真器和Target这三者之间的连接的正确性。在调用halt命令进入调试模式之前,我们建议用户最好先调用idcode命令来读取IDCODE值,以检查我们所读出的IDCODE值是否与您特定CPU的值相吻合。如果它们一致,则说明Host、JTAG仿真器与Target这三者之间的连接是正确的,同时也说明您的目标板在硬件上似乎也是无误的:-)
对于我用的基于Samsung S3C44B0X CPU的目标板,idcode命令打印如下信息:
Reading the JTAG Device ID code
... [OK]
Device ID = 0x1F0F0F0F
bit[0] = 1,
always be 1, required by IEEE Std 1149.1
Manufacturer
(bit[11:1]): 0x787 – SAMSUNG
Part number
(bit[27:12]): 0xF0F0
Version
(bit[31:28]) : 0x1
JTAGER exit或quit命令用来推出JTAGER程序,回到shell。命令exit与命令quit是等价的。其调用语法如下:
exit或quit
JTAGER halt命令被用来向目标机CPU发出调试请求(DBGRQ),目标机在收到调试请求后将停止当前的执行路径,转入调试状态。当目标机进入调试状态后,其内部时钟将被停止,也即CPU不再由其内部的时钟信号所驱动,而是由调试脉冲信号所驱动。
JTAGER halt命令不带有任何命令选项,其调用语法如下:
halt
JTAGER halt命令是reg、mem、flash等JTAGER调试命令的基础。只有在使用halt命令将目标机置于调试状态后,reg、mem和flash这三个命令才能被调用。否则,这三个命令将会打印如下这样的错误信息:
Error: The target is running.
Please use "halt" command to halt it.
JTAGER restart命令被用来结束目标机的当前调试状态,使目标机CPU从上次被halt命令中断的那个地址处继续运行。如果执行成功,则在该命令结束后,目标机将处于正常的系统运行状态下。
JTAGER restart命令不带有任何命令选项,其调用语法如下:
restart
JTAGER ice命令被用来读写目标机CPU内的EmbeddedICE-RT logic的寄存器值。其命令语法如下:
ice [--list]
ice --name=regname [newvalue]
当以不指定任何选项或参数的方式调用ice命令时,它将读取并打印目标机CPU内的所有ICE寄存器的当前值。
--list
该选项用来列出所有合法的ICE寄存器名字。该选项是可选的。
--name=regname
该选项用来指定所要读写的ICE寄存器名字。选项的参数值regname必须是--list选项列出的ICE寄存器名字列表中的一个。该选项是必不可少的。
newvalue
非选项参数(non-option
argument)newvalue表示用户为某个ICE寄存器设定的新值,它遵循前面所述的“JTAGER参数值表示规则”。该参数是可选的。如果newvalue非选项参数被指定,则被指定的新值被写入到指定ICE寄存器中。如果没有出现newvalue非选项参数,则读取指定ICE寄存器的当前值。
JTAGER reg命令可以读写目标机CPU core的寄存器。该命令必须在目标机CPU处于调试状态下才能使用。其调用语法如下:
reg [--list]
reg --name=regname [newvalue]
当以不带任何选项或参数的形式调用reg命令时,它将读取并打印目标机CPU
core的所有寄存器的当前值。
--list
该选项用来列出所有合法的CPU
core寄存器名字。该选项是可选的。
--name=regname
该选项用来指定所要读写的CPU
core寄存器名字。选项的参数值regname必须是--list选项列出的CPU core寄存器名字列表中的一个。该选项是必不可少的。
newvalue
非选项参数(non-option
argument)newvalue表示用户为某个CPU core寄存器设定的新值,它遵循前面所述的“JTAGER参数值表示规则”。该参数是可选的。如果newvalue非选项参数被指定,则被指定的新值被写入到指定的CPU core寄存器中。如果没有出现newvalue非选项参数,则读取指定的CPU
core寄存器的当前值。
JTAGER mem命令用来读写目标机上某个指定的内存空间区域。该命令必须在目标机CPU处于调试状态下才能使用。其调用语法如下:
mem --read --start-address=address
[--length=len] [--output=outfile]
mem --write --start-address=address
[--length=len] [--input=infile|--value=newvalue]
--read
该选项指定mem命令读取指定内存区域的当前值。
--write
该选项指定mem命令向内存区域中写入新值。
--start-address=address
该选项指定内存区域的起始地址值。选项参数值address遵循前述的“JTAGER参数值表示规则”。选项参数值address总是被向下圆整到32位字边界。
--length=len
该选项指定内存区域的大小,也即多少个32位字。选项参数值len遵循前述的“JTAGER参数值表示规则”。该选项是可选的。如果不指定内存区域的大小,那么默认的大小是1,也即我们缺省地总是读写1个内存字(word)单元。
--output=outfile
该选项指定将输出结果输出到outfile所指定的二进制文件中。选项参数值outfile指定二进制输出文件的全路径名。该选项是可选的,它只能被使用在内存读命令中,也即与--read选项一起使用。
--input=infile
该选项指示mem命令从二进制输入文件infile中读取输入数据。选项参数值infile指定二进制输入文件的全路径名。该选项只能被使用在内存写命令中,而且所写内存区域的大小必须大于1。
--value=newvalue
该选项指定向某个内存单元中写入的新值。选项参数值newvalue遵循前述的“JTAGER参数值表示规则”。该选项只能被使用在内存写命令中,而且所写内存区域的大小必须等于1。
JTAGER flash命令用于读写目标机上的Flash内存设备。该命令只能在目标机处于调试状态下使用。其调用语法如下:
flash [--list|--detect|--info] [chipname]
flash --set-params
[--chip-size=chipsize] [--start-address=address]
flash
--erase-sector|--erase-block|--erase-chip [sector-address|block-address]
flash --read --start-address=address
--length=len [--output=outfile]
flash --write --start-address=address
--length=len --input=infile
--list
该选项列出所有被JTAGER支持的flash芯片名字。
--detect
该选项指定flash命令检测目标机上是否存在指定的Flash设备。在进行任何flash读写操作之前,都必须首先使用该选项检测指定Flash设备的存在与否。如果检测成功,则指定的flash设备将被选择为当前flash设备。随后的flash读写操作均针是对当前flash设备而言的。
chipname
该非选项参数指定待检测的Flash设备的芯片名字。它必须是--list选项所列出的芯片名字之一。
--info
该选项指定flash命令打印显示当前flash设备的一般描述信息以及其CFI数据信息,一般性描述信息包括:flash设备的物理起始地址、flash设备的大小(字节数)、flash设备的扇区大小、flash设备的块大小、flash设备的宽度等信息。
--set-params
该选项指示flash命令修改当前flash设备的参数。可由用户修改的参数包括:flash芯片的大小(字节数)以及它在目标板上的起始物理地址。
--chip-size=chipsize
该选项指定当前选定的flash芯片的大小。注意:用户所指定的选项参数值chipsize必须如实反映当前flash芯片的大小(字节数),否则读写flash将可能产生意料之外的错误!
--erase-sector
该选项指示flash命令擦除指定的扇区。
--erase-block
该选项指示flash命令擦除指定的块。
--erase-chip
该选项指示flash命令擦除整个flash设备。
sector-address
当指定了--erase-sector选项时,该非选项参数指定待擦除的扇区地址。注意:只要是待擦除扇区中的任何一个地址值均可。该非选项参数值遵循“JTAGER参数值表示规则”。
block-address
当指定了--erase-block选项时,该非选项参数指定待擦除的块地址。注意:只要是待擦除块中的任何一个地址值均可。该非选项参数值遵循“JTAGER参数值表示规则”。
--read
该选项指示flash命令读取指定Flash内存区域的当前内容。
--write
该选项指示flash命令向指定Flash内存区域中写入新的内容。
--start-address=address
如果--set-params选项被指定,则这个选项指定当前flash芯片在目标板上的起始物理地址。否则,该选项指定待读写的Flash内存区域的起始物理地址。对于16位宽的Flash设备,选项参数值address将被向下圆整到16位字边界。而对于32位宽的Flash设备而言,选项参数值address将被向下圆整到32位字边界。选项参数值address遵循
“JTAGER参数值表示规则”。
注意:当用这个选项来配置当前flash芯片在目标板上的起始物理地址时,选项参数值address必须如实反映当前flash芯片在目标板上的起始物理地址,否则读写flash时可能会出现意料之外的错误!
--length=len
该选项指定待读写的Flash内存区域的大小,也即多少个字。至于字的具体大小则取决于当前Flash设备的宽度。选项参数值len遵循前述的“JTAGER参数值表示规则”。该选项是可选的。如果不指定Flash内存区域的大小,那么默认的大小是1,也即我们缺省地总是读写1个Flash内存字单元。
--output=outfile
该选项指定将输出结果输出到outfile所指定的二进制文件中。选项参数值outfile指定二进制输出文件的全路径名。该选项是可选的,它只能被使用在flash读命令中,也即与--read选项一起使用。
--input=infile
该选项指示flash写命令从二进制输入文件infile中读取输入数据。选项参数值infile指定二进制输入文件的全路径名。该选项只能被使用在flash写命令中,也即与--write选项一起使用。
正如前面所述,通过读取目标机的IDCODE值在一定程度上可以验证Host、JTAG仿真器与目标板三者之间连接的正确性。因此,在用户进入JTAGER程序后,在进行任何调试操作之前,最好先用idcode命令读取目标机的IDCODE值,以看看我们所读出的IDCODE值是否与用户特定CPU的IDCODE值相吻合。
对于我们的基于Samsung S3C44B0X CPU的目标板,通过idcode命令,我们可以得到如下信息:
JTAGER:>
idcode
Reading the JTAG Device ID code ... [OK]
Device ID = 0x1F0F0F0F
bit[0] = 1,
always be 1, required by IEEE Std 1149.1
Manufacturer
(bit[11:1]): 0x787 – SAMSUNG
Part number
(bit[27:12]): 0xF0F0
Version
(bit[31:28]) : 0x1
JTAGER:>
上述输出结果正是我们所期望的。一切看起来都似乎正常……接下来进入我们的正题。
用不带任何选项和参数的ice命令,就可以读到目标机上的所有ICE寄存器的当前值:
JTAGER:> ice
Reading all ICE registers:
Reading ICE debug
control register ... 0x00000000
Reading ICE debug status
register ... 0x00000004
Reading ICE abort status
register ... 0x00000000
Reading ICE DCC control
register ... 0x00000000
Reading ICE DCC data register
... 0x00300051
Reading ICE watchpoint 0
address value register ... 0xF5AF657E
Reading ICE watchpoint 0
address mask register ... 0xFE51A40E
Reading ICE watchpoint 0
data value register ... 0x45FE56FC
Reading ICE watchpoint 0
data mask register ... 0xF5287FDD
Reading ICE watchpoint 0
control value register ... 0x00000000
Reading ICE watchpoint 0
control mask register ... 0x00000000
Reading ICE watchpoint 1
address value register ... 0xDB8DEDBE
Reading ICE watchpoint 1
address mask register ... 0xED96B590
Reading ICE watchpoint 1
data value register ... 0x7C4FE3FB
Reading ICE watchpoint 1
data mask register ... 0xFFFFFFC7
Reading ICE watchpoint 1
control value register ... 0x00000000
Reading ICE watchpoint 1
control mask register ... 0x00000000
ICE调试控制寄存器和ICE调试状态寄存器是我们比较关心的两个寄存器。因此使用命令”ice --name=dbgctl” 和 “ice --name=dbgstat” 可以单独读取这个ICE寄存器的当前值:
JTAGER:> ice --name=dbgstat
Reading ICE debug status register ... 0x00000004
JTAGER:> ice --name=dbgctl
Reading ICE debug control register ... 0x00000000
JTAGER:>
目标机上的ICE寄存器在调试过程中起着至关重要的作用。
使用halt命令可以让目标机进入调试状态。对于基于ARM7TDMI core的目标机CPU而言,halt命令是通过将EmbeddedICE-RT logic的调试控制寄存器的bit[1]设置为1来向目标机CPU发出调试请求的。ARM7TDMI
core在收到ICE的调试请求后,将停止CPU的当前执行路径,进入调试状态,同时设置ICE调试状态寄存器的调试应答DBGACK位。
JTAGER:> halt
Requesting HALT target ... [OK]
The target is halted in ARM mode.
在成功地使目标机CPU进入调试状态后,halt命令会清除ICE调试控制寄存器的调试请求位。我们可以用ice命令看到ICE调试控制寄存器的值仍然为0,而ICE调试状态寄存器的值已经变为9,也即调试状态寄存器中的调试应答位DBGACK被置位。
JTAGER:> ice --name=dbgctl
Reading ICE debug control register ... 0x00000000
JTAGER:> ice --name=dbgstat
Reading ICE debug status register ... 0x00000009
在目标机CPU进入调试状态后,我们就可以进行调试操作了,如:读写CPU core寄存器、读写内存、读写Flash设备等等。
使用不带任何选项和参数的reg命令可以读取所有目标机CPU
core寄存器的当前值。
JTAGER:> reg
R0 = 0x00000000 R1 =
0x00000000 R2 = 0x00000000
R3 = 0x00000000 R4 =
0x00000000 R5 = 0x00000000
R6 =
0x00000000 R7 =
0x00000000 R8 = 0x00000000
R9 = 0x00000000 R10 =
0x00000000 R11 = 0x00000000
R12 = 0x00000000 R13 = 0x00000000 R14
= 0x00848130
R15 = 0x00455D6C PC = 0x00455D6C CPSR = 0xF00000D3
假定我们要向R1寄存器中写入一个新值0x23470DAE,这可以通过下列命令来完成:
JTAGER:> reg --name=r1 0x23470DAE
R1 register has been set new value 0x23470DAE, successfully.
JTAGER:>
通过下列命令我们可以读回R1寄存器的当前值,可以看出R1寄存器的确已经被设置为值0x23470DAE:
JTAGER:> reg --name=r1
R1 = 0x23470DAE
JTAGER:>
这里我们用内存读写操作来做一个小试验,那就是打开目标板(基于Samsung S3C44B0X CPU)上的蜂鸣器(BEEP)。相关的设备寄存器有三个:PCONE、PDATE、PUPE,地址分别是0x01d20028、0x01d2002c、0x01d20030。其中PCONE和PUPE是控制寄存器,应该被初始化为0x15569和0x08。PDATE是数据寄存器,其bit[3]控制着BEEP的开(bit[3] = 0)与关(bit[3] =
1),该寄存器应该被初始化为0x1ff。
首先用下列内存写命令序列初始化这个三个寄存器:
JTAGER:> mem --write --start-address=0x01d20030
--value=0x8
The value of memory unit 0x01D20030 has been changed to 0x00000008
successfully.
JTAGER:> mem --write --start-address=0x01d20028 --value=0x15569
The value of memory unit 0x01D20028 has been changed to 0x00015569 successfully.
JTAGER:> mem --write --start-address=0x01d2002c --value=0x1ff
The value of memory unit 0x01D2002C has been changed to 0x000001FF
successfully.
然后,可以下列内存读命令读回这个3个寄存器的值:
JTAGER:> mem --read --start-address=0x01d20028
--length=3
Read memory block 0x01D20028 - 0x01D20030 ... [OK]
0x01D20028:
00015569 000001FF 00000008
从上述输出结果可以看出,各初始值已被正确地写入。接下来,我们要清PDATE的bit[3]位以便打开BEEP,这可以通过向PDATE寄存器写入值0x1F7来实现:
JTAGER:> mem --write --start-address=0x01d2002c
--value=0x1f7
The value of memory unit 0x01D2002C has been changed to 0x000001F7
successfully.
执行上述命令后,我们就可以听到目标板上持续不断的BEEP声。在使用一次内存读命令可以看到PDATE寄存器的值已经变为0x1F7:
JTAGER:> mem --read --start-address=0x01d20028
--length=3
Read memory block 0x01D20028 - 0x01D20030 ... [OK]
0x01D20028:
00015569 000001F7 00000008
当然,这种声音太刺耳,赶紧把它关掉。这可以通过向PDATE寄存器写入值0x1ff来实现:
JTAGER:> mem --write --start-address=0x01d2002c --value=0x1ff
The value of memory unit 0x01D2002C has been changed to 0x000001FF
successfully.
执行上述命令后,刺耳的BEEP声消失了。最后,可以用一个简单的内存读命令看一看PDATE寄存器的当前值:
JTAGER:> mem --read --start-address=0x01d20028
Read memory block 0x01D2002c - 0x01D2002c ... [OK]
0x01D2002C:
000001FF
我的目标板在地址范围0x00000000 – 0x001FFFFF这2Mbytes的空间内配置了SST39VF160
Flash设备。
在进行flash读写操作之前,必须首先进行flash检测操作。对于我的目标板而言,这可以通过如下命令来完成:
JTAGER:> flash --detect sst39vf160
Detecting flash chip sst39vf160 ... [OK]
现在,SST39VF160已经被选定为我们的当前Flash设备。然后,我们可以--info选项来查看当前选定的flash设备的一般性描述信息和CFI信息:
JTAGER:>
flash --info
The current
selected flash chip : SST39VF160
Physical start address: 0x00000000
The
whole flash chip size (bytes): 2MB
Sector size: 4KB
Block size: 64KB
Flash bit width: 16-bit
Flash CFI information size (16-bit words): 37
Reading Flash
chip SST39VF160 CFI information: ... [OK]
0x0051 0x0052 0x0059
0x0001 0x0007 0x0000 0x0000 0x0000
0x0000 0x0000 0x0000
0x0027 0x0036 0x0000 0x0000 0x0004
0x0000 0x0004 0x0006
0x0001 0x0000 0x0001 0x0001 0x0015
0x0001 0x0000 0x0000
0x0000 0x0002 0x00ff 0x0001 0x0010
0x0000 0x001f 0x0000
0x0000 0x0001
请确信上述由“flash –info”命令输出的信息与您特定的flash芯片相吻合。您也可以使用--set-params选项来配置具体的flash芯片大小和该flash芯片在您目标板上的确却起始物理地址。接下来,我们可以进行flash读操作。我们将读取block 1(其块起始地址是0x10000)的sector 1(其扇区起始地址是0x11000)最开始的32个字(16-bit)。
JTAGER:> flash --read --start-address=0x11000
--length=32
Reading 16-bit flash chip SST39VF160 range 0x00011000 - 0x0001103E ...
[OK]
0x00011000: 0xFFFF 0xFFFF
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0xFFFF 0xFFFF
0x00011010: 0xFFFF 0xFFFF
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0xFFFF 0xFFFF
0x00011020: 0xFFFF 0xFFFF
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0xFFFF 0xFFFF
0x00011030: 0xFFFF 0xFFFF
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0xFFFF 0xFFFF
JTAGER:>
可以看出,该扇区的开始32个字(16-bit)并没有储存任何有效数据。接下来,我们准备一个包含有64字节数据的二进制文件data.bin。该数据文件可以包含任意的数据内容,下面是我所用的数据内容:
0x0102
0x1111 0x0600 0x0000 0x7FFC
0x0000 0x7FFC 0x0000
0x7FFC 0x0000 0x7FFC 0x0000
0x7FFC 0x0000 0x8000 0x0001
0x8000 0x0001 0x0459 0x0086
0x12AA 0x00DF 0x0630 0x5670
0xED52 0x1145 0x3322 0x5544
0x7766 0x9988 0xBBAA 0xDDCC
用下面的flash写命令将输入文件data.bin中的源数据写入到block 1的sector 1的最开始64个字节中:
JTAGER:> flash --write --start-address=0x11000
--length=32 --input=/root/data.bin
Writing 16-bit flash chip SST39VF160 0x00011000 - 0x0001103E ..... [OK]
JTAGER:>
接着,用flash读命令读回这64个字节的内容,从flash读命令的输出结果可以看出数据已被正确地写入:
JTAGER:> flash --read --start-address=0x11000
--length=32
Reading 16-bit flash chip SST39VF160 range 0x00011000 - 0x0001103E ...
[OK]
0x00011000:
0x0102 0x1111 0x0600 0x0000
0x7FFC 0x0000 0x7FFC 0x0000
0x00011010:
0x7FFC 0x0000 0x7FFC 0x0000
0x7FFC 0x0000 0x8000 0x0001
0x00011020:
0x8000 0x0001 0x0459 0x0086
0x12AA 0x00DF 0x0630 0x5670
0x00011030:
0xED52 0x1145 0x3322 0x5544
0x7766 0x9988 0xBBAA 0xDDCC
最后,我们还可以用flash扇区擦除操作擦除block
1的sector 1,使之回到原始的无效数据状态。
JTAGER:> flash --erase-sector 0x11000
Erase flash SST39VF160 sector 0x00011000 - 0x00011FFF ..... [OK]
JTAGER:> flash --read --start-address=0x11000 --length=32
Reading 16-bit flash chip SST39VF160 range 0x00011000 - 0x0001103E ...
[OK]
0x00011000:
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0x00011010:
0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF
0x00011020:
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0x00011030:
0xFFFF 0xFFFF 0xFFFF 0xFFFF
0xFFFF 0xFFFF 0xFFFF 0xFFFF