Improve shared data placement, require less atomic support and use unsafecell for the clocks

This commit is contained in:
Dion Dokter 2024-08-05 11:18:16 +02:00
parent e39e93ead4
commit 2a7fe16ceb
7 changed files with 22 additions and 22 deletions

View File

@ -280,6 +280,7 @@ pub fn init(config: Config) -> Peripherals {
#[cfg(feature = "_dual-core")]
mod dual_core {
use core::cell::UnsafeCell;
use core::mem::MaybeUninit;
use core::sync::atomic::{AtomicUsize, Ordering};
@ -301,9 +302,11 @@ mod dual_core {
/// This static must be placed in the same position for both cores. How and where this is done is left to the user.
pub struct SharedData {
init_flag: AtomicUsize,
clocks: MaybeUninit<Clocks>,
clocks: UnsafeCell<MaybeUninit<Clocks>>,
}
unsafe impl Sync for SharedData {}
const INIT_DONE_FLAG: usize = 0xca11ab1e;
/// Initialize the `embassy-stm32` HAL with the provided configuration.
@ -319,7 +322,7 @@ mod dual_core {
pub fn init_primary(config: Config, shared_data: &'static MaybeUninit<SharedData>) -> Peripherals {
let shared_data = unsafe { shared_data.assume_init_ref() };
rcc::set_freqs_ptr(&shared_data.clocks);
rcc::set_freqs_ptr(shared_data.clocks.get());
let p = init_hw(config);
shared_data.init_flag.store(INIT_DONE_FLAG, Ordering::SeqCst);
@ -339,14 +342,13 @@ mod dual_core {
pub fn try_init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Option<Peripherals> {
let shared_data = unsafe { shared_data.assume_init_ref() };
if shared_data
.init_flag
.compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst)
.is_err()
{
if shared_data.init_flag.load(Ordering::SeqCst) != INIT_DONE_FLAG {
return None;
}
// Separate load and store to support the CM0 of the STM32WL
shared_data.init_flag.store(0, Ordering::SeqCst);
Some(init_secondary_hw(shared_data))
}
@ -360,19 +362,15 @@ mod dual_core {
/// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs
/// for more information on its requirements.
pub fn init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Peripherals {
let shared_data = unsafe { shared_data.assume_init_ref() };
while shared_data
.init_flag
.compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst)
.is_err()
{}
init_secondary_hw(shared_data)
loop {
if let Some(p) = try_init_secondary(shared_data) {
return p;
}
}
}
fn init_secondary_hw(shared_data: &'static SharedData) -> Peripherals {
rcc::set_freqs_ptr(&shared_data.clocks);
rcc::set_freqs_ptr(shared_data.clocks.get());
// We use different timers on the different cores, so we have to still initialize one here
#[cfg(feature = "_time-driver")]

View File

@ -59,8 +59,8 @@ static CLOCK_FREQS_PTR: core::sync::atomic::AtomicPtr<MaybeUninit<Clocks>> =
core::sync::atomic::AtomicPtr::new(core::ptr::null_mut());
#[cfg(feature = "_dual-core")]
pub(crate) fn set_freqs_ptr(freqs: &'static MaybeUninit<Clocks>) {
CLOCK_FREQS_PTR.store(freqs as *const _ as *mut _, core::sync::atomic::Ordering::SeqCst);
pub(crate) fn set_freqs_ptr(freqs: *mut MaybeUninit<Clocks>) {
CLOCK_FREQS_PTR.store(freqs, core::sync::atomic::Ordering::SeqCst);
}
#[cfg(not(feature = "_dual-core"))]

View File

@ -9,6 +9,7 @@ SECTIONS
{
.ram_d3 :
{
*(.ram_d3.shared_data)
*(.ram_d3)
} > RAM_D3
}

View File

@ -10,7 +10,7 @@ use embassy_stm32::SharedData;
use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _};
#[link_section = ".ram_d3"]
#[link_section = ".ram_d3.shared_data"]
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
#[embassy_executor::main]

View File

@ -9,6 +9,7 @@ SECTIONS
{
.ram_d3 :
{
*(.ram_d3.shared_data)
*(.ram_d3)
} > RAM_D3
}

View File

@ -10,7 +10,7 @@ use embassy_stm32::SharedData;
use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _};
#[link_section = ".ram_d3"]
#[link_section = ".ram_d3.shared_data"]
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
#[embassy_executor::main]