summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bell <mdb036@gmail.com>2025-01-21 21:35:08 +0000
committerDamien George <damien@micropython.org>2025-02-07 12:13:34 +1100
commit3699cf5f38736b670a26786af4025584dcb5aef2 (patch)
tree7dd94cc8fbfc4d3cae08c91832aae121ccca1f7b
parent81ab49a60759376271ad1e1fbf05bae0ffe9e7b1 (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.c14
-rw-r--r--tests/ports/rp2/rp2_thread_reset_part1.py18
-rw-r--r--tests/ports/rp2/rp2_thread_reset_part1.py.exp1
-rw-r--r--tests/ports/rp2/rp2_thread_reset_part2.py12
-rw-r--r--tests/ports/rp2/rp2_thread_reset_part2.py.exp3
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