v2.0.0
Functions
pico_flash
High Level APIs

High level flash API. More...

## Functions
bool | flash_safe_execute_core_init (void)
| Initialize a core such that the other core can lock it out during flash_safe_execute. More...
bool | flash_safe_execute_core_deinit (void)
| De-initialize work done by flash_safe_execute_core_init. More...
int | flash_safe_execute (void(*func)(void *), void *param, uint32_t enter_exit_timeout_ms)
| Execute a function with IRQs disabled and with the other core also not executing/reading flash. More...
flash_safety_helper_t * | get_flash_safety_helper (void)
| Internal method to return the flash safety helper implementation. More...

## Detailed Description

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 successfully 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:

1. FreeRTOS smp with `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.
2. FreeRTOS non SMP with pico_multicore - Again, there is no way to force code execution between a FreeRTOS core and a non FreeRTOS core.
3. pico_multicore without flash_safe_execute_core_init() having been called on the other core - The flash_safe_execute method does not know if code is executing on the other core, so it has to assume it is. Either way, it is not able to intervene if flash_safe_execute_core_init() has not been called on the other core.

Fortunately, all is not lost in this situation, you may:

- Set PICO_FLASH_ASSUME_CORE0_SAFE=1 to explicitly say that core 0 is never using flash.
- Set PICO_FLASH_ASSUME_CORE1_SAFE=1 to explicitly say that core 1 is never using flash.

## Function Documentation

## ◆ flash_safe_execute()

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.

Parameters

  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

Returns
  PICO_OK on success (the function will have been called). PICO_ERROR_TIMEOUT on timeout (the function may have been called). PICO_ERROR_NOT_PERMITTED if safe execution is not possible (the function will not have been called). PICO_ERROR_INSUFFICIENT_RESOURCES if the method fails due to dynamic resource exhaustion (the function will not have been called)

Note
  if PICO_FLASH_ASSERT_ON_UNSAFE is 1, this function will assert in debug mode vs returning PICO_ERROR_NOT_PERMITTED

## ◆ flash_safe_execute_core_deinit()

bool flash_safe_execute_core_deinit | ( | void |  | ) |

De-initialize work done by flash_safe_execute_core_init.

Returns
  true on success

## ◆ 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.

Note
  This is not necessary for FreeRTOS SMP, but should be used when launching via multicore_launch_core1

Returns
  true on success; there is no need to call flash_safe_execute_core_deinit() on failure.

## ◆ get_flash_safety_helper()

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.

Returns
  the flash_safety_helper_t