- 0.2.0, 2004-09-25
- 0.1.0, 2003-11-30
Copyright
(C) 2003 2004, Rongkai Zhan (Chinese Name: 詹荣开)
1 Introduction
1.1 What is JTAGER
1.2 The List of Devices Supported
2 Build and Configuration
3 The Commands Set
of JTAGER
3.1 Command Syntax Rules
3.2 Commands Group
3.3 Reset Command
3.4 Help Command
3.5 Idcode Command
3.6 Exit/quit Commands
3.7 Halt Command
3.8 Restart Command
3.9 Ice Command
3.10 Reg Command
3.11 Execbat Command
3.12 Memcmp Command
3.13 Memcpy Command
3.14 Memcsum Command
3.15 Memdump Command
3.16 Memset Command
3.17 Memtest Command
3.18 Flprobe Command
3.19 Flerase Command
3.20 Flwrite Command
JTAGER is a simple embedded system debugger running on the Linux host. By JTAGER, we can: 1) read or write the core registers of the CPU on the embedded target board. 2) Read or write the external device registers of the target board. 3) Read or write the RAM on the target board. 4) Read or write the solid storage device on the target board, such as Flash.
+------------+ +--------------------+ +--------------+ | | | | | | | | | | | | | Debug Host | <-----> | Protocol Converter | <-----> | Debug Target | | | | | | | | | | | | | +------------+ +--------------------+ +--------------+ | | | | V V The host running For example, Multi-ICE, the debug toolkits Wiggler-compatible JTAG (such JTAGER) dongle, etc. Figure 1 A typical embedded debug system
|
To
debug the embedded target board, we need to use a protocol converter
based on JTAG interface to transfer signal and data between the host
side and the target side. Figure 1 can demonstrate a typical
embedded debug system.
Because it is very simple and very cheap, the MacriagorWiggler-compatible JTAG dongles are used most frequently. The circuit diagram can be found here:
(1) The types of target CPU core
(2) The types of JTAG interfaces
(3) The types of FLASH chips
Because
the root privilege is needed to install and run JTAGER, so we assume
that you have get the root privilege of your Linux host. If not, please
contact with the administrator.
First,
download the JTAGER package and place it in some directory, such as the
“/tmp” directory. Follow the following steps to unpack it.
#cd /tmp #tar zxvf jtager-0.1.0.tar.gz #cd jtager-0.1.0 |
Then,
run configure script and compile:
#configure
--prefix=/usr/local/jtager #make all |
Finally,
run “make install” to install JTAGER to your specified path (the
default path is /usr/local):
#make install |
To run
JTAGER, type “./jtager” and press <ENTER>:
#cd /usr/local/jtager/bin #./jtager |
JTAGER
is a program driven by commands. When users run JTAGER program in shell,
JTAGER will print its command prompt – “JTAGER:>”, after outputting some logo
informations.
All
JTAGER commands, command options and arguments are case-insensitive, and
separated by the space character.
All
JTAGER commands use the GNU-style long-named options. That is, each
JTAGER command option is leaded by two consecutive chars ‘-‘. For example:
JTAGER:> ice --list |
JTAGER
command options may be followed its option argument, for example:
JTAGER:> memdump --base=0x01c80000 |
JTAGER
commands also maybe have non-option arguments. For example, in the
following JTAGER command, “0x111” is a non-option argument:
JTAGER:> reg --name=r0 0x111 |
*)
The rule for JTAGER command arguments representation
Any
arguments are a string or an integer. For an integer argument, it can
use the hexadecimal representation or the decimal representation. For
example, these hex representations — “0xff0 0Xff0 ff0H FF0h” can all be accepted
by JTAGER. If not explicitly using hex representation like these, the
arguments are treated as decimal number by default. All option arguments
and non-option arguments of each JTAGER command comply with this rule.
*)
The rule for memory block size representation
This
rule is for the '--size' option, which is used to specify the memory
block size. Anyhow, the argument of the '--size' option is sure to obey
the rule for command arguments representation (see 1.1). To specify how
many bytes (8-bit), how many half-words (16-bit), or how many words
(32-bits), we can append a suffix character 'b' 'B' 's' 'S' 'w' or 'W'
to the option argument of the '--size' option, and we call the suffix
character "the size indicator suffix". For example:
JTAGER:> memdump 0x01c80000 --size=0xfb
or
JTAGER:> memdump 0x01c80000 --size=0xfB
The
above commands will dump the contents of the memory block [0x01C800000,
0x01C80000F], whose size is 0xF bytes.
ATTENTION
PLEASE: Because the character 'b' or 'B' is also a hexadeciamal char,
'--size=0xfb' doesn't means the memory block size is 251 (=0xFB) bytes.
Therefore, if you want to specify the memory block size is 251 bytes,
you should
use '--size=0xFBB'.
To specify how
many half-word the memory block is, we can use the following commands:
JTAGER:> memdump 0x01c80000 --size=0xfs
or
JTAGER:> memdump 0x01c80000 --size=0xfS
NOTE: The
suffix 's' or 'S' means short.
If there is no
suffix character, we means how many words by default. For example, the
following command will dump the memory block [0x01C00000, 0x01C0003C],
whose size is 15 words:
JTAGER:> memdump 0x01c80000 --size=0xf
Of course, you
also can explicitly specify that its size is 15 words:
JTAGER:> memdump 0x01c80000 --size=0xfw
or
JTAGER:> memdump 0x01c80000 --size=0xfW
NOTE: All
'--size' options obey this rule. And the '--size' option has a default
value: 1 word.
To
more exactly express the function of each JTAGER command, we separate
all JTAGER commands into two groups: 1) the base commands group. 2) The
debug commands group.
The
basic commands group contains five JTAGER commands:
The
debug commands group contains the following commands:
The
JTAGER reset command can be used to reset the JTAG link between your
host side and your target side, and bring the TAP controller of your
target CPU into the Run-Test/Idle state. You can refer to IEEE Standard
1149.1 – 1990 <<IEEE Standard Test Access Port and Boundary-Scan
Architecture>> for more information about the TAP controller state
machine.
This
command has no any options or arguments. Command syntax:
reset |
The
JTAGER help command can show the help information of some specified
JTAGER command, or print a list of all available JTAGER commands.
Command
syntax:
help [[--cmdname=]cmdname] |
The
option argument cmdname is optional, and can be any
legal JTAGER command name string. If the argument cmdname is not specified, the help
command will print a list of all JTAGER commands. The list contains into
two columns, which are separated by the tab character ‘\t’. The first
column is command name string; the second one is the command description
string.
For
example, you can type “help help” to get the help information
about the help command:
USAGE: help
[[--cmdname=]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. |
The
JTAGER idcode command is used to read the IDCODE value of your target
CPU. Generally speaking, each embedded CPU with the support of JTAG test
has a unique 32-bit IDCODE value. According to the JEDEC standard and
<<IEEE Std 1149.1>>, the bit[0] of IDCODE value must always
be 1, its bit[11 : 1] represents the unique manufacturer ID, its bit[27
: 12] represents the product ID number, and its bit[31 : 28] represents
version number. Each kind of CPU has different IDCODE value. Refer to
the BSDL file of your target CPU to get its specific IDCODE value.
The
JTAGER idcode command has no any command options or arguments. Its
command syntax:
idcode |
Another
use of the JTAGER idcode command is to check whether the link between
host, JTAG emulator and target is ok. Before using the halt command to
enter the debug state, user had better use the idcode command to read
back the IDCODE value of your target. If the value we read back is equal
to the specific IDCODE value of your target CPU, it seems that
everything is ok J
For
example, for author’s test board that is based on Samsung S3C44B0X CPU,
the call to idcode command will print the following information:
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 |
The
value 0x1F0F0F0F read back is just the one the
author expects for his Samsung S3C44B0X CPU.
Both
the JTAGER exit command and the quit command can be used to exit JTAGER
program. They are equivalent. Their command syntax:
exit or quit |
The
JTAGER halt command can make your target CPU enter into the debug state
by sending DEBUG request to your target CPU. After receiving the DEBUG
request, the target CPU will stop its current execution path and enter
the debug state. When in the debug state, the target CPU is not driven
by its internal clock pulse signal, and is fully controlled by the debug
clock pulse signal from user’s host side.
The
JTAGER halt command has no any options or arguments. Its command syntax:
halt |
The
JTAGER halt command is the bases of the other JTAGER debug commands
(such as reg, mem and flash commands). Only if the target is halted into
the debug state, the other debug commands can be used, otherwise they
will print an error message like this:
Error: The target is running.
Please use "halt" command to halt it. |
The
JTAGER restart command can end user’s current debug session created by
the last call to the halt command, and make the target CPU return to the
normal system state, that is, the target CPU resumes its execution from
the last halted point.
Command
syntax:
restart -–pc=address |
The
JTAGER ice command can read or write the contents of the EmbeddedICE-RT
logic’s registers in your target CPU.
Command
syntax:
ice [--list] ice --name=regname [[--value=]newvalue] |
When
the command is called with no any options and arguments, it will read
and print the contents of all ICE registers.
--list
The option is used to list all legal ICE
registers short names. It is optional.
--name=regname
The option is used to specify the name of the
register to read or write. Its option argument regnamemust be one of the names listed
by the --list option.
--value=newvalue
The option --value represents the new value set for
the specified ICE register. It is optional. If it is specified, then the
specified new value will be written into the specified ICE register.
Otherwise, the ice command will read the current value of the specified
ICE register.
The
JTAGER reg command can read or write the core registers of the target
CPU. NOTE: this command must be used only if the target CPU is in the
debug state.
The
command syntax of this command is similar with the one of the JTAGER ice
command. Its command syntax:
reg [--list] reg --name=regname [[--value=]newvalue] |
When
the command is called with no any options and arguments, it will read
and print the current contents of all core registers of your target CPU.
--list
The option is used to list all legal CPU core
registers names. It is optional.
--name=regname
The option is used to specify the name of the
register to read or write. Its option argument regname must be one of the CPU core
register names listed by the --list option.
--value=newvalue
The option --value represents the new value set for
the specified core register. It is optional. If it is specified, then
the specified new value will be written into the specified CPU core
register. Otherwise, the reg command will read the current value of the
specified CPU core register.
DESCRIPTION:
Execute a jtager batch-command file
SYNTAX: execbat /your/jtager/batch/file
A jtager batch command file is a file containing a sequence of jtager
commands. The main purposal of a jtager batch command file is that we
can write some jtager commands to initialize a raw target board. In a
raw target board, the ram space is usually not available, and the UART
is also not available too. Therefore, we can put some jtager commands
used to setup the memory controller or UART port in a jtager batch
command file.
In the source tarball of jtager, the "extra/s3c44b0x-init.bat" is a
jtager batch command file for initializing my S3C44B0X develop board.
When you write yourself jtager batch command file, you can use this file
as a template.
For example, the following command will initialize my S3C44B0X board:
JTAGER:> execbat /root/jtager/extra/s3c44b0x-init.bat
*** line 12: reg --name=cpsr --value=0x000000D3
CPSR register has been set new value 0x000000D3, successfully.
*** line 17: memset 0x01D30000 --value=0x0
*** line 22: memset 0x01d80000 --value=0x34021
*** line 23: memset 0x01d80004 --value=0x7ff8
*** line 24: memset 0x01d80008 --value=0x09
......
DESCRIPTION:
Copy memory block from one to another
SYNTAX: memcpy --to=addr1 --from=addr2 [[--size=]count]
The option '--to' specifies the base address of the destination memory
block, while the option '--from' specifies the base address of the
source memory block. The option '--size' specifies the size of these two
memory blocks.
For example, the following command will copy the contents of the memory
block [0x0C100000, 0x0C101000) to the memory block [0x0C200000,
0x0C201000):
JTAGER:> memcpy --to=0x0C200000 --from=0x0C100000 --size=0x1000b
memcpy: [0x0C100000, 0x0C101000) => [0x0C200000, 0x0C201000) ...
[OK]
Total 4096 bytes are copied.
After executing the above command, we run 'memcmp' command again, and
will find these two memory blocks are the same:
JTAGER:> memcmp --base1=0x0C100000 --base2=0x0C200000
--size=0x1000b
memcmp: [0x0C100000, 0x0C101000) =?= [0x0C200000, 0x0C201000) ....
[YES]
DESCRIPTION: Copy memory block from one to another
SYNTAX: memcpy --to=addr1 --from=addr2 [[--size=]count]
The option '--to' specifies the base address of the destination memory
block, while the option '--from' specifies the base address of the
source memory block. The option '--size' specifies the size of these two
memory blocks.
For example, the following command will copy the contents of the memory
block [0x0C100000, 0x0C101000) to the memory block [0x0C200000,
0x0C201000):
JTAGER:> memcpy --to=0x0C200000 --from=0x0C100000 --size=0x1000b
memcpy: [0x0C100000, 0x0C101000) => [0x0C200000, 0x0C201000) ...
[OK]
Total 4096 bytes are copied.
After executing the above command, we run 'memcmp' command again, and
will find these two memory blocks are the same:
JTAGER:> memcmp --base1=0x0C100000 --base2=0x0C200000
--size=0x1000b
memcmp: [0x0C100000, 0x0C101000) =?= [0x0C200000, 0x0C201000) ....
[YES]
DESCRIPTION: Calculate the MD5 sum of a memory
block
SYNTAX: memcsum/md5sum [--base=]addr [--size=count]
ALIAS: md5sum
The option '--base' specifies the base address of the memory block,
while the option '--size' specifies the size of the memory block.
For example, the following command will calculate the MD5 sum of the
memory block [0x0C100000, 0x0C101000):
JTAGER:> md5sum 0x0C100000 --size=0x1000b
e95065d361b843a7025a63830273fde8 memory block [0x0C100000,
0x0C100FFF]
From the above output information, we know that the MD5 sum of memory
block [0x0C100000, 0x0C101000) is:
e95065d361b843a7025a63830273fde8
DESCRIPTION: Display the contents of a memory block
SYNTAX: memdump [--base=]addr [--size=count]
For example, the following command will dump the memory block
[0x0C100000, 0x0C100040) by the byte-output way:
JTAGER:> memdump 0x0C100000 --size=64b
0x0C100000: FF FF FB F7 FF FF FF FE FF BF F7 FF FF FD FF FF
|................|
0x0C100010: FF FF FF FF FF FD FF FF FF F5 FB FF FF FF FE FF
|................|
0x0C100020: FF FF FF FF FF FD FF FF FF FF FF FF FF FF FF FD
|................|
0x0C100030: FF FF FF FF EF FF FF FF FF FF FF FF FF FF FF FE
|................|
The following command will dump the memory block by the memory block
[0x0C100000, 0x0C100040) by the half-word output way:
JTAGER:> memdump 0x0C100000 --size=32s
0x0C100000: FFFF F7FB FFFF FEFF BFFF FFF7 FDFF FFFF
|................|
0x0C100010: FFFF FFFF FDFF FFFF F5FF FFFB FFFF FFFE
|................|
0x0C100020: FFFF FFFF FDFF FFFF FFFF FFFF FFFF FDFF
|................|
0x0C100030: FFFF FFFF FFEF FFFF FFFF FFFF FFFF FEFF
|................|
And The following command will dump the memory block by the memory
block [0x0C100000, 0x0C100040) by the word-output way:
JTAGER:> memdump 0x0C100000 --size=16
0x0C100000: F7FBFFFF FEFFFFFF FFF7BFFF FFFFFDFF
|................|
0x0C100010: FFFFFFFF FFFFFDFF FFFBF5FF FFFEFFFF
|................|
0x0C100020: FFFFFFFF FFFFFDFF FFFFFFFF FDFFFFFF
|................|
0x0C100030: FFFFFFFF FFFFFFEF FFFFFFFF FEFFFFFF
|................|
DESCRIPTION: Test if a memory block is fully
read-able and write-able.
SYNTAX: memtest [--base=]addr [--size=count]
For example, the following command will test if the memory block
[0x0C100000, 0x0C101000) is fully read-able
and write-able:
JTAGER:> memtest 0x0C100000 --size=0x1000b
memtest: testing if the memory block [0xC100000, 0xC100FFF] are
fully read-able and write-able ... [OK]
Because the memory block is a ram block, it is fully read-able and
write-able, of course.
DESCRIPTION: Probe flash chips at the specified
base address.
SYNTAX: flprobe [[--chip-base=]addr]
The option '--chip-base' is optional, its default argument is 0x00. For
example, the following command will
probe flash chip at the base address 0x00:
JTAGER:> flprobe
Probing flash chip at 0x00000000 ... [found : sst39vf160]
base address: 0x00000000
chip size: 2048 KB
sector size: 4 KB
bus width: 16-bit
DESCRIPTION:
Erase one FLASH sector or the whole chip.
SYNTAX: flerase --whole-chip
flerase [--sector-address=]addr
For example, the following command will erase the flash sector
[0x101000, 0x102000):
JTAGER:> flerase 0x101000
Erasing sst39vf160 flash sector [0x00101000, 0x00102000) ...... [OK]
|
|
|
|
|
|
|
|
|
|
|
|
|
|