Next: Flash Commands, Previous: TAP Declaration, Up: Top [Contents][Index]
This chapter discusses how to set up GDB debug targets for CPUs. You can also access these targets without GDB (see Architecture and Core Commands, and Target State handling) and through various kinds of NAND and NOR flash commands. If you have multiple CPUs you can have multiple such targets.
We’ll start by looking at how to examine the targets you have, then look at how to add one more target and how to configure it.
All targets that have been set up are part of a list,
where each member has a name.
That name should normally be the same as the TAP name.
You can display the list with the targets
(plural!) command.
This display often has only one CPU; here’s what it might
look like with more than one:
TargetName Type Endian TapName State -- ------------------ ---------- ------ ------------------ ------------ 0* at91rm9200.cpu arm920t little at91rm9200.cpu running 1 MyTarget cortex_m little mychip.foo tap-disabled
One member of that list is the current target, which
is implicitly referenced by many commands.
It’s the one marked with a *
near the target name.
In particular, memory addresses often refer to the address
space seen by that current target.
Commands like mdw
(memory display words)
and flash erase_address
(erase NOR flash blocks)
are examples; and there are many more.
Several commands let you examine the list of targets:
Note: target numbers are deprecated; don’t use them.
They will be removed shortly after August 2010, including this command.
Iterate target using target names
, not by counting.
Returns the number of targets, N. The highest numbered target is N - 1.
set c [target count] for { set x 0 } { $x < $c } { incr x } { # Assuming you have created this function print_target_details $x }
Returns the name of the current target.
Lists the names of all current targets in the list.
foreach t [target names] { puts [format "Target: %s\n" $t] }
Note: target numbers are deprecated; don’t use them. They will be removed shortly after August 2010, including this command.
The list of targets is numbered starting at zero. This command returns the name of the target at index number.
set thename [target number $x] puts [format "Target %d is: %s\n" $x $thename]
Note: the name of this command is plural. Other target command names are singular.
With no parameter, this command displays a table of all known targets in a user friendly form.
With a parameter, this command sets the current target to the given target with the given name; this is only relevant on boards which have more than one target.
Each target has a CPU type, as shown in the output of
the targets
command. You need to specify that type
when calling target create
.
The CPU type indicates more than just the instruction set.
It also indicates how that instruction set is implemented,
what kind of debug support it integrates,
whether it has an MMU (and if so, what kind),
what core-specific commands may be available
(see Architecture and Core Commands),
and more.
For some CPU types, OpenOCD also defines variants which indicate differences that affect their handling. For example, a particular implementation bug might need to be worked around in some chip versions.
It’s easy to see what target types are supported, since there’s a command to list them. However, there is currently no way to list what target variants are supported (other than by reading the OpenOCD source code).
Lists all supported target types. At this writing, the supported CPU types and variants are:
arm11
– this is a generation of ARMv6 cores
arm720t
– this is an ARMv4 core with an MMU
arm7tdmi
– this is an ARMv4 core
arm920t
– this is an ARMv4 core with an MMU
arm926ejs
– this is an ARMv5 core with an MMU
arm966e
– this is an ARMv5 core
arm9tdmi
– this is an ARMv4 core
avr
– implements Atmel’s 8-bit AVR instruction set.
(Support for this is preliminary and incomplete.)
cortex_a
– this is an ARMv7 core with an MMU
cortex_m
– this is an ARMv7 core, supporting only the
compact Thumb2 instruction set.
dragonite
– resembles arm966e
dsp563xx
– implements Freescale’s 24-bit DSP.
(Support for this is still incomplete.)
fa526
– resembles arm920 (w/o Thumb)
feroceon
– resembles arm926
mips_m4k
– a MIPS core. This supports one variant:
xscale
– this is actually an architecture,
not a CPU type. It is based on the ARMv5 architecture.
There are several variants defined:
ixp42x
, ixp45x
, ixp46x
,
pxa27x
... instruction register length is 7 bits
pxa250
, pxa255
,
pxa26x
... instruction register length is 5 bits
pxa3xx
... instruction register length is 11 bits
openrisc
– this is an OpenRISC 1000 core.
The current implementation supports three JTAG TAP cores:
OpenCores TAP
(See: http://opencores.org/project,jtag)
Altera Virtual JTAG TAP
(See: http://www.altera.com/literature/ug/ug_virtualjtag.pdf)
Xilinx BSCAN_* virtual JTAG interface
(See: http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/spartan6_hdl.pdf)
And two debug interfaces cores:
Advanced debug interface
(See: http://opencores.org/project,adv_debug_sys)
SoC Debug Interface
(See: http://opencores.org/project,dbg_interface)
To avoid being confused by the variety of ARM based cores, remember this key point: ARM is a technology licencing company. (See: http://www.arm.com.) The CPU name used by OpenOCD will reflect the CPU design that was licenced, not a vendor brand which incorporates that design. Name prefixes like arm7, arm9, arm11, and cortex reflect design generations; while names like ARMv4, ARMv5, ARMv6, and ARMv7 reflect an architecture version implemented by a CPU design.
Before creating a “target”, you must have added its TAP to the scan chain.
When you’ve added that TAP, you will have a dotted.name
which is used to set up the CPU support.
The chip-specific configuration file will normally configure its CPU(s)
right after it adds all of the chip’s TAPs to the scan chain.
Although you can set up a target in one step, it’s often clearer if you use shorter commands and do it in two steps: create it, then configure optional parts. All operations on the target after it’s created will use a new command, created as part of target creation.
The two main things to configure after target creation are a work area, which usually has target-specific defaults even if the board setup code overrides them later; and event handlers (see Target Events), which tend to be much more board-specific. The key steps you use might look something like this
target create MyTarget cortex_m -chain-position mychip.cpu $MyTarget configure -work-area-phys 0x08000 -work-area-size 8096 $MyTarget configure -event reset-deassert-pre { jtag_rclk 5 } $MyTarget configure -event reset-init { myboard_reinit }
You should specify a working area if you can; typically it uses some on-chip SRAM. Such a working area can speed up many things, including bulk writes to target memory; flash operations like checking to see if memory needs to be erased; GDB memory checksumming; and more.
Warning: On more complex chips, the work area can become inaccessible when application code (such as an operating system) enables or disables the MMU. For example, the particular MMU context used to acess the virtual address will probably matter ... and that context might not have easy access to other addresses needed. At this writing, OpenOCD doesn’t have much MMU intelligence.
It’s often very useful to define a reset-init
event handler.
For systems that are normally used with a boot loader,
common tasks include updating clocks and initializing memory
controllers.
That may be needed to let you write the boot loader into flash,
in order to “de-brick” your board; or to load programs into
external DDR memory without having run the boot loader.
This command creates a GDB debug target that refers to a specific JTAG tap.
It enters that target into a list, and creates a new
command (target_name
) which is used for various
purposes including additional configuration.
-chain-position dotted.name
configparam.
This name is also used to create the target object command,
referred to here as $target_name
,
and in other places the target needs to be identified.
$target_name configure
are permitted.
If the target is big-endian, set it here with -endian big
.
If the variant matters, set it here with -variant
.
You must set the -chain-position dotted.name
here.
The options accepted by this command may also be
specified as parameters to target create
.
Their values can later be queried one at a time by
using the $target_name cget
command.
Warning: changing some of these after setup is dangerous. For example, moving a target from one TAP to another; and changing its endianness or variant.
-chain-position
dotted.name – names the TAP
used to access this target.
-endian
(big|little) – specifies
whether the CPU uses big or little endian conventions
-event
event_name event_body –
See Target Events.
Note that this updates a list of named event handlers.
Calling this twice with two different event names assigns
two different handlers, but calling it twice with the
same event name assigns only one handler.
-variant
name – specifies a variant of the target,
which OpenOCD needs to know about.
-work-area-backup
(0|1) – says
whether the work area gets backed up; by default,
it is not backed up.
When possible, use a working_area that doesn’t need to be backed up,
since performing a backup slows down operations.
For example, the beginning of an SRAM block is likely to
be used by most build systems, but the end is often unused.
-work-area-size
size – specify work are size,
in bytes. The same size applies regardless of whether its physical
or virtual address is being used.
-work-area-phys
address – set the work area
base address to be used when no MMU is active.
-work-area-virt
address – set the work area
base address to be used when an MMU is active.
Do not specify a value for this except on targets with an MMU.
The value should normally correspond to a static mapping for the
-work-area-phys
address, set up by the current operating system.
-rtos
rtos_type – enable rtos support for target,
rtos_type can be one of auto|eCos|ThreadX|
FreeRTOS|linux|ChibiOS|embKernel
See RTOS Support.
The Tcl/Tk language has the concept of object commands, and OpenOCD adopts that same model for targets.
A good Tk example is a on screen button. Once a button is created a button has a name (a path in Tk terms) and that name is useable as a first class command. For example in Tk, one can create a button and later configure it like this:
# Create button .foobar -background red -command { foo } # Modify .foobar configure -foreground blue # Query set x [.foobar cget -background] # Report puts [format "The button is %s" $x]
In OpenOCD’s terms, the “target” is an object just like a Tcl/Tk button, and its object commands are invoked the same way.
str912.cpu mww 0x1234 0x42 omap3530.cpu mww 0x5555 123
The commands supported by OpenOCD target objects are:
Internal OpenOCD scripts (most notably startup.tcl) use these to deal with specific reset cases. They are not otherwise documented here.
These provide an efficient script-oriented interface to memory.
The array2mem
primitive writes bytes, halfwords, or words;
while mem2array
reads them.
In both cases, the TCL side uses an array, and
the target side uses raw memory.
The efficiency comes from enabling the use of
bulk JTAG data transfer operations.
The script orientation comes from working with data
values that are packaged for use by TCL scripts;
mdw
type primitives only print data they retrieve,
and neither store nor return those values.
Each configuration parameter accepted by
$target_name configure
can be individually queried, to return its current value.
The queryparm is a parameter name
accepted by that command, such as -work-area-phys
.
There are a few special cases:
-event
event_name – returns the handler for the
event named event_name.
This is a special case because setting a handler requires
two parameters.
-type
– returns the target type.
This is a special case because this is set using
target create
and can’t be changed
using $target_name configure
.
For example, if you wanted to summarize information about all the targets you might use something like this:
foreach name [target names] { set y [$name cget -endian] set z [$name cget -type] puts [format "Chip %d is %s, Endian: %s, type: %s" \ $x $name $y $z] }
Displays the current target state:
debug-running
,
halted
,
reset
,
running
, or unknown
.
(Also, see Event Polling.)
Displays a table listing all event handlers currently associated with this target. See Target Events.
Invokes the handler for the event named event_name. (This is primarily intended for use by OpenOCD framework code, for example by the reset code in startup.tcl.)
Display contents of address addr, as
32-bit words (mdw
), 16-bit halfwords (mdh
),
or 8-bit bytes (mdb
).
If count is specified, displays that many units.
(If you want to manipulate the data instead of displaying it,
see the mem2array
primitives.)
Writes the specified word (32 bits), halfword (16 bits), or byte (8-bit) pattern, at the specified address addr.
At various times, certain things can happen, or you want them to happen. For example:
All of the above items can be addressed by target event handlers.
These are set up by $target_name configure -event
or
target create ... -event
.
The programmer’s model matches the -command
option used in Tcl/Tk
buttons and events. The two examples below act the same, but one creates
and invokes a small procedure while the other inlines it.
proc my_attach_proc { } { echo "Reset..." reset halt } mychip.cpu configure -event gdb-attach my_attach_proc mychip.cpu configure -event gdb-attach { echo "Reset..." # To make flash probe and gdb load to flash work we need a reset init. reset init }
The following target events are defined:
reset init
)
reset halt
)
reset
processing
after reset_init
was triggered
but before either SRST alone is re-asserted on the scan chain,
or reset-assert
is triggered.
reset
processing
after reset-assert-pre
was triggered.
When such a handler is present, cores which support this event will use
it instead of asserting SRST.
This support is essential for debugging with JTAG interfaces which
don’t include an SRST line (JTAG doesn’t require SRST), and for
selective reset on scan chains that have multiple targets.
reset
processing
after reset-assert
has been triggered.
or the target asserted SRST on the entire scan chain.
reset
processing
after reset-assert-post
has been triggered.
reset
processing
after reset-deassert-pre
has been triggered
and (if the target is using it) after SRST has been
released on the scan chain.
reset
processing.
This is where you would configure PLLs and clocking, set up DRAM so you can download programs that don’t fit in on-chip SRAM, set up pin multiplexing, and so on. (You may be able to switch to a fast JTAG clock rate here, after the target clocks are fully set up.)
reset
processing
before reset_init
is called.
This is the most robust place to use jtag_rclk
or adapter_khz
to switch to a low JTAG clock rate,
when reset disables PLLs needed to use a fast clock.
Next: Flash Commands, Previous: TAP Declaration, Up: Top [Contents][Index]