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:
@@ -70,10 +70,20 @@ bi_decl(bi_block_device(
|
|||||||
BINARY_INFO_BLOCK_DEV_FLAG_WRITE |
|
BINARY_INFO_BLOCK_DEV_FLAG_WRITE |
|
||||||
BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN));
|
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,
|
// Flash erase and write must run with interrupts disabled and the other core suspended,
|
||||||
// because the XIP bit gets disabled.
|
// because the XIP bit gets disabled.
|
||||||
static uint32_t begin_critical_flash_section(void) {
|
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();
|
multicore_lockout_start_blocking();
|
||||||
}
|
}
|
||||||
return save_and_disable_interrupts();
|
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) {
|
static void end_critical_flash_section(uint32_t state) {
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
if (multicore_lockout_victim_is_initialized(1 - get_core_num())) {
|
if (use_multicore_lockout()) {
|
||||||
multicore_lockout_end_blocking();
|
multicore_lockout_end_blocking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
tests/ports/rp2/rp2_thread_reset_part1.py
Normal file
18
tests/ports/rp2/rp2_thread_reset_part1.py
Normal 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...")
|
||||||
1
tests/ports/rp2/rp2_thread_reset_part1.py.exp
Normal file
1
tests/ports/rp2/rp2_thread_reset_part1.py.exp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Part 1 complete...
|
||||||
12
tests/ports/rp2/rp2_thread_reset_part2.py
Normal file
12
tests/ports/rp2/rp2_thread_reset_part2.py
Normal 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")
|
||||||
3
tests/ports/rp2/rp2_thread_reset_part2.py.exp
Normal file
3
tests/ports/rp2/rp2_thread_reset_part2.py.exp
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Starting
|
||||||
|
Written
|
||||||
|
Removed
|
||||||
Reference in New Issue
Block a user