diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index a72a1a667..30f486ccc 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -80,7 +80,7 @@ stm32-fmc = "0.3.0" cfg-if = "1.0.0" embedded-io = { version = "0.6.0" } embedded-io-async = { version = "0.6.1" } -chrono = { version = "^0.4", default-features = false, optional = true} +chrono = { version = "^0.4", default-features = false, optional = true } bit_field = "0.10.2" document-features = "0.2.7" diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 03c0eda1d..12ebbae2d 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -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: UnsafeCell>, } + 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) -> 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) -> Option { 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) -> 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")] diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 0656619b1..8022a35a4 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -59,8 +59,8 @@ static CLOCK_FREQS_PTR: core::sync::atomic::AtomicPtr> = core::sync::atomic::AtomicPtr::new(core::ptr::null_mut()); #[cfg(feature = "_dual-core")] -pub(crate) fn set_freqs_ptr(freqs: &'static MaybeUninit) { - CLOCK_FREQS_PTR.store(freqs as *const _ as *mut _, core::sync::atomic::Ordering::SeqCst); +pub(crate) fn set_freqs_ptr(freqs: *mut MaybeUninit) { + CLOCK_FREQS_PTR.store(freqs, core::sync::atomic::Ordering::SeqCst); } #[cfg(not(feature = "_dual-core"))] diff --git a/examples/stm32h755cm4/memory.x b/examples/stm32h755cm4/memory.x index 538bac586..7d60354e3 100644 --- a/examples/stm32h755cm4/memory.x +++ b/examples/stm32h755cm4/memory.x @@ -9,6 +9,7 @@ SECTIONS { .ram_d3 : { + *(.ram_d3.shared_data) *(.ram_d3) } > RAM_D3 } \ No newline at end of file diff --git a/examples/stm32h755cm4/src/bin/blinky.rs b/examples/stm32h755cm4/src/bin/blinky.rs index f750c5db6..b5c547839 100644 --- a/examples/stm32h755cm4/src/bin/blinky.rs +++ b/examples/stm32h755cm4/src/bin/blinky.rs @@ -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 = MaybeUninit::uninit(); #[embassy_executor::main] diff --git a/examples/stm32h755cm7/memory.x b/examples/stm32h755cm7/memory.x index ab2afc216..ef884796a 100644 --- a/examples/stm32h755cm7/memory.x +++ b/examples/stm32h755cm7/memory.x @@ -9,6 +9,7 @@ SECTIONS { .ram_d3 : { + *(.ram_d3.shared_data) *(.ram_d3) } > RAM_D3 } \ No newline at end of file diff --git a/examples/stm32h755cm7/src/bin/blinky.rs b/examples/stm32h755cm7/src/bin/blinky.rs index f76a136aa..94d2226c0 100644 --- a/examples/stm32h755cm7/src/bin/blinky.rs +++ b/examples/stm32h755cm7/src/bin/blinky.rs @@ -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 = MaybeUninit::uninit(); #[embassy_executor::main]