Debugging

WFI and JTAG

JTAG and wfi do not place nicely together. You've probably noticed this yourself, wondering why JTAG can't connect or a halt/breakpoint doesn't work.

When the ARM core is executing the wait for interrupt operation, the core is placed into a low power mode and the core clock is gated. This wreaks havoc with JTAG, as the core clock is required to detect the JTAG clock transitions.

The simplest way to keep your debugging sanity is to provide hooks to disable wfi when JTAG is needed. One option is to use a #define to control whether your idle loop performs wfi or spins the processor. In quick pseudo-code:

#ifdef DISABLE_WFI
    tx_thread_sleep(1)
#else
    asm("wfi");
#endif

However, once you need to debug returned units, reliability units, or factory failures it's not always feasible to reflash a unit. A more complicated implementation is to incorporate an NVRAM library and set a software flag (more on that in the future). On boot, the software checks the flag and uses the correct idle loop. If you then need to debug a device but can't re-flash it, simply set the NVRAM flag, reboot, et voila!

Note that this strategy will have an effect on timing and power consumption, so it will not be the holy grail for all cases. But it will certainly make your life easier if you're running into the wfi wall.

Debugging Strategy: Finding Version from a Memory Dump

Have you ever had a device that's in a weird state, and you're curious what version of software is on it so you can load the correct debug symbols? Here's a strategy for figuring that out:

  • Connect to device over JTAG when it's in the desired state
  • Use your JTAG tool to dump the contents of memory into a binary file on your host
    • Example using openocd:
      • dump_image sram.bin 0x300000 0x20000
    • You will need to know where in memory your binary gets loaded, as well as the size of the binary
  • Run strings on the downloaded binary file. You will need to look for something representative for your version string.
    • For example, "buildbot" is the jenkins machine that builds nightly images for my current project.
    • strings sram.bin | grep buildbot
      master 0.1.10 Wed Sep 21 03:10:25 PDT 2016 buildbot@company.io
  • Once you know the version of software you have, you can grab the debug symbols for that build and continue on your merry way.

Happy hunting!