ports/rp2: "Uncaught exception in IRQ callback handler" when retrieving PIO FIFO value with MSB set
Port, board and/or hardware
Official Pico w/rp2040
MicroPython version
MicroPython v1.24.0 on 2024-10-25; Raspberry Pi Pico with RP2040
Reproduction
uncaught_exception_test.py.txt
Expected behaviour
MPY: soft reboot
0x12345678
0x12345678
Observed behaviour
MPY: soft reboot
Uncaught exception in IRQ callback handler
Traceback (most recent call last):
File "<stdin>", line 33, in irq_handler
MemoryError: memory allocation failed, heap is locked
0x00000000
0x00000000
Additional Information
Some discussion/commentary here:
https://github.com/micropython/micropython/blob/master/ports/rp2/rp2_pio.c#L820
Code of Conduct
Yes, I agree
ports/rp2: Lazy PIO handlers.
Summary
This change has (or should have, famous last words) no impact on vanilla MicroPython builds, but is intended to avoid RP2's PIO implementation from trampling PIO usage in USER_C_MODULES.
This is consistent with PIOs tracking of used state machines and managed programs, and makes working with PIO in USER_C_MODULES much less of an uphill battle.
Since PIO deinit runs before gc_sweep_all it's impossible to work around this wrinkle otherwise. A module finalizer does not get the opportunity to put the PIOs back into a state which wont crash rp2_pio_deinit.
rp2_pio.c:
- init: Avoid exclusive handlers being added to all PIOs and add them when needed.
- deinit: Only remove handlers we have set.
- rp2_pio_irq: Add the exlusive handler if needed.
- rp2_state_mahcine_irq: Add the exclusive handler if needed.
If a PIO's interrupt is in use, it will raise:
ValueError: irq claimed by external resource
Testing
I've performed some basic tests running pio_1hz.py with both sm.irq and pio.irq functions. Both IRQs still fire as expected, and I can soft reset.
In my work-in-progress that uses this feature, rp2_pio.c no longer trounces our C module code.
I have not yet tested the impact this has on Pico W (none, hopefully).
Trade-offs and Alternatives
This probably comes at a small cost in additional code size, but brings PIO handlers in line with the managed PIO instruction memory and management of individual state machines.