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:
parent
81ab49a607
commit
3699cf5f38
5 changed files with 46 additions and 2 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
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
|
||||
Loading…
Reference in a new issue