diff --git a/flash/program/flash_program.c b/flash/program/flash_program.c index 7333acde3..af621756d 100644 --- a/flash/program/flash_program.c +++ b/flash/program/flash_program.c @@ -8,6 +8,7 @@ #include #include "pico/stdlib.h" +#include "pico/flash.h" #include "hardware/flash.h" // We're going to erase and reprogram a region 256k from the start of flash. @@ -26,6 +27,19 @@ void print_buf(const uint8_t *buf, size_t len) { } } +// This function will be called when it's safe to call flash_range_erase +static void call_flash_range_erase(void *param) { + uint32_t offset = (uint32_t)param; + flash_range_erase(offset, FLASH_SECTOR_SIZE); +} + +// This function will be called when it's safe to call flash_range_program +static void call_flash_range_program(void *param) { + uint32_t offset = ((uintptr_t*)param)[0]; + const uint8_t *data = (const uint8_t *)((uintptr_t*)param)[1]; + flash_range_program(offset, data, FLASH_PAGE_SIZE); +} + int main() { stdio_init_all(); uint8_t random_data[FLASH_PAGE_SIZE]; @@ -37,12 +51,21 @@ int main() { // Note that a whole number of sectors must be erased at a time. printf("\nErasing target region...\n"); - flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE); + + // Flash is "execute in place" and so will be in use when any code runs, e.g. an interrupt handler or code running on a different core + // Calling flash_range_erase or flash_range_program at the same time as flash is running code would cause a crash. + // flash_safe_execute disables interrupts and tries to cooperate with the other core to ensure flash is not in use + // See the documentation for flash_safe_execute and its assumptions and limitations + int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); + hard_assert(rc == PICO_OK); + printf("Done. Read back target region:\n"); print_buf(flash_target_contents, FLASH_PAGE_SIZE); printf("\nProgramming target region...\n"); - flash_range_program(FLASH_TARGET_OFFSET, random_data, FLASH_PAGE_SIZE); + uintptr_t params[] = { FLASH_TARGET_OFFSET, (uintptr_t)random_data}; + rc = flash_safe_execute(call_flash_range_program, params, UINT32_MAX); + hard_assert(rc == PICO_OK); printf("Done. Read back target region:\n"); print_buf(flash_target_contents, FLASH_PAGE_SIZE);