-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
rp2/rp2_flash.c: Disable IRQs before calling flash_erase/program. #7683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks for this. The change will (of course) introduce latency to IRQs (and maybe even some will be missed) when there are writes to the filesystem. But I guess there's no way around this. (On stm32 it's a bit different, the system will automatically stall any IRQs if flash is busy.) |
Yes that's true, some DMA IRQs are missed in an audio module I'm working on which causes it to record an incomplete audio stream to file... This doesn't fix it but would it be slightly better if IRQs are restored briefly after flash_range_erase (and maybe even call event hook) and then disabled again before flash_range_program ? i.e: diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c
index b89cb6fd8..204e36dad 100644
--- a/ports/rp2/rp2_flash.c
+++ b/ports/rp2/rp2_flash.c
@@ -95,12 +95,17 @@ 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) {
+ uint32_t ints = save_and_disable_interrupts();
flash_range_erase(self->flash_base + offset, bufinfo.len);
+ restore_interrupts(ints);
+ MICROPY_EVENT_POLL_HOOK
// TODO check return value
} else {
offset += mp_obj_get_int(args[3]);
}
+ uint32_t ints = save_and_disable_interrupts();
flash_range_program(self->flash_base + offset, bufinfo.buf, bufinfo.len);
+ restore_interrupts(ints);
// TODO check return value
return mp_const_none;
} Edit, maybe a better way is to exclude specific critical IRQ handlers that run from RAM with uint32_t mask = *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ISER_OFFSET));
mask &= ~(CRITICAL_IRQ_NUMBERS);
irq_set_mask_enabled(mask, false);
....
flash_range_erase(...);
flash_range_program(...);
....
irq_set_mask_enabled(mask, true); |
Yes, would be good. A similar thing was done for the esp8266, see b6e5f82 |
3c5d37f
to
6610b9c
Compare
Okay updated. |
* Flash erase/program functions disable the XIP bit.
6610b9c
to
d27403c
Compare
Used MICROPY_BEGIN/END_ATOMIC_SECTION instead. |
Merged in c82244a |
Flash erase/program functions disable the XIP bit. If any code runs from flash at the same time (ex an IRQ or code it calls) it will fail and cause a lockup.
Example using pio example + file write:
Output:
Followed by a lockup.