mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 22:32:29 +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
@ -80,7 +80,7 @@ stm32-fmc = "0.3.0"
|
|||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
embedded-io = { version = "0.6.0" }
|
embedded-io = { version = "0.6.0" }
|
||||||
embedded-io-async = { version = "0.6.1" }
|
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"
|
bit_field = "0.10.2"
|
||||||
document-features = "0.2.7"
|
document-features = "0.2.7"
|
||||||
|
|
||||||
|
@ -280,6 +280,7 @@ pub fn init(config: Config) -> Peripherals {
|
|||||||
|
|
||||||
#[cfg(feature = "_dual-core")]
|
#[cfg(feature = "_dual-core")]
|
||||||
mod dual_core {
|
mod dual_core {
|
||||||
|
use core::cell::UnsafeCell;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
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.
|
/// 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 {
|
pub struct SharedData {
|
||||||
init_flag: AtomicUsize,
|
init_flag: AtomicUsize,
|
||||||
clocks: MaybeUninit<Clocks>,
|
clocks: UnsafeCell<MaybeUninit<Clocks>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for SharedData {}
|
||||||
|
|
||||||
const INIT_DONE_FLAG: usize = 0xca11ab1e;
|
const INIT_DONE_FLAG: usize = 0xca11ab1e;
|
||||||
|
|
||||||
/// Initialize the `embassy-stm32` HAL with the provided configuration.
|
/// 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 {
|
pub fn init_primary(config: Config, shared_data: &'static MaybeUninit<SharedData>) -> Peripherals {
|
||||||
let shared_data = unsafe { shared_data.assume_init_ref() };
|
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);
|
let p = init_hw(config);
|
||||||
|
|
||||||
shared_data.init_flag.store(INIT_DONE_FLAG, Ordering::SeqCst);
|
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> {
|
pub fn try_init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Option<Peripherals> {
|
||||||
let shared_data = unsafe { shared_data.assume_init_ref() };
|
let shared_data = unsafe { shared_data.assume_init_ref() };
|
||||||
|
|
||||||
if shared_data
|
if shared_data.init_flag.load(Ordering::SeqCst) != INIT_DONE_FLAG {
|
||||||
.init_flag
|
|
||||||
.compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
return None;
|
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))
|
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
|
/// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs
|
||||||
/// for more information on its requirements.
|
/// for more information on its requirements.
|
||||||
pub fn init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Peripherals {
|
pub fn init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Peripherals {
|
||||||
let shared_data = unsafe { shared_data.assume_init_ref() };
|
loop {
|
||||||
|
if let Some(p) = try_init_secondary(shared_data) {
|
||||||
while shared_data
|
return p;
|
||||||
.init_flag
|
}
|
||||||
.compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst)
|
}
|
||||||
.is_err()
|
|
||||||
{}
|
|
||||||
|
|
||||||
init_secondary_hw(shared_data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_secondary_hw(shared_data: &'static SharedData) -> Peripherals {
|
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
|
// We use different timers on the different cores, so we have to still initialize one here
|
||||||
#[cfg(feature = "_time-driver")]
|
#[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());
|
core::sync::atomic::AtomicPtr::new(core::ptr::null_mut());
|
||||||
|
|
||||||
#[cfg(feature = "_dual-core")]
|
#[cfg(feature = "_dual-core")]
|
||||||
pub(crate) fn set_freqs_ptr(freqs: &'static MaybeUninit<Clocks>) {
|
pub(crate) fn set_freqs_ptr(freqs: *mut MaybeUninit<Clocks>) {
|
||||||
CLOCK_FREQS_PTR.store(freqs as *const _ as *mut _, core::sync::atomic::Ordering::SeqCst);
|
CLOCK_FREQS_PTR.store(freqs, core::sync::atomic::Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "_dual-core"))]
|
#[cfg(not(feature = "_dual-core"))]
|
||||||
|
@ -9,6 +9,7 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
.ram_d3 :
|
.ram_d3 :
|
||||||
{
|
{
|
||||||
|
*(.ram_d3.shared_data)
|
||||||
*(.ram_d3)
|
*(.ram_d3)
|
||||||
} > RAM_D3
|
} > RAM_D3
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ use embassy_stm32::SharedData;
|
|||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
#[link_section = ".ram_d3"]
|
#[link_section = ".ram_d3.shared_data"]
|
||||||
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
|
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
|
@ -9,6 +9,7 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
.ram_d3 :
|
.ram_d3 :
|
||||||
{
|
{
|
||||||
|
*(.ram_d3.shared_data)
|
||||||
*(.ram_d3)
|
*(.ram_d3)
|
||||||
} > RAM_D3
|
} > RAM_D3
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ use embassy_stm32::SharedData;
|
|||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
#[link_section = ".ram_d3"]
|
#[link_section = ".ram_d3.shared_data"]
|
||||||
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
|
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
|
Loading…
Reference in New Issue
Block a user