RP2040 embedded runtime: adainit hangs in tasking when with Ada.Exceptions; is present (debugger only)

Hello everyone,

I’m seeing a strange debugger-dependent hang on the Raspberry Pi Pico (RP2040) with the embedded runtime.

Observed behaviour

  • Works perfectly when:
    • Loaded via simple cp and hardware reset, or
    • Debugged and I press the hardware reset button after the initial breakpoint.
  • Hangs inside adainit (tasking initialisation) when launched directly via cortex-debug + OpenOCD without a hardware reset.

Call stack at the hang (core0):

fault@0x100049f8
<signal handler called>
system.bb.threads.queues.change_priority
system.bb.interrupts.interrupt_wrapper
system.tasking.environment_task

Core1 sits at a low bootrom address.

Minimal trigger

Adding this single line is enough to trigger the problem (even though it produces a “unit not referenced” warning and is never executed):

with Ada.Exceptions;

Commenting it out (and the whole exception handler block) makes the sketch run reliably under the debugger.

Runtime & target details

  • Using embedded_rp2040 = "^15.3" (Alire)
  • The same code with embedded_rp2350 = "^15.3" works fine.
  • Only the embedded profile is affected because it provides proper exception handling.

What I tried

  • Many OpenOCD reset sequences (reset halt, core0/core1 arp_reset in different orders, preLaunchCommands, postRestartCommands).
  • Removing runToEntryPoint, breakpoints, etc.

The clean repro is the simple doorbell example (Chapter 7.1) from my tutorial:

Repository branch:

Question

Has anyone else seen the embedded RP2040 runtime’s tasking initialisation fail when Ada.Exceptions is in the closure? Could this be related to how exception handlers or the environment task are registered under the debugger?

I’m happy to supply more logs, try patches, or create a minimal Alire project. Any pointers to the relevant parts of the BB runtime would be very welcome!

Thanks,
Martin

I’ve been able to reproduce the problem with your code on my RP2040 and it looks like Ada.Exceptions is a red herring. Instead, the problem seems to be a defect in the runtime where interrupts are enabled too early (in System.BB.Board_Support.Initialize_Board), which means that the timer interrupt is sometimes spuriously triggering before the runtime is fully initialized and ready for interrupts.

As far as I can tell, this crash should only be possible when doing a warm reset of the RP2040, since it only occurs when a previously configured timer alarm happens to expire while the runtime is reinitialising after a warm reset. In your case, having a short delay of 20ms (delay 0.02) and having extra elaboration needed for Ada.Exceptions just happens to line everything up such that you hit this defect.

I’ve made a quick patch to the runtime locally to avoid enabling interrupts too early and that seems to fix the problem. I’ll do some more testing, and try and push out a new release sometime this weekend.

By the way, when debugging weird runtime-related problems like this it can sometimes help to build the runtime in debug mode so you get full debug info on the runtime’s symbols. This can really help as the stack trace will also include all calls inside the runtime. To build the runtime in debug mode, just add -XEMBEDDED_RP2040_BUILD=Debug to your gprbuild flags. When building your project with alr build you can do:

alr build -- -XEMBEDDED_RP2040_BUILD=Debug