How to override the default OpenOCD reset handling?

Q

How to override the default OpenOCD reset handling?

A

OpenOCD provides a way to completely override the default reset handling and provide your own custom implementation of the reset procedures. These are the relevant parts from the OpenOCD documentation (see Reset Configuration and CPU Configuration):

 9.4 Custom Reset Handling...

OpenOCD has several ways to help support the various reset mechanisms provided by chip and board vendors. The commands shown in the previous section give standard parameters. There are also event handlers associated with TAPs or Targets. Those handlers are Tcl procedures you can provide, which are invoked at particular points in the reset sequence.

When SRST is not an option you must set up a reset-assert event handler for your target. For example, some JTAG adapters don’t include the SRST signal; and some boards have multiple targets, and you won’t always want to reset everything at once.

After configuring those mechanisms, you might still find your board doesn’t start up or reset correctly. For example, maybe it needs a slightly different sequence of SRST and/or TRST manipulations, because of quirks that the reset_config mechanism doesn’t address; or asserting both might trigger a stronger reset, which needs special attention.

Experiment with lower level operations, such as adapter assertadapter deassert and the jtag arp_* operations shown here, to find a sequence of operations that works. See JTAG Commands. When you find a working sequence, it can be used to override jtag_init, which fires during OpenOCD startup (see Configuration Stage); or init_reset, which fires during reset processing.

You might also want to provide some project-specific reset schemes. For example, on a multi-target board the standard reset command would reset all targets, but you may need the ability to reset only one target at time and thus want to avoid using the board-wide SRST signal.

Overridable Procedure: init_reset mode

This is invoked near the beginning of the reset command, usually to provide as much of a cold (power-up) reset as practical. By default it is also invoked from jtag_init if the scan chain does not respond to pure JTAG operations. The mode parameter is the parameter given to the low level reset command (halt, init, or run), setup, or potentially some other value.The default implementation just invokes jtag arp_init-reset. Replacements will normally build on low level JTAG operations such as adapter assert and adapter deassert. Operations here must not address individual TAPs (or their associated targets) until the JTAG scan chain has first been verified to work.Implementations must have verified the JTAG scan chain before they return. This is done by calling jtag arp_init (or jtag arp_init-reset).

Command: jtag arp_init

This validates the scan chain using just the four standard JTAG signals (TMS, TCK, TDI, TDO). It starts by issuing a JTAG-only reset. Then it performs checks to verify that the scan chain configuration matches the TAPs it can observe. Those checks include checking IDCODE values for each active TAP, and verifying the length of their instruction registers using TAP -ircapture and -irmask values. If these tests all pass, TAP setup events are issued to all TAPs with handlers for that event.

Command: jtag arp_init-reset

This uses TRST and SRST to try resetting everything on the JTAG scan chain (and anything else connected to SRST). It then invokes the logic of jtag arp_init.

 11.5 Target Events...

The following target events are defined:

  • reset-assert
    Issued as part of 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.
  • ...


To implement custom reset handling you can override the init_reset procedure and/or provide a reset-assert event handler. This how-to describes the recommended way to do this in netX Studio CDT.

Please note that implementing the proper reset handling may require advanced knowledge of OpenOCD and the target hardware specifics. The scripts below are just examples of where to place the custom reset handling and should not be used directly.


To override the init_reset procedure:

  1. Create an openocd_config.cfg file in the project root directory with the default init_reset implementation (see https://github.com/openocd-org/openocd/blob/v0.10.0/src/jtag/startup.tcl):

    openocd_config.cfg
    # This reset logic may be overridden by board/target/... scripts as needed
    # to provide a reset that, if possible, is close to a power-up reset.
    #
    # Exit requirements include:  (a) JTAG must be working, (b) the scan
    # chain was validated with "jtag arp_init" (or equivalent), (c) nothing
    # stays in reset.  No TAP-specific scans were performed.  It's OK if
    # some targets haven't been reset yet; they may need TAP-specific scans.
    #
    # The "mode" values include:  halt, init, run (from "reset" command);
    # startup (at OpenOCD server startup, when JTAG may not yet work); and
    # potentially more (for reset types like cold, warm, etc)
    proc init_reset { mode } {
    	if {[using_jtag]} {
    		jtag arp_init-reset
    	}
    }
  2. Customize the init_reset according to your target requirements, e.g.:

    openocd_config.cfg
    proc init_reset { mode } {
        puts "Using custom reset..."
        
        # assert both resets; equivalent to power-on reset
        jtag_reset 1 1
    
        # drop TRST after 1ms 
        sleep 1
        jtag_reset 0 1
    
        # minimum 32 TCK cycles to wake up the controller
        runtest 50
    
        # now the TAP will be responsive; validate scanchain
        jtag arp_init
    
        # ... and take it out of reset
        jtag_reset 0 0
    }
  3. Set the OpenOCD config script in Debug Settings:


  4. Start debugging and pay attention to the OpenOCD console to make sure your custom init_reset procedure is executed:


То provide a reset-assert event handler and override the default:

  1. In the openocd_config.cfg file, add the following commands to configure the reset-assert handler:

    openocd_config.cfg
    $_TARGETNAME_APP configure -event reset-assert {
    	# do nothing; reset will be handled by init_reset
    }
    
    proc init_reset { mode } {
        ...
    }

    The target 'configure' command is preceded by the target name which is usually referenced as a variable, e.g. $_TARGETNAME. Check the target configuration file for your target to see the target name variable to use. For example, the target configuration file for the netX 90 application side is BuildTools\openocd\config\target\hilscher_netx90_app.cfg and the target name variable for the APP CPU is $_TARGETNAME_APP.

  2. Make sure the OpenOCD config script is setup in Debug Settings (see above)