Next: Daemon Configuration, Previous: OpenOCD Project Setup, Up: Top [Contents][Index]
This chapter is aimed at any user who needs to write a config file, including developers and integrators of OpenOCD and any user who needs to get a new board working smoothly. It provides guidelines for creating those files.
You should find the following directories under $(INSTALLDIR)/scripts, with files including the ones listed here. Use them as-is where you can; or as models for new files.
$ ls interface -R interface/: altera-usb-blaster.cfg hilscher_nxhx50_re.cfg openocd-usb-hs.cfg arm-jtag-ew.cfg hitex_str9-comstick.cfg openrd.cfg at91rm9200.cfg icebear.cfg osbdm.cfg axm0432.cfg jlink.cfg parport.cfg busblaster.cfg jtagkey2.cfg parport_dlc5.cfg buspirate.cfg jtagkey2p.cfg redbee-econotag.cfg calao-usb-a9260-c01.cfg jtagkey.cfg redbee-usb.cfg calao-usb-a9260-c02.cfg jtagkey-tiny.cfg rlink.cfg calao-usb-a9260.cfg jtag-lock-pick_tiny_2.cfg sheevaplug.cfg chameleon.cfg kt-link.cfg signalyzer.cfg cortino.cfg lisa-l.cfg signalyzer-h2.cfg digilent-hs1.cfg luminary.cfg signalyzer-h4.cfg dlp-usb1232h.cfg luminary-icdi.cfg signalyzer-lite.cfg dummy.cfg luminary-lm3s811.cfg stlink-v1.cfg estick.cfg minimodule.cfg stlink-v2.cfg flashlink.cfg neodb.cfg stm32-stick.cfg flossjtag.cfg ngxtech.cfg sysfsgpio-raspberrypi.cfg flossjtag-noeeprom.cfg olimex-arm-usb-ocd.cfg ti-icdi.cfg flyswatter2.cfg olimex-arm-usb-ocd-h.cfg turtelizer2.cfg flyswatter.cfg olimex-arm-usb-tiny-h.cfg ulink.cfg ftdi olimex-jtag-tiny.cfg usb-jtag.cfg hilscher_nxhx10_etm.cfg oocdlink.cfg usbprog.cfg hilscher_nxhx500_etm.cfg opendous.cfg vpaclink.cfg hilscher_nxhx500_re.cfg opendous_ftdi.cfg vsllink.cfg hilscher_nxhx50_etm.cfg openocd-usb.cfg xds100v2.cfg interface/ftdi: axm0432.cfg hitex_str9-comstick.cfg olimex-jtag-tiny.cfg calao-usb-a9260-c01.cfg icebear.cfg oocdlink.cfg calao-usb-a9260-c02.cfg jtagkey2.cfg opendous_ftdi.cfg cortino.cfg jtagkey2p.cfg openocd-usb.cfg dlp-usb1232h.cfg jtagkey.cfg openocd-usb-hs.cfg dp_busblaster.cfg jtag-lock-pick_tiny_2.cfg openrd.cfg flossjtag.cfg kt-link.cfg redbee-econotag.cfg flossjtag-noeeprom.cfg lisa-l.cfg redbee-usb.cfg flyswatter2.cfg luminary.cfg sheevaplug.cfg flyswatter.cfg luminary-icdi.cfg signalyzer.cfg gw16042.cfg luminary-lm3s811.cfg signalyzer-lite.cfg hilscher_nxhx10_etm.cfg minimodule.cfg stm32-stick.cfg hilscher_nxhx500_etm.cfg neodb.cfg turtelizer2-revB.cfg hilscher_nxhx500_re.cfg ngxtech.cfg turtelizer2-revC.cfg hilscher_nxhx50_etm.cfg olimex-arm-usb-ocd.cfg vpaclink.cfg hilscher_nxhx50_re.cfg olimex-arm-usb-ocd-h.cfg xds100v2.cfg hitex_lpc1768stick.cfg olimex-arm-usb-tiny-h.cfg $
$ ls board actux3.cfg lpc1850_spifi_generic.cfg am3517evm.cfg lpc4350_spifi_generic.cfg arm_evaluator7t.cfg lubbock.cfg at91cap7a-stk-sdram.cfg mcb1700.cfg at91eb40a.cfg microchip_explorer16.cfg at91rm9200-dk.cfg mini2440.cfg at91rm9200-ek.cfg mini6410.cfg at91sam9261-ek.cfg netgear-dg834v3.cfg at91sam9263-ek.cfg olimex_LPC2378STK.cfg at91sam9g20-ek.cfg olimex_lpc_h2148.cfg atmel_at91sam7s-ek.cfg olimex_sam7_ex256.cfg atmel_at91sam9260-ek.cfg olimex_sam9_l9260.cfg atmel_at91sam9rl-ek.cfg olimex_stm32_h103.cfg atmel_sam3n_ek.cfg olimex_stm32_h107.cfg atmel_sam3s_ek.cfg olimex_stm32_p107.cfg atmel_sam3u_ek.cfg omap2420_h4.cfg atmel_sam3x_ek.cfg open-bldc.cfg atmel_sam4s_ek.cfg openrd.cfg balloon3-cpu.cfg osk5912.cfg colibri.cfg phone_se_j100i.cfg crossbow_tech_imote2.cfg phytec_lpc3250.cfg csb337.cfg pic-p32mx.cfg csb732.cfg propox_mmnet1001.cfg da850evm.cfg pxa255_sst.cfg digi_connectcore_wi-9c.cfg redbee.cfg diolan_lpc4350-db1.cfg rsc-w910.cfg dm355evm.cfg sheevaplug.cfg dm365evm.cfg smdk6410.cfg dm6446evm.cfg spear300evb.cfg efikamx.cfg spear300evb_mod.cfg eir.cfg spear310evb20.cfg ek-lm3s1968.cfg spear310evb20_mod.cfg ek-lm3s3748.cfg spear320cpu.cfg ek-lm3s6965.cfg spear320cpu_mod.cfg ek-lm3s811.cfg steval_pcc010.cfg ek-lm3s811-revb.cfg stm320518_eval_stlink.cfg ek-lm3s8962.cfg stm32100b_eval.cfg ek-lm3s9b9x.cfg stm3210b_eval.cfg ek-lm3s9d92.cfg stm3210c_eval.cfg ek-lm4f120xl.cfg stm3210e_eval.cfg ek-lm4f232.cfg stm3220g_eval.cfg embedded-artists_lpc2478-32.cfg stm3220g_eval_stlink.cfg ethernut3.cfg stm3241g_eval.cfg glyn_tonga2.cfg stm3241g_eval_stlink.cfg hammer.cfg stm32f0discovery.cfg hilscher_nxdb500sys.cfg stm32f3discovery.cfg hilscher_nxeb500hmi.cfg stm32f4discovery.cfg hilscher_nxhx10.cfg stm32ldiscovery.cfg hilscher_nxhx500.cfg stm32vldiscovery.cfg hilscher_nxhx50.cfg str910-eval.cfg hilscher_nxsb100.cfg telo.cfg hitex_lpc1768stick.cfg ti_am335xevm.cfg hitex_lpc2929.cfg ti_beagleboard.cfg hitex_stm32-performancestick.cfg ti_beagleboard_xm.cfg hitex_str9-comstick.cfg ti_beaglebone.cfg iar_lpc1768.cfg ti_blaze.cfg iar_str912_sk.cfg ti_pandaboard.cfg icnova_imx53_sodimm.cfg ti_pandaboard_es.cfg icnova_sam9g45_sodimm.cfg topas910.cfg imx27ads.cfg topasa900.cfg imx27lnst.cfg twr-k60f120m.cfg imx28evk.cfg twr-k60n512.cfg imx31pdk.cfg tx25_stk5.cfg imx35pdk.cfg tx27_stk5.cfg imx53loco.cfg unknown_at91sam9260.cfg keil_mcb1700.cfg uptech_2410.cfg keil_mcb2140.cfg verdex.cfg kwikstik.cfg voipac.cfg linksys_nslu2.cfg voltcraft_dso-3062c.cfg lisa-l.cfg x300t.cfg logicpd_imx27.cfg zy1000.cfg $
$ ls target aduc702x.cfg lpc1763.cfg am335x.cfg lpc1764.cfg amdm37x.cfg lpc1765.cfg ar71xx.cfg lpc1766.cfg at32ap7000.cfg lpc1767.cfg at91r40008.cfg lpc1768.cfg at91rm9200.cfg lpc1769.cfg at91sam3ax_4x.cfg lpc1788.cfg at91sam3ax_8x.cfg lpc17xx.cfg at91sam3ax_xx.cfg lpc1850.cfg at91sam3nXX.cfg lpc2103.cfg at91sam3sXX.cfg lpc2124.cfg at91sam3u1c.cfg lpc2129.cfg at91sam3u1e.cfg lpc2148.cfg at91sam3u2c.cfg lpc2294.cfg at91sam3u2e.cfg lpc2378.cfg at91sam3u4c.cfg lpc2460.cfg at91sam3u4e.cfg lpc2478.cfg at91sam3uxx.cfg lpc2900.cfg at91sam3XXX.cfg lpc2xxx.cfg at91sam4sd32x.cfg lpc3131.cfg at91sam4sXX.cfg lpc3250.cfg at91sam4XXX.cfg lpc4350.cfg at91sam7se512.cfg lpc4350.cfg.orig at91sam7sx.cfg mc13224v.cfg at91sam7x256.cfg nuc910.cfg at91sam7x512.cfg omap2420.cfg at91sam9260.cfg omap3530.cfg at91sam9260_ext_RAM_ext_flash.cfg omap4430.cfg at91sam9261.cfg omap4460.cfg at91sam9263.cfg omap5912.cfg at91sam9.cfg omapl138.cfg at91sam9g10.cfg pic32mx.cfg at91sam9g20.cfg pxa255.cfg at91sam9g45.cfg pxa270.cfg at91sam9rl.cfg pxa3xx.cfg atmega128.cfg readme.txt avr32.cfg samsung_s3c2410.cfg c100.cfg samsung_s3c2440.cfg c100config.tcl samsung_s3c2450.cfg c100helper.tcl samsung_s3c4510.cfg c100regs.tcl samsung_s3c6410.cfg cs351x.cfg sharp_lh79532.cfg davinci.cfg smp8634.cfg dragonite.cfg spear3xx.cfg dsp56321.cfg stellaris.cfg dsp568013.cfg stellaris_icdi.cfg dsp568037.cfg stm32f0x_stlink.cfg efm32_stlink.cfg stm32f1x.cfg epc9301.cfg stm32f1x_stlink.cfg faux.cfg stm32f2x.cfg feroceon.cfg stm32f2x_stlink.cfg fm3.cfg stm32f3x.cfg hilscher_netx10.cfg stm32f3x_stlink.cfg hilscher_netx500.cfg stm32f4x.cfg hilscher_netx50.cfg stm32f4x_stlink.cfg icepick.cfg stm32l.cfg imx21.cfg stm32lx_dual_bank.cfg imx25.cfg stm32lx_stlink.cfg imx27.cfg stm32_stlink.cfg imx28.cfg stm32w108_stlink.cfg imx31.cfg stm32xl.cfg imx35.cfg str710.cfg imx51.cfg str730.cfg imx53.cfg str750.cfg imx6.cfg str912.cfg imx.cfg swj-dp.tcl is5114.cfg test_reset_syntax_error.cfg ixp42x.cfg test_syntax_error.cfg k40.cfg ti-ar7.cfg k60.cfg ti_calypso.cfg lpc1751.cfg ti_dm355.cfg lpc1752.cfg ti_dm365.cfg lpc1754.cfg ti_dm6446.cfg lpc1756.cfg tmpa900.cfg lpc1758.cfg tmpa910.cfg lpc1759.cfg u8500.cfg
The openocd.cfg user config file may override features in any of the above files by setting variables before sourcing the target file, or by adding commands specific to their situation.
The user config file should be able to source one of these files with a command like this:
source [find interface/FOOBAR.cfg]
A preconfigured interface file should exist for every debug adapter in use today with OpenOCD. That said, perhaps some of these config files have only been used by the developer who created it.
A separate chapter gives information about how to set these up. See Debug Adapter Configuration. Read the OpenOCD source code (and Developer’s Guide) if you have a new kind of hardware interface and need to provide a driver for it.
The user config file should be able to source one of these files with a command like this:
source [find board/FOOBAR.cfg]
The point of a board config file is to package everything about a given board that user config files need to know. In summary the board files should contain (if present)
source [find target/...cfg]
statements
reset
handlers for SDRAM and I/O configuration
Generic things inside target chips belong in target config files,
not board config files. So for example a reset-init
event
handler should know board-specific oscillator and PLL parameters,
which it passes to target-specific utility code.
The most complex task of a board config file is creating such a
reset-init
event handler.
Define those handlers last, after you verify the rest of the board
configuration works.
In addition to target-specific utility code, another way that board and target config files communicate is by following a convention on how to use certain variables.
The full Tcl/Tk language supports “namespaces”, but Jim-Tcl does not. Thus the rule we follow in OpenOCD is this: Variables that begin with a leading underscore are temporary in nature, and can be modified and used at will within a target configuration file.
Complex board config files can do the things like this, for a board with three chips:
# Chip #1: PXA270 for network side, big endian set CHIPNAME network set ENDIAN big source [find target/pxa270.cfg] # on return: _TARGETNAME = network.cpu # other commands can refer to the "network.cpu" target. $_TARGETNAME configure .... events for this CPU.. # Chip #2: PXA270 for video side, little endian set CHIPNAME video set ENDIAN little source [find target/pxa270.cfg] # on return: _TARGETNAME = video.cpu # other commands can refer to the "video.cpu" target. $_TARGETNAME configure .... events for this CPU.. # Chip #3: Xilinx FPGA for glue logic set CHIPNAME xilinx unset ENDIAN source [find target/spartan3.cfg]
That example is oversimplified because it doesn’t show any flash memory,
or the reset-init
event handlers to initialize external DRAM
or (assuming it needs it) load a configuration into the FPGA.
Such features are usually needed for low-level work with many boards,
where “low level” implies that the board initialization software may
not be working. (That’s a common reason to need JTAG tools. Another
is to enable working with microcontroller-based systems, which often
have no debugging support except a JTAG connector.)
Target config files may also export utility functions to board and user config files. Such functions should use name prefixes, to help avoid naming collisions.
Board files could also accept input variables from user config files.
For example, there might be a J4_JUMPER
setting used to identify
what kind of flash memory a development board is using, or how to set
up other clocks and peripherals.
Most boards have only one instance of a chip. However, it should be easy to create a board with more than one such chip (as shown above). Accordingly, we encourage these conventions for naming variables associated with different target.cfg files, to promote consistency and so that board files can override target defaults.
Inputs to target config files include:
CHIPNAME
...
This gives a name to the overall chip, and is used as part of
tap identifier dotted names.
While the default is normally provided by the chip manufacturer,
board files may need to distinguish between instances of a chip.
ENDIAN
...
By default little - although chips may hard-wire big.
Chips that can’t change endianness don’t need to use this variable.
CPUTAPID
...
When OpenOCD examines the JTAG chain, it can be told verify the
chips against the JTAG IDCODE register.
The target file will hold one or more defaults, but sometimes the
chip in a board will use a different ID (perhaps a newer revision).
Outputs from target config files include:
_TARGETNAME
...
By convention, this variable is created by the target configuration
script. The board configuration file may make use of this variable to
configure things like a “reset init” script, or other things
specific to that board and that target.
If the chip has 2 targets, the names are _TARGETNAME0
,
_TARGETNAME1
, ... etc.
Board config files run in the OpenOCD configuration stage;
they can’t use TAPs or targets, since they haven’t been
fully set up yet.
This means you can’t write memory or access chip registers;
you can’t even verify that a flash chip is present.
That’s done later in event handlers, of which the target reset-init
handler is one of the most important.
Except on microcontrollers, the basic job of reset-init
event
handlers is setting up flash and DRAM, as normally handled by boot loaders.
Microcontrollers rarely use boot loaders; they run right out of their
on-chip flash and SRAM memory. But they may want to use one of these
handlers too, if just for developer convenience.
Note: Because this is so very board-specific, and chip-specific, no examples are included here. Instead, look at the board config files distributed with OpenOCD. If you have a boot loader, its source code will help; so will configuration files for other JTAG tools (see Translating Configuration Files).
Some of this code could probably be shared between different boards. For example, setting up a DRAM controller often doesn’t differ by much except the bus width (16 bits or 32?) and memory timings, so a reusable TCL procedure loaded by the target.cfg file might take those as parameters. Similarly with oscillator, PLL, and clock setup; and disabling the watchdog. Structure the code cleanly, and provide comments to help the next developer doing such work. (You might be that next person trying to reuse init code!)
The last thing normally done in a reset-init
handler is probing
whatever flash memory was configured. For most chips that needs to be
done while the associated target is halted, either because JTAG memory
access uses the CPU or to prevent conflicting CPU access.
Before your reset-init
handler has set up
the PLLs and clocking, you may need to run with
a low JTAG clock rate.
See JTAG Speed.
Then you’d increase that rate after your handler has
made it possible to use the faster JTAG clock.
When the initial low speed is board-specific, for example
because it depends on a board-specific oscillator speed, then
you should probably set it up in the board config file;
if it’s target-specific, it belongs in the target config file.
For most ARM-based processors the fastest JTAG clock4 is one sixth of the CPU clock; or one eighth for ARM11 cores. Consult chip documentation to determine the peak JTAG clock rate, which might be less than that.
Warning: On most ARMs, JTAG clock detection is coupled to the core clock, so software using a wait for interrupt operation blocks JTAG access. Adaptive clocking provides a partial workaround, but a more complete solution just avoids using that instruction with JTAG debuggers.
If both the chip and the board support adaptive clocking,
use the jtag_rclk
command, in case your board is used with JTAG adapter which
also supports it. Otherwise use adapter_khz
.
Set the slow rate at the beginning of the reset sequence,
and the faster rate as soon as the clocks are at full speed.
The concept of init_board
procedure is very similar to init_targets
(See The init_targets procedure.) - it’s a replacement of “linear”
configuration scripts. This procedure is meant to be executed when OpenOCD enters run stage
(See Entering the Run Stage,) after init_targets
. The idea to have
separate init_targets
and init_board
procedures is to allow the first one to configure
everything target specific (internal flash, internal RAM, etc.) and the second one to configure
everything board specific (reset signals, chip frequency, reset-init event handler, external memory, etc.).
Additionally “linear” board config file will most likely fail when target config file uses
init_targets
scheme (“linear” script is executed before init
and init_targets
- after),
so separating these two configuration stages is very convenient, as the easiest way to overcome this
problem is to convert board config file to use init_board
procedure. Board config scripts don’t
need to override init_targets
defined in target config files when they only need to add some specifics.
Just as init_targets
, the init_board
procedure can be overridden by “next level” script (which sources
the original), allowing greater code reuse.
### board_file.cfg ### # source target file that does most of the config in init_targets source [find target/target.cfg] proc enable_fast_clock {} { # enables fast on-board clock source # configures the chip to use it } # initialize only board specifics - reset, clock, adapter frequency proc init_board {} { reset_config trst_and_srst trst_pulls_srst $_TARGETNAME configure -event reset-init { adapter_khz 1 enable_fast_clock adapter_khz 10000 } }
Board config files communicate with target config files using naming conventions as described above, and may source one or more target config files like this:
source [find target/FOOBAR.cfg]
The point of a target config file is to package everything about a given chip that board config files need to know. In summary the target files should contain
As a rule of thumb, a target file sets up only one chip. For a microcontroller, that will often include a single TAP, which is a CPU needing a GDB target, and its on-chip flash.
More complex chips may include multiple TAPs, and the target config file may need to define them all before OpenOCD can talk to the chip. For example, some phone chips have JTAG scan chains that include an ARM core for operating system use, a DSP, another ARM core embedded in an image processing engine, and other processing engines.
All target configuration files should start with code like this, letting board config files express environment-specific differences in how things should be set up.
# Boards may override chip names, perhaps based on role, # but the default should match what the vendor uses if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME sam7x256 } # ONLY use ENDIAN with targets that can change it. if { [info exists ENDIAN] } { set _ENDIAN $ENDIAN } else { set _ENDIAN little } # TAP identifiers may change as chips mature, for example with # new revision fields (the "3" here). Pick a good default; you # can pass several such identifiers to the "jtag newtap" command. if { [info exists CPUTAPID ] } { set _CPUTAPID $CPUTAPID } else { set _CPUTAPID 0x3f0f0f0f }
Remember: Board config files may include multiple target
config files, or the same target file multiple times
(changing at least CHIPNAME
).
Likewise, the target configuration file should define
_TARGETNAME
(or _TARGETNAME0
etc) and
use it later on when defining debug targets:
set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME
After the “defaults” are set up, add the TAPs on each chip to the JTAG scan chain. See TAP Declaration, and the naming convention for taps.
In the simplest case the chip has only one TAP, probably for a CPU or FPGA. The config file for the Atmel AT91SAM7X256 looks (in part) like this:
jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
A board with two such at91sam7 chips would be able
to source such a config file twice, with different
values for CHIPNAME
, so
it adds a different TAP each time.
If there are nonzero -expected-id values, OpenOCD attempts to verify the actual tap id against those values. It will issue error messages if there is mismatch, which can help to pinpoint problems in OpenOCD configurations.
JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3) ERROR: Tap: sam7x256.cpu - Expected id: 0x12345678, Got: 0x3f0f0f0f ERROR: expected: mfg: 0x33c, part: 0x2345, ver: 0x1 ERROR: got: mfg: 0x787, part: 0xf0f0, ver: 0x3
There are more complex examples too, with chips that have multiple TAPs. Ones worth looking at include:
After adding a TAP for a CPU, you should set it up so that
GDB and other commands can use it.
See CPU Configuration.
For the at91sam7 example above, the command can look like this;
note that $_ENDIAN
is not needed, since OpenOCD defaults
to little endian, and this chip doesn’t support changing that.
set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME
Work areas are small RAM areas associated with CPU targets. They are used by OpenOCD to speed up downloads, and to download small snippets of code to program flash chips. If the chip includes a form of “on-chip-ram” - and many do - define a work area if you can. Again using the at91sam7 as an example, this can look like:
$_TARGETNAME configure -work-area-phys 0x00200000 \ -work-area-size 0x4000 -work-area-backup 0
After setting targets, you can define a list of targets working in SMP.
set _TARGETNAME_1 $_CHIPNAME.cpu1 set _TARGETNAME_2 $_CHIPNAME.cpu2 target create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap \ -coreid 0 -dbgbase $_DAP_DBG1 target create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap \ -coreid 1 -dbgbase $_DAP_DBG2 #define 2 targets working in smp. target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1
In the above example on cortex_a, 2 cpus are working in SMP. In SMP only one GDB instance is created and :
The SMP behaviour can be disabled/enabled dynamically. On cortex_a following command have been implemented.
>cortex_a smp_gdb gdb coreid 0 -> -1 #0 : coreid 0 is displayed to GDB , #-> -1 : next resume triggers a real resume > cortex_a smp_gdb 1 gdb coreid 0 -> 1 #0 :coreid 0 is displayed to GDB , #->1 : next resume displays coreid 1 to GDB > resume > cortex_a smp_gdb gdb coreid 1 -> 1 #1 :coreid 1 is displayed to GDB , #->1 : next resume displays coreid 1 to GDB > cortex_a smp_gdb -1 gdb coreid 1 -> -1 #1 :coreid 1 is displayed to GDB, #->-1 : next resume triggers a real resume
As a rule, you should put the reset_config
command
into the board file. Most things you think you know about a
chip can be tweaked by the board.
Some chips have specific ways the TRST and SRST signals are managed. In the unusual case that these are chip specific and can never be changed by board wiring, they could go here. For example, some chips can’t support JTAG debugging without both signals.
Provide a reset-assert
event handler if you can.
Such a handler uses JTAG operations to reset the target,
letting this target config be used in systems which don’t
provide the optional SRST signal, or on systems where you
don’t want to reset all targets at once.
Such a handler might write to chip registers to force a reset,
use a JRC to do that (preferable – the target may be wedged!),
or force a watchdog timer to trigger.
(For Cortex-M targets, this is not necessary. The target
driver knows how to use trigger an NVIC reset when SRST is
not available.)
Some chips need special attention during reset handling if
they’re going to be used with JTAG.
An example might be needing to send some commands right
after the target’s TAP has been reset, providing a
reset-deassert-post
event handler that writes a chip
register to report that JTAG debugging is being done.
Another would be reconfiguring the watchdog so that it stops
counting while the core is halted in the debugger.
JTAG clocking constraints often change during reset, and in some cases target config files (rather than board config files) are the right places to handle some of those issues. For example, immediately after reset most chips run using a slower clock than they will use later. That means that after reset (and potentially, as OpenOCD first starts up) they must use a slower JTAG clock rate than they will use later. See JTAG Speed.
Important: When you are debugging code that runs right after chip reset, getting these issues right is critical. In particular, if you see intermittent failures when OpenOCD verifies the scan chain after reset, look at how you are setting up JTAG clocking.
Target config files can either be “linear” (script executed line-by-line when parsed in
configuration stage, See Configuration Stage,) or they can contain a special
procedure called init_targets
, which will be executed when entering run stage
(after parsing all config files or after init
command, See Entering the Run Stage.)
Such procedure can be overriden by “next level” script (which sources the original).
This concept faciliates code reuse when basic target config files provide generic configuration
procedures and init_targets
procedure, which can then be sourced and enchanced or changed in
a “more specific” target config file. This is not possible with “linear” config scripts,
because sourcing them executes every initialization commands they provide.
### generic_file.cfg ### proc setup_my_chip {chip_name flash_size ram_size} { # basic initialization procedure ... } proc init_targets {} { # initializes generic chip with 4kB of flash and 1kB of RAM setup_my_chip MY_GENERIC_CHIP 4096 1024 } ### specific_file.cfg ### source [find target/generic_file.cfg] proc init_targets {} { # initializes specific chip with 128kB of flash and 64kB of RAM setup_my_chip MY_CHIP_WITH_128K_FLASH_64KB_RAM 131072 65536 }
The easiest way to convert “linear” config files to init_targets
version is to
enclose every line of “code” (i.e. not source
commands, procedures, etc.) in this procedure.
For an example of this scheme see LPC2000 target config files.
The init_boards
procedure is a similar concept concerning board config files
(See The init_board procedure.)
A special procedure called init_target_events
is run just after
init_targets
(See The init_targets
procedure.) and before init_board
(See The init_board procedure.) It is used
to set up default target events for the targets that do not have those
events already assigned.
If the chip has a DCC, enable it. If the chip is an ARM9 with some special high speed download features - enable it.
If present, the MMU, the MPU and the CACHE should be disabled.
Some ARM cores are equipped with trace support, which permits examination of the instruction and data bus activity. Trace activity is controlled through an “Embedded Trace Module” (ETM) on one of the core’s scan chains. The ETM emits voluminous data through a “trace port”. (See ARM Hardware Tracing.) If you are using an external trace port, configure it in your board config file. If you are using an on-chip “Embedded Trace Buffer” (ETB), configure it in your target config file.
etm config $_TARGETNAME 16 normal full etb etb config $_TARGETNAME $_CHIPNAME.etb
This applies ONLY TO MICROCONTROLLERS that have flash built in.
Never ever in the “target configuration file” define any type of flash that is external to the chip. (For example a BOOT flash on Chip Select 0.) Such flash information goes in a board file - not the TARGET (chip) file.
Examples:
If you have a configuration file for another hardware debugger or toolset (Abatron, BDI2000, BDI3000, CCS, Lauterbach, Segger, Macraigor, etc.), translating it into OpenOCD syntax is often quite straightforward. The most tricky part of creating a configuration script is oftentimes the reset init sequence where e.g. PLLs, DRAM and the like is set up.
One trick that you can use when translating is to write small Tcl procedures to translate the syntax into OpenOCD syntax. This can avoid manual translation errors and make it easier to convert other scripts later on.
Example of transforming quirky arguments to a simple search and replace job:
# Lauterbach syntax(?) # # Data.Set c15:0x042f %long 0x40000015 # # OpenOCD syntax when using procedure below. # # setc15 0x01 0x00050078 proc setc15 {regs value} { global TARGETNAME echo [format "set p15 0x%04x, 0x%08x" $regs $value] arm mcr 15 [expr ($regs>>12)&0x7] \ [expr ($regs>>0)&0xf] [expr ($regs>>4)&0xf] \ [expr ($regs>>8)&0x7] $value }
Next: Daemon Configuration, Previous: OpenOCD Project Setup, Up: Top [Contents][Index]