Crate rp2040_multicore_per_cpu

source ·
Expand description

§RP2040 Per-core static data

The RP2040 has two cores. The rp2040-hal crate’s multicore module makes it easy to start code on the second core. However, this brings with it the same challenges as multi-threaded programming: state in shared memory between the cores.

This crate allows you to make use of the (unstable) #[thread_local] attribute on static variables to make them per-core state. This allows the same code to run on both cores but with its own core-specific static state, such maintaining program state, or for things like DMA buffers.

For example:

#![feature(thread_local)]
extern crate rp2040_multicore_per_cpu;

#[thread_local]
static MY_COUNTER: RefCell<usize> = RefCell::new(0);

fn next_id() -> usize {
  MY_COUNTER.replace_with(|c| *c + 1)
}

Each core will get its own instance of the MY_COUNTER variable. Since these are not shared, they do not need atomic operations to update.

These core-local variables are initialized on program startup and retain their value from there on, even between invocations of Core::spawn.

If the variables are zero-initialized then they will be reserved space in the .tbss section in the executable, and then space in .bss for each core. Similarly, variables initialized with non-zero constants will be in the executable’s .tdata section, and have space reserved in .bss; the initial values are copied at program startup. Note that this uses the __pre_init hook to do this, so it won’t be available for other uses.

§Build setup

Note that this requires some setup in the linker script to allocate space for the static data. See memory.x for details. You also need to make you explicitly depend on this crate with extern crate rp2040_multicore_per_cpu;. This crate has no Rust API of its own, but must still be included in the linker line to ensure the __aeabi_read_tp function is defined.

Also note this uses the __pre_init hook from [cortex-m-rt] to set up the per-core state at reset time, making it unavailable for other uses (this is rare however).