8000 rp2/rp2_flash: Lockout second core only when doing flash erase/write. · micropython/micropython@c3989e3 · GitHub
[go: up one dir, main page]

Skip to content

Commit c3989e3

Browse files
committed
rp2/rp2_flash: Lockout second core only when doing flash erase/write.
Using the multicore lockout feature in the general atomic section makes it much more difficult to get correct. Signed-off-by: Damien George <damien@micropython.org>
1 parent 3d0b627 commit c3989e3

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

ports/rp2/mpthreadport.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ uint32_t mp_thread_begin_atomic_section(void) {
5252
// When both cores are executing, we also need to provide
5353
// full mutual exclusion.
5454
mp_thread_mutex_lock(&atomic_mutex, 1);
55-
// In case this atomic section is for flash access, then
56-
// suspend the other core.
57-
multicore_lockout_start_blocking();
5855
}
5956

6057
return save_and_disable_interrupts();
@@ -64,7 +61,6 @@ void mp_thread_end_atomic_section(uint32_t state) {
6461
restore_interrupts(state);
6562

6663
if (core1_entry) {
67-
multicore_lockout_end_blocking();
6864
mp_thread_mutex_unlock(&atomic_mutex);
6965
}
7066
}

ports/rp2/rp2_flash.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ bi_decl(bi_block_device(
7070
BINARY_INFO_BLOCK_DEV_FLAG_WRITE |
7171
BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN));
7272

73+
// Flash erase and write must run with interrupts disabled and the other core suspended,
74+
// because the XIP bit gets disabled.
75+
static uint32_t begin_critical_flash_section(void) {
76+
if (multicore_lockout_victim_is_initialized(1 - get_core_num())) {
77+
multicore_lockout_start_blocking();
78+
}
79+
return save_and_disable_interrupts();
80+
}
81+
82+
static void end_critical_flash_section(uint32_t state) {
83+
restore_interrupts(state);
84+
if (multicore_lockout_victim_is_initialized(1 - get_core_num())) {
85+
multicore_lockout_end_blocking();
86+
}
87+
}
88+
7389
STATIC mp_obj_t rp2_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
7490
// Parse arguments
7591
enum { ARG_start, ARG_len };
@@ -135,19 +151,17 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
135151
mp_buffer_info_t bufinfo;
136152
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
137153
if (n_args == 3) {
138-
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
139-
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
154+
mp_uint_t atomic_state = begin_critical_flash_section();
140155
flash_range_erase(self->flash_base + offset, bufinfo.len);
141-
MICROPY_END_ATOMIC_SECTION(atomic_state);
156+
end_critical_flash_section(atomic_state);
142157
mp_event_handle_nowait();
143158
// TODO check return value
144159
} else {
145160
offset += mp_obj_get_int(args[3]);
146161
}
147-
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
148-
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
162+
mp_uint_t atomic_state = begin_critical_flash_section();
149163
flash_range_program(self->flash_base + offset, bufinfo.buf, bufinfo.len);
150-
MICROPY_END_ATOMIC_SECTION(atomic_state);
164+
end_critical_flash_section(atomic_state);
151165
mp_event_handle_nowait();
152166
// TODO check return value
153167
return mp_const_none;
@@ -170,10 +184,9 @@ STATIC mp_obj_t rp2_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_
170184
return MP_OBJ_NEW_SMALL_INT(BLOCK_SIZE_BYTES);
171185
case MP_BLOCKDEV_IOCTL_BLOCK_ERASE: {
172186
uint32_t offset = mp_obj_get_int(arg_in) * BLOCK_SIZE_BYTES;
173-
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
174-
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
187+
mp_uint_t atomic_state = begin_critical_flash_section();
175188
flash_range_erase(self->flash_base + offset, BLOCK_SIZE_BYTES);
176-
MICROPY_END_ATOMIC_SECTION(atomic_state);
189+
end_critical_flash_section(atomic_state);
177190
// TODO check return value
178191
return MP_OBJ_NEW_SMALL_INT(0);
179192
}

0 commit comments

Comments
 (0)
0