Functions to enable one core to force the other core to pause execution in a known state. More...

Functions

void multicore_lockout_victim_init (void)
 Initialize the current core such that it can be a "victim" of lockout (i.e. forced to pause in a known state by the other core) More...
 
bool multicore_lockout_victim_is_initialized (uint core_num)
 Determine if multicore_victim_init() has been called on the specified core. More...
 
void multicore_lockout_start_blocking (void)
 Request the other core to pause in a known state and wait for it to do so. More...
 
bool multicore_lockout_start_timeout_us (uint64_t timeout_us)
 Request the other core to pause in a known state and wait up to a time limit for it to do so. More...
 
void multicore_lockout_end_blocking (void)
 Release the other core from a locked out state amd wait for it to acknowledge. More...
 
bool multicore_lockout_end_timeout_us (uint64_t timeout_us)
 Release the other core from a locked out state amd wait up to a time limit for it to acknowledge. More...
 

Detailed Description

Functions to enable one core to force the other core to pause execution in a known state.

Sometimes it is useful to enter a critical section on both cores at once. On a single core system a critical section can trivially be entered by disabling interrupts, however on a multi-core system that is not sufficient, and unless the other core is polling in some way, then it will need to be interrupted in order to cooperatively enter a blocked state.

These "lockout" functions use the inter core FIFOs to cause an interrupt on one core from the other, and manage waiting for the other core to enter the "locked out" state.

The usage is that the "victim" core ... i.e the core that can be "locked out" by the other core calls multicore_lockout_victim_init to hook the FIFO interrupt. Note that either or both cores may do this.

Note
When "locked out" the victim core is paused (it is actually executing a tight loop with code in RAM) and has interrupts disabled. This makes the lockout functions suitable for use by code that wants to write to flash (at which point no code may be executing from flash)

The core which wishes to lockout the other core calls multicore_lockout_start_blocking or multicore_lockout_start_timeout_us to interrupt the other "victim" core and wait for it to be in a "locked out" state. Once the lockout is no longer needed it calls multicore_lockout_end_blocking or multicore_lockout_end_timeout_us to release the lockout and wait for confirmation.

Note
Because multicore lockout uses the intercore FIFOs, the FIFOs cannot be used for any other purpose

Function Documentation

◆ multicore_lockout_end_blocking()

void multicore_lockout_end_blocking ( void  )

Release the other core from a locked out state amd wait for it to acknowledge.

Note
The other core must previously have been "locked out" by calling a multicore_lockout_start_ function from this core

◆ multicore_lockout_end_timeout_us()

bool multicore_lockout_end_timeout_us ( uint64_t  timeout_us)

Release the other core from a locked out state amd wait up to a time limit for it to acknowledge.

The other core must previously have been "locked out" by calling a multicore_lockout_start_ function from this core

Note
be very careful using small timeout values, as a timeout here will leave the "lockout" functionality in a bad state. It is probably preferable to use multicore_lockout_end_blocking anyway as if you have already waited for the victim core to enter the lockout state, then the victim core will be ready to exit the lockout state very quickly.
Parameters
timeout_usthe timeout in microseconds
Returns
true if the other core successfully exited locked out state within the timeout, false otherwise

◆ multicore_lockout_start_blocking()

void multicore_lockout_start_blocking ( void  )

Request the other core to pause in a known state and wait for it to do so.

The other (victim) core must have previously executed multicore_lockout_victim_init()

Note
multicore_lockout_start_ functions are not nestable, and must be paired with a call to a corresponding multicore_lockout_end_blocking

◆ multicore_lockout_start_timeout_us()

bool multicore_lockout_start_timeout_us ( uint64_t  timeout_us)

Request the other core to pause in a known state and wait up to a time limit for it to do so.

The other core must have previously executed multicore_lockout_victim_init()

Note
multicore_lockout_start_ functions are not nestable, and must be paired with a call to a corresponding multicore_lockout_end_blocking
Parameters
timeout_usthe timeout in microseconds
Returns
true if the other core entered the locked out state within the timeout, false otherwise

◆ multicore_lockout_victim_init()

void multicore_lockout_victim_init ( void  )

Initialize the current core such that it can be a "victim" of lockout (i.e. forced to pause in a known state by the other core)

This code hooks the intercore FIFO IRQ, and the FIFO may not be used for any other purpose after this.

◆ multicore_lockout_victim_is_initialized()

bool multicore_lockout_victim_is_initialized ( uint  core_num)

Determine if multicore_victim_init() has been called on the specified core.

Note
this state persists even if the core is subsequently reset; therefore you are advised to always call multicore_lockout_victim_init() again after resetting a core, which had previously been initialized.
Parameters
core_numthe core number (0 or 1)
Returns
true if multicore_victim_init() has been called on the specified core, false otherwise.