From a8355973a54f05db1d19ed980f336106a3302840 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Tue, 3 Sep 2024 15:08:16 +0100 Subject: [PATCH 1/2] Use flash_safe_execute Although it's not required in this example, demonstrate how to call flash function using flash_safe_execute Fixes #510 --- flash/program/flash_program.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) 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); From 4c6f94c772b35226a7a507ba1a7d19178f4cd1a3 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Fri, 22 Nov 2024 12:54:31 -0600 Subject: [PATCH 2/2] Update flash_program.c minor comment tweak --- flash/program/flash_program.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flash/program/flash_program.c b/flash/program/flash_program.c index af621756d..69a0f4d2e 100644 --- a/flash/program/flash_program.c +++ b/flash/program/flash_program.c @@ -52,7 +52,8 @@ int main() { // Note that a whole number of sectors must be erased at a time. printf("\nErasing target region...\n"); - // 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 + // Flash is "execute in place" and so will be in use when any code that is stored in flash 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