rp2/rp2_flash: Disable IRQs while calling flash_erase/program.

Flash erase/program functions disable the XIP bit.  If any code runs from
flash at the same time (eg an IRQ or code it calls) it will fail and cause
a lockup.
This commit is contained in:
iabdalkader 2021-08-19 02:16:30 +02:00 committed by Damien George
parent 8c4ba575fd
commit c82244a7c0
1 changed files with 11 additions and 0 deletions

View File

@ -95,12 +95,20 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
if (n_args == 3) {
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
flash_range_erase(self->flash_base + offset, bufinfo.len);
MICROPY_END_ATOMIC_SECTION(atomic_state);
MICROPY_EVENT_POLL_HOOK
// TODO check return value
} else {
offset += mp_obj_get_int(args[3]);
}
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
flash_range_program(self->flash_base + offset, bufinfo.buf, bufinfo.len);
MICROPY_END_ATOMIC_SECTION(atomic_state);
MICROPY_EVENT_POLL_HOOK
// TODO check return value
return mp_const_none;
}
@ -122,7 +130,10 @@ STATIC mp_obj_t rp2_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_
return MP_OBJ_NEW_SMALL_INT(BLOCK_SIZE_BYTES);
case MP_BLOCKDEV_IOCTL_BLOCK_ERASE: {
uint32_t offset = mp_obj_get_int(arg_in) * BLOCK_SIZE_BYTES;
// Flash erase/program must run in an atomic section because the XIP bit gets disabled.
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
flash_range_erase(self->flash_base + offset, BLOCK_SIZE_BYTES);
MICROPY_END_ATOMIC_SECTION(atomic_state);
// TODO check return value
return MP_OBJ_NEW_SMALL_INT(0);
}