embassy-sync

This commit is contained in:
ivmarkov 2022-09-19 09:16:44 +03:00
parent eea491e132
commit e0d1d4c44b
3 changed files with 73 additions and 6 deletions

View File

@ -32,6 +32,7 @@ embedded-hal = "=1.0.0-alpha.8"
embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] }
esp-idf-sys = { version = "0.31.9", optional = true, default-features = false, features = ["native"] }
critical-section = { version = "1.1", optional = true }
embassy-sync = { version = "0.1", optional = true, git = "https://github.com/ivmarkov/embassy" }
embassy-time = { version = "0.1", optional = true, features = ["tick-hz-1_000_000"], git = "https://github.com/ivmarkov/embassy" }
edge-executor = { version = "0.2", optional = true, default-features = false }

View File

@ -108,3 +108,35 @@ pub mod critical_section {
#[cfg(feature = "critical-section-mutex")]
critical_section::set_impl!(EspCriticalSection);
}
#[cfg(feature = "embassy-sync")]
pub mod embassy_sync {
use embassy_sync::blocking_mutex::raw::RawMutex;
/// A mutex that allows borrowing data across executors but NOT accross interrupts.
///
/// # Safety
///
/// This mutex is safe to share between different executors.
pub struct CriticalSectionRawMutex(super::CriticalSection);
unsafe impl Send for CriticalSectionRawMutex {}
unsafe impl Sync for CriticalSectionRawMutex {}
impl CriticalSectionRawMutex {
/// Create a new `CriticalSectionRawMutex`.
pub const fn new() -> Self {
Self(super::CriticalSection::new())
}
}
unsafe impl RawMutex for CriticalSectionRawMutex {
const INIT: Self = Self::new();
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
let _guard = self.0.enter();
f()
}
}
}

View File

@ -2,6 +2,8 @@ use core::sync::atomic::{AtomicU64, Ordering};
use esp_idf_sys::*;
pub(crate) static CS: CriticalSection = CriticalSection::new();
/// Returns true if the currently active core is executing an ISR request
#[inline(always)]
#[link_section = ".iram1.interrupt_active"]
@ -214,28 +216,60 @@ impl<'a> Drop for CriticalSectionGuard<'a> {
#[inline(always)]
#[link_section = ".iram1.interrupt_free"]
pub fn free<R>(f: impl FnOnce() -> R) -> R {
let cs = CriticalSection::new();
let _guard = cs.enter();
let _guard = CS.enter();
f()
}
#[cfg(feature = "critical-section")]
pub mod critical_section {
static CS: super::CriticalSection = super::CriticalSection::new();
pub struct EspCriticalSection {}
unsafe impl critical_section::Impl for EspCriticalSection {
unsafe fn acquire() {
super::enter(&CS);
super::enter(&super::CS);
}
unsafe fn release(_token: ()) {
super::exit(&CS);
super::exit(&super::CS);
}
}
#[cfg(feature = "critical-section-interrupt")]
critical_section::set_impl!(EspCriticalSection);
}
#[cfg(feature = "embassy-sync")]
pub mod embassy_sync {
use core::marker::PhantomData;
use embassy_sync::blocking_mutex::raw::RawMutex;
/// A mutex that allows borrowing data across executors and interrupts.
///
/// # Safety
///
/// This mutex is safe to share between different executors and interrupts.
pub struct CriticalSectionRawMutex {
_phantom: PhantomData<()>,
}
unsafe impl Send for CriticalSectionRawMutex {}
unsafe impl Sync for CriticalSectionRawMutex {}
impl CriticalSectionRawMutex {
/// Create a new `CriticalSectionRawMutex`.
pub const fn new() -> Self {
Self {
_phantom: PhantomData,
}
}
}
unsafe impl RawMutex for CriticalSectionRawMutex {
const INIT: Self = Self::new();
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
super::free(f)
}
}
}