Debugging from reset: The runaway core syndrome


A microcontroller’s job is to execute programmed code. When MCU is powered up the application starts running...


Stop the core, I need to do something first!

Stopping program execution on the entry address is usually the first thing you want to do while your embedded application is under development for at least one of the following reasons:

  • It is useful for testing and debugging of initialization code such as first stage boot loaders (FSBL), ROM boot loaders, U-Boot, Board support packages (BSP), etc.
  • Another reason is having a clean slate when programming the code to non-volatile memory (flash, QSPI), because a previously programmed application might be preventing access to desired destination memory for programming.
  • Also an uninitialized device is preferred to execute initialization routines which usually expect resources to be uninitialized, as is the case, when the device is released from reset. However, resources might already be partially initialized if a debugging tool released the system from reset, let it run for a short while, stopped the execution and only then preset the execution to the entry port. Such an approach can lead to unpredictable results.

System-on-Chip (SoC) vendors provide solutions to overcome debugging problems from runaway targets in the form of a dedicated debug mechanism. Such features can be implemented on SoC level by a silicon vendor or in case of ARM IP integration on a core level as per ARM specifications. ARM cores generally feature exception catch debug settings like Reset Catch Enable (RCE) bit which provides the ability to stop code execution, when required.


But why is the core not stopping?

While debug mechanisms are available, they are just not accessible at that point of time. Less than ideal target board or SoC design are the most common reasons for such situations:

  • Reset signals are combined in a single signal on the debug connector when a SoC package features multiple reset signals like TAP reset (TRST) and System reset (SRST). TRST is meant for the debug (test) subsystem reset and it shouldn’t affect the execution of application while SRST should reset the application and leave the debug part intact, e.g. breakpoints which were set. It is clear that reset catch mechanism (usually in the debug subsystem) must be accessible and not be in reset or left unpowered, while the application subsystem is held in reset in order to halt the execution after the application subsystem is released from reset.
  • Execution subsystem (a core) and debug subsystem have a common supply within one of many possible core clusters in a multicore SoC. Such approach renders reset catch mechanism unusable for catching the execution immediately after enabling the power for a secondary core. However, it can still be used for catching software resets.
Reset Vector Catch iSYSTEM ARM Cortex

There are also variations of the listed problems that are preventing catching the execution after releasing reset signals.

How does winIDEA handle Reset Catch?

It depends on SoC, capabilities of a SoC / board combination and desired operation.

Example: all available mechanisms will be put into effect when pressing a Reset button in winIDEA and none when hitting Attach. Users can additionally configure the catch reset exception in winIDEA. These will be configured when available which might be after the core is released from reset and as such only useful for self reset catching.

There is no common way to determine on which devices/cores it is possible to use reset catch mechanism. Indicator that reset catch is possible is the displayed debug status in winIDEA. It is unlikely that it is possible, if debug status displays HALTED or DETACHED, when a core is held in reset.

What can be done?

If the SoC debug mechanism fails to stop the core on the entry address, there are some workarounds available.

For example: create an infinite loop (e.g. ‘Branch to itself’ instruction) at entry point, which the MCU will execute until a breakpoint is set or the core is stopped. This way you can make sure that the part of the application you wish to debug does not run before the debug session is established. Of course, utilize the debug after download/reset option to set the execution to the start position as it is in production code.

Was this insightful?

Subscribe to our newsletter or follow us on LinkedIn for more articles like this.