Debugging / flashing NuttX on ARM with hardware debugger (JTAG/SWD)
NOTE: If you experience the issues described on this page, you can enable the configuration option below to resolve it.
Code Block |
---|
CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y |
What's the problem?
On some architectures (like ARM Cortex-M3) Idle thread causes the core to stop using WFI (Wait For Interrupt) assembly instruction. This effectively stops clocking of the core, which is resumed only by some enabled interrupt. This causes hardware debuggers to believe that they were disconnected from the target, as they lose connection with the now stopped core. For example OpenOCD shows errors like these the moment you start the target:
...
This makes debugging the code impossible and flashing the chip is much harder - you have to connect to the chip at the right moment (when it's not disabled due to WFI) - the chances of doing that are inverse proportional to the load of your system (if your chip spends 99% of time in Idle mode, you have 1% chance of connecting and halting it).
Solution
Some ARM cores that support disabling of clocking after WFI instruction have special configuration options to make debugging possible. One example is STM32 family - with it's DBGMCU->CR register it's possible to keep the core clocked during power-down modes. If your chip supports such configuration you should put it in some early stage of initialization, like in stm32_boardinitialize() function. The following code demonstrates the change for STM32:
...
In rare cases that you still have problems with connecting to the target (especially after power cycle), you should try connecting and halting the chip under reset (this is supported by new versions of OpenOCD), by holding the reset button while starting OpenOCD or by configuring OpenOCD to do that for you.
Work-around
If you keep the RESET button pressed and run OpenOCD command to connected to it, then it will connect sucessful. After connecting you need to keep the reset button pressed until you open the telnet connection (telnet 127.0.0.1 4444) and execute "reset halt":
...