Skip to content

Commit b6303d8

Browse files
Use flash_safe_execute (#545)
* Use flash_safe_execute Although it's not required in this example, demonstrate how to call flash function using flash_safe_execute Fixes #510
1 parent 305489f commit b6303d8

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

flash/program/flash_program.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <stdlib.h>
99

1010
#include "pico/stdlib.h"
11+
#include "pico/flash.h"
1112
#include "hardware/flash.h"
1213

1314
// 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) {
2627
}
2728
}
2829

30+
// This function will be called when it's safe to call flash_range_erase
31+
static void call_flash_range_erase(void *param) {
32+
uint32_t offset = (uint32_t)param;
33+
flash_range_erase(offset, FLASH_SECTOR_SIZE);
34+
}
35+
36+
// This function will be called when it's safe to call flash_range_program
37+
static void call_flash_range_program(void *param) {
38+
uint32_t offset = ((uintptr_t*)param)[0];
39+
const uint8_t *data = (const uint8_t *)((uintptr_t*)param)[1];
40+
flash_range_program(offset, data, FLASH_PAGE_SIZE);
41+
}
42+
2943
int main() {
3044
stdio_init_all();
3145
uint8_t random_data[FLASH_PAGE_SIZE];
@@ -37,12 +51,22 @@ int main() {
3751

3852
// Note that a whole number of sectors must be erased at a time.
3953
printf("\nErasing target region...\n");
40-
flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);
54+
55+
// 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
56+
// or code running on a different core.
57+
// Calling flash_range_erase or flash_range_program at the same time as flash is running code would cause a crash.
58+
// flash_safe_execute disables interrupts and tries to cooperate with the other core to ensure flash is not in use
59+
// See the documentation for flash_safe_execute and its assumptions and limitations
60+
int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX);
61+
hard_assert(rc == PICO_OK);
62+
4163
printf("Done. Read back target region:\n");
4264
print_buf(flash_target_contents, FLASH_PAGE_SIZE);
4365

4466
printf("\nProgramming target region...\n");
45-
flash_range_program(FLASH_TARGET_OFFSET, random_data, FLASH_PAGE_SIZE);
67+
uintptr_t params[] = { FLASH_TARGET_OFFSET, (uintptr_t)random_data};
68+
rc = flash_safe_execute(call_flash_range_program, params, UINT32_MAX);
69+
hard_assert(rc == PICO_OK);
4670
printf("Done. Read back target region:\n");
4771
print_buf(flash_target_contents, FLASH_PAGE_SIZE);
4872

0 commit comments

Comments
 (0)