Pico W ENOMEM error when (re)using PIO (rp2_pio_init, CYW43)
First reported here: Pico W ENOMEM error when using PIO - Raspberry Pi Forums.
A program that uses PIO (such as the example code: micropython/pio_1hz.py at master · micropython/micropython) can't be reliably stopped and restarted on a Pico W, while it can on a Pico.
Expected result: being able to stop and start PIO example at will
Actual result: after a small number of attempts OSError: [Errno 12] ENOMEM
The cause appears to be identified as PIO.remove_program() not being usable when the CYW43 driver is loaded, as the CYW43 itself is running a PIO program.
Indeed, comments inside rp2_pio_init() suggest this may be an issue:
void rp2_pio_init(void) {
// Reset all PIO instruction memory.
#if MICROPY_PY_NETWORK_CYW43
// TODO: cannot reset PIO memory when CYW43 driver is enabled and active
// because it uses a PIO for the bus interface.
Version:
MicroPython v1.19.1 on 2022-07-29; Raspberry Pi Pico W with RP2040
rp2-pico-w-20220729-unstable-v1.19.1-223-g963e599ec.uf2
rp2/rp2_pio: Track use of PIO resources and free them on soft reset.
Prior to this commit, on Pico W (where the CYW43 driver is enabled) the PIO instruction memory was not released on soft reset, so using PIO after a soft reset would eventually (after a few soft resets) lead to ENOMEM when allocating a PIO program.
This commit fixes that by tracking the use of PIO memory by this module and freeing it on soft reset.
Similarly, use of the state machines themselves are tracked and released on soft reset.
Fixes issue #9003.