rp2/rp2_flash: Workaround multicore lockout not being reset.

With regression test.

See upstream bug https://github.com/raspberrypi/pico-sdk/issues/2201

Tested-by: Angus Gratton <angus@redyak.com.au>
Signed-off-by: Mike Bell <mdb036@gmail.com>
This commit is contained in:
Mike Bell 2025-01-21 21:35:08 +00:00 committed by Damien George
parent 81ab49a607
commit 3699cf5f38
5 changed files with 46 additions and 2 deletions

View file

@ -70,10 +70,20 @@ bi_decl(bi_block_device(
BINARY_INFO_BLOCK_DEV_FLAG_WRITE |
BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN));
// This is a workaround to pico-sdk #2201: https://github.com/raspberrypi/pico-sdk/issues/2201
// which means the multicore_lockout_victim_is_initialized returns true even after core1 is reset.
static bool use_multicore_lockout(void) {
return multicore_lockout_victim_is_initialized(1 - get_core_num())
#if MICROPY_PY_THREAD
&& core1_entry != NULL
#endif
;
}
// Flash erase and write must run with interrupts disabled and the other core suspended,
// because the XIP bit gets disabled.
static uint32_t begin_critical_flash_section(void) {
if (multicore_lockout_victim_is_initialized(1 - get_core_num())) {
if (use_multicore_lockout()) {
multicore_lockout_start_blocking();
}
return save_and_disable_interrupts();
@ -81,7 +91,7 @@ static uint32_t begin_critical_flash_section(void) {
static void end_critical_flash_section(uint32_t state) {
restore_interrupts(state);
if (multicore_lockout_victim_is_initialized(1 - get_core_num())) {
if (use_multicore_lockout()) {
multicore_lockout_end_blocking();
}
}

View file

@ -0,0 +1,18 @@
# This is a regression test for https://github.com/micropython/micropython/issues/16619
# it runs in two parts by necessity:
#
# - This "part1" creates a non-terminating thread.
# - The test runner issues a soft reset, which will terminate that thread.
# - "part2" is the actual test, which is whether flash access works correctly
# after the thread was terminated by soft reset.
import _thread
def infinite():
while True:
pass
_thread.start_new_thread(infinite, ())
print("Part 1 complete...")

View file

@ -0,0 +1 @@
Part 1 complete...

View file

@ -0,0 +1,12 @@
# This is part2 of a two-part regression test, see part1
# for details of what's expected.
import os
FILENAME = "/rp2_thread_reset_test.txt"
print("Starting")
with open(FILENAME, "w") as f:
f.write("test")
print("Written")
os.unlink(FILENAME)
print("Removed")

View file

@ -0,0 +1,3 @@
Starting
Written
Removed