Functions | |
bool | flash_safe_execute_core_init (void) |
bool | flash_safe_execute_core_deinit (void) |
int | flash_safe_execute (void(*func)(void *), void *param, uint32_t enter_exit_timeout_ms) |
flash_safety_helper_t * | get_flash_safety_helper (void) |
High level flash API
Flash cannot be erased or written to when in XIP mode. However the system cannot directly access memory in the flash address space when not in XIP mode.
It is therefore critical that no code or data is being read from flash while flash is been written or erased.
If only one core is being used, then the problem is simple - just disable interrupts; however if code is running on the other core, then it has to be asked, nicely, to avoid flash for a bit. This is hard to do if you don't have complete control of the code running on that core at all times.
This library provides a flash_safe_execute method which calls a function back having sucessfully gotten into a state where interrupts are disabled, and the other core is not executing or reading from flash.
How it does this is dependent on the supported environment (Free RTOS SMP or pico_multicore). Additionally the user can provide their own mechanism by providing a strong definition of get_flash_safety_helper().
Using the default settings, flash_safe_execute will only call the callback function if the state is safe otherwise returning an error (or an assert depending on PICO_FLASH_ASSERT_ON_UNSAFE).
There are conditions where safety would not be guaranteed:
configNUM_CORES=1
- FreeRTOS still uses pico_multicore in this case, so flash_safe_execute cannot know what the other core is doing, and there is no way to force code execution between a FreeRTOS core and a non FreeRTOS core.Fortunately, all is not lost in this situation, you may:
int flash_safe_execute | ( | void(*)(void *) | func, |
void * | param, | ||
uint32_t | enter_exit_timeout_ms | ||
) |
Execute a function with IRQs disabled and with the other core also not executing/reading flash
func | the function to call |
param | the parameter to pass to the function |
enter_exit_timeout_ms | the timeout for each of the enter/exit phases when coordinating with the other core |
bool flash_safe_execute_core_deinit | ( | void | ) |
De-initialize work done by flash_safe_execute_core_init
bool flash_safe_execute_core_init | ( | void | ) |
Initialize a core such that the other core can lock it out during flash_safe_execute.
flash_safety_helper_t* get_flash_safety_helper | ( | void | ) |
Internal method to return the flash safety helper implementation.
Advanced users can provide their own implementation of this function to perform different inter-core coordination before disabling XIP mode.