mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 00:02:28 +00:00
Improve shared data placement, require less atomic support and use unsafecell for the clocks
This commit is contained in:
parent
e39e93ead4
commit
2a7fe16ceb
@ -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")]
|
||||
|
@ -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"))]
|
||||
|
@ -9,6 +9,7 @@ SECTIONS
|
||||
{
|
||||
.ram_d3 :
|
||||
{
|
||||
*(.ram_d3.shared_data)
|
||||
*(.ram_d3)
|
||||
} > RAM_D3
|
||||
}
|
@ -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]
|
||||
|
@ -9,6 +9,7 @@ SECTIONS
|
||||
{
|
||||
.ram_d3 :
|
||||
{
|
||||
*(.ram_d3.shared_data)
|
||||
*(.ram_d3)
|
||||
} > RAM_D3
|
||||
}
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user