diff options
| author | Mike Bell <mdb036@gmail.com> | 2025-01-21 21:35:08 +0000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-02-07 12:13:34 +1100 |
| commit | 3699cf5f38736b670a26786af4025584dcb5aef2 (patch) | |
| tree | 7dd94cc8fbfc4d3cae08c91832aae121ccca1f7b | |
| parent | 81ab49a60759376271ad1e1fbf05bae0ffe9e7b1 (diff) | |
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>
| -rw-r--r-- | ports/rp2/rp2_flash.c | 14 | ||||
| -rw-r--r-- | tests/ports/rp2/rp2_thread_reset_part1.py | 18 | ||||
| -rw-r--r-- | tests/ports/rp2/rp2_thread_reset_part1.py.exp | 1 | ||||
| -rw-r--r-- | tests/ports/rp2/rp2_thread_reset_part2.py | 12 | ||||
| -rw-r--r-- | tests/ports/rp2/rp2_thread_reset_part2.py.exp | 3 |
5 files changed, 46 insertions, 2 deletions
diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c index c1acb54e7..a487fb163 100644 --- a/ports/rp2/rp2_flash.c +++ b/ports/rp2/rp2_flash.c @@ -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(); } } diff --git a/tests/ports/rp2/rp2_thread_reset_part1.py b/tests/ports/rp2/rp2_thread_reset_part1.py new file mode 100644 index 000000000..d43868113 --- /dev/null +++ b/tests/ports/rp2/rp2_thread_reset_part1.py @@ -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...") diff --git a/tests/ports/rp2/rp2_thread_reset_part1.py.exp b/tests/ports/rp2/rp2_thread_reset_part1.py.exp new file mode 100644 index 000000000..48ea7efad --- /dev/null +++ b/tests/ports/rp2/rp2_thread_reset_part1.py.exp @@ -0,0 +1 @@ +Part 1 complete... diff --git a/tests/ports/rp2/rp2_thread_reset_part2.py b/tests/ports/rp2/rp2_thread_reset_part2.py new file mode 100644 index 000000000..15f0eaab8 --- /dev/null +++ b/tests/ports/rp2/rp2_thread_reset_part2.py @@ -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") diff --git a/tests/ports/rp2/rp2_thread_reset_part2.py.exp b/tests/ports/rp2/rp2_thread_reset_part2.py.exp new file mode 100644 index 000000000..d7581c7d2 --- /dev/null +++ b/tests/ports/rp2/rp2_thread_reset_part2.py.exp @@ -0,0 +1,3 @@ +Starting +Written +Removed |
