## 6 Config File Guidelines

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.

- `interface` ... These are for debug adapters. Files that configure JTAG adapters go here.

      $ 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
      $

- `board` ... think Circuit Board, PWA, PCB, they go by many names. Board files contain initialization items that are specific to a board. They reuse target configuration files, since the same microprocessor chips are used on many boards, but support for external parts varies widely. For example, the SDRAM initialization sequence for the board, or the type of external flash and what address it uses. Any initialization sequence to enable that external flash or SDRAM should be found in the board file. Boards may also contain multiple targets: two CPUs; or a CPU and an FPGA.

      $ 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
      $

- `target` ... think chip. The “target” directory represents the JTAG TAPs on a chip which OpenOCD should control, not a board. Two common types of targets are ARM chips and FPGA or CPLD chips. When a chip has multiple TAPs (maybe it has both ARM and DSP cores), the target config file defines all of them.

      $ 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

- more ... browse for other library files which may be useful. For example, there are various generic and CPU-specific utilities.

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.

### 6.1 Interface Config Files

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.

### 6.2 Board Config Files

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)

1. One or more `source [find target/...cfg]` statements
2. NOR flash configuration (see NOR Configuration)
3. NAND flash configuration (see NAND Configuration)
4. Target `reset` handlers for SDRAM and I/O configuration
5. JTAG adapter reset configuration (see Reset Configuration)
6. All things that are not “inside a chip”

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.

#### 6.2.1 Communication Between Config files

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.

#### 6.2.2 Variable Naming Convention

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.

#### 6.2.3 The reset-init Event Handler

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.

#### 6.2.4 JTAG Clock Rate

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.

#### 6.2.5 The init_board procedure

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
        }
    }

### 6.3 Target Config Files

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

1. Set defaults
2. Add TAPs to the scan chain
3. Add CPU targets (includes GDB support)
4. CPU/Chip/CPU-Core specific features
5. On-Chip flash

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.

#### 6.3.1 Default Value Boiler Plate Code

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

#### 6.3.2 Adding TAPs to the Scan Chain

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:

- `target/omap3530.cfg` – with disabled ARM and DSP, plus a JRC to enable them
- `target/str912.cfg` – with flash, CPU, and boundary scan
- `target/ti_dm355.cfg` – with ETM, ARM, and JRC (this JRC is not currently used)

#### 6.3.3 Add CPU targets

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

#### 6.3.4 Define CPU targets working in SMP

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 :

- a set of hardware breakpoint sets the same breakpoint on all targets in the list.
- halt command triggers the halt of all targets in the list.
- resume command triggers the write context and the restart of all targets in the list.
- following a breakpoint: the target stopped by the breakpoint is displayed to the GDB session.
- dedicated GDB serial protocol packets are implemented for switching/retrieving the target displayed by the GDB session see Using OpenOCD SMP with GDB.

The SMP behaviour can be disabled/enabled dynamically. On cortex_a following command have been implemented.

- cortex_a smp_on : enable SMP mode, behaviour is as described above.
- cortex_a smp_off : disable SMP mode, the current target is the one displayed in the GDB session, only this target is now controlled by GDB session. This behaviour is useful during system boot up.
- cortex_a smp_gdb : display/fix the core id displayed in GDB session see following example.

    >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

#### 6.3.5 Chip Reset Setup

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.

#### 6.3.6 The init_targets procedure

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.)

#### 6.3.7 The init_target_events 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.

#### 6.3.8 ARM Core Specific Hacks

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

#### 6.3.9 Internal Flash Configuration

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:

- at91sam7x256 - has 256K flash YES enable it.
- str912 - has flash internal YES enable it.
- imx27 - uses boot flash on CS0 - it goes in the board file.
- pxa270 - again - CS0 flash - it goes in the board file.

### 6.4 Translating Configuration Files

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
    }

#### Footnotes

### (4)

A FAQ http://www.arm.com/support/faqdev/4170.html gives details.