If your code crashes and ends up in a HardFault handler or in any other ARM Cortex M0+ crash handler, nothing is printed. The function isr_hardfault
(in CMSIS complaint terms named Hardfault_Handler()
) is just implemented as a function that triggers a breakpoint (bkpt #0
), thereby signaling to a possibly connected debug probe that the code has now crashed and halted.
See https://github.com/raspberrypi/pico-sdk/blob/ee68c78d0afae2b69c03ae1a72bf5cc267a2d94c/src/rp2_common/pico_crt0/crt0.S#L29-L170.
The crash /exception output as in ESP32 is a luxury that by default does not exist on the RP2040 and the Arduino-Pico framework. What you’re doing with PIO_FRAMEWORK_ARDUINO_ENABLE_EXCEPTIONS
is enable the usage of C++ exception constructs, aka try { /* .. */ } catch(std::exception e) { /* ..*/ }
. This has nothing to do with printing a crash log.
So the advice that makes the most sense is follow the documentation on how to connect a debug probe to the RP2040. That is surprisingly easy and comfortable: If you have have a second Raspberry Pi Pico or Raspberry Pi Pico 2, you can copy the “DebugProbe” firmware on it as released in
https://github.com/raspberrypi/debugprobe/releases
(e.g. copying debugprobe_on_pico.uf2
to a RP2040’s based Pico’s BOOTSEL USB drive), which will make that Pico act like a CMSIS-DAP debug probe (debug_tool = cmsis-dap
in the platformio.ini
). Then with just 3 wires (SWDIO, SWCLK, GND) between them, one Pico can debug the other Pico.
That is all again documented.
https://arduino-pico.readthedocs.io/en/latest/platformio.html#debugging
This would then enable you to see how code execution ended up in the crash handler, for example via the call stack:
Another approach is to implement the isr_hardfault()
function in a way that does print out information about the crash, by decoding the info from some ARM Cortex core registers and the stack and printing them to the serial. The https://github.com/armink/CmBacktrace project can do that. However, if you use the USB serial with the Pico, that in itself may require USB interrupts to work and send out the data, which definitely won’t trigger if the core has experienced a HardFault interrupt and is stuck in there, so using Serial(USB).println()
likely won’t work. It may work however to use the UART based Serial (Serial0
) and, of course, connect a separate USB-to-UART converter to connect to that port and read out the data.