Multithread breaks file operations on pico2w.
Port, board and/or hardware
RPI_PICO2_W
MicroPython version
MicroPython v1.25.0-preview.180.g495ce91ca on 2025-01-06; Raspberry Pi Pico 2 W with RP2350
Reproduction
- copy the below threads using code and run it:
import time
import _thread
global killme
def threadtest():
global killme
print("Other starts")
while True:
if killme:
break
print("másik thread")
time.sleep(3.17)
print("Other ends")
killme = False
try:
new_thread = _thread.start_new_thread(threadtest, ())
print("Main starts")
while True:
print("Main thread")
time.sleep(1)
except KeyboardInterrupt as theInterrupt:
print("Main ends")
killme = True
- run it
- stop it
- try to copy or delete any file with mpremote, it will hang
- powercycle (pull out the usb conenctor and back) and things will work until I run the above code again.
Expected behaviour
Expected to be able to upload code.
Observed behaviour
Was not able to upload code.
Additional Information
When I copied/ran non-threaded code, a simple hello world the problem did not happen.
Code of Conduct
Yes, I agree
rp2: flash writes broken after starting core1 and performing a soft reset
Port, board and/or hardware
rp2040, rp2350 (Pico, Pico 2, Pico W, Pico 2 W)
MicroPython version
N/A, but tested on MicroPython v1.25.0-preview.217.gb4f53a0e51.dirty and various stable releases.
Reproduction
If I run the following code (via Thonny) then it breaks my ability to save files (trying to write to flash will cause a lockup) until I hard reset:
import _thread
def core1():
pass
_thread.start_new_thread(core1, ())
while True:
pass
If I remove multicore_lockout_start_blocking(); and multicore_lockout_end_blocking(); it will work fine. Since my core1 is already doing nothing (spinning on WFI) there's no need to make sure it's doing nothing.
Expected behaviour
I expect it to soft reset and for flash IO to work as normal.
Observed behaviour
A "Ctrl+C" will stop the main loop on core0 but leave core1 spinning, flash writes will work.
A soft reset (stop in Thonny) will stop/reset core1, and flash writes will break.
Additional Information
The bug happens because a soft reset will reset core1, but will not reset the multicore lockout victim state. The check on multicore_lockout_victim_is_initialized(1 - get_core_num()) will pass, but multicore_lockout_start_blocking() will block forever, since multicore_lockout_victim_is_initialized just returns an incorrect boolean value that isn't reset by multicore_reset_core1()
This is documented in Pico SDK here: https://github.com/raspberrypi/pico-sdk/blob/95ea6acad131124694cda1c162c52cd30e0aece0/src/rp2_common/pico_multicore/multicore.c#L26-L32
This is an upstream bug in Pico SDK, documented here https://github.com/raspberrypi/pico-sdk/issues/2201
There may be a downstream workaround in the interim. For example MICROPY_BEGIN_ATOMIC_SECTION checks for core1_entry
Code of Conduct
Yes, I agree