Merge #555
555: Use cortex-m only on cortex-m archs. r=Dirbaio a=Dirbaio Without this, build fails for iOS. Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
commit
7561fa1934
@ -29,7 +29,6 @@ executor-agnostic = []
|
|||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
log = { version = "0.4.14", optional = true }
|
log = { version = "0.4.14", optional = true }
|
||||||
|
|
||||||
cortex-m = "0.7.3"
|
|
||||||
futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] }
|
futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] }
|
||||||
pin-project = { version = "1.0.8", default-features = false }
|
pin-project = { version = "1.0.8", default-features = false }
|
||||||
embassy-macros = { version = "0.1.0", path = "../embassy-macros"}
|
embassy-macros = { version = "0.1.0", path = "../embassy-macros"}
|
||||||
@ -38,12 +37,28 @@ atomic-polyfill = "0.1.5"
|
|||||||
critical-section = "0.2.5"
|
critical-section = "0.2.5"
|
||||||
embedded-hal = "0.2.6"
|
embedded-hal = "0.2.6"
|
||||||
heapless = "0.7.5"
|
heapless = "0.7.5"
|
||||||
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
# WASM dependencies
|
# WASM dependencies
|
||||||
wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true }
|
wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true }
|
||||||
js-sys = { version = "0.3", optional = true }
|
js-sys = { version = "0.3", optional = true }
|
||||||
wasm-timer = { version = "0.2.5", optional = true }
|
wasm-timer = { version = "0.2.5", optional = true }
|
||||||
|
|
||||||
|
[target."thumbv6m-none-eabi".dependencies]
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
[target."thumbv7m-none-eabi".dependencies]
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
[target."thumbv7em-none-eabi".dependencies]
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
[target."thumbv7em-none-eabihf".dependencies]
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
[target."thumbv8m.base-none-eabi".dependencies]
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
[target."thumbv8m.main-none-eabi".dependencies]
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
[target."thumbv8m.main-none-eabihf".dependencies]
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
embassy = { path = ".", features = ["executor-agnostic"] }
|
embassy = { path = ".", features = ["executor-agnostic"] }
|
||||||
futures-executor = { version = "0.3.17", features = [ "thread-pool" ] }
|
futures-executor = { version = "0.3.17", features = [ "thread-pool" ] }
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
use super::{CriticalSectionMutex, Mutex, NoopMutex, ThreadModeMutex};
|
|
||||||
|
|
||||||
pub trait MutexKind {
|
pub trait MutexKind {
|
||||||
type Mutex<T>: Mutex<Data = T>;
|
type Mutex<T>: super::Mutex<Data = T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum CriticalSection {}
|
pub enum CriticalSection {}
|
||||||
impl MutexKind for CriticalSection {
|
impl MutexKind for CriticalSection {
|
||||||
type Mutex<T> = CriticalSectionMutex<T>;
|
type Mutex<T> = super::CriticalSectionMutex<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(cortex_m, feature = "std"))]
|
||||||
pub enum ThreadMode {}
|
pub enum ThreadMode {}
|
||||||
|
#[cfg(any(cortex_m, feature = "std"))]
|
||||||
impl MutexKind for ThreadMode {
|
impl MutexKind for ThreadMode {
|
||||||
type Mutex<T> = ThreadModeMutex<T>;
|
type Mutex<T> = super::ThreadModeMutex<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Noop {}
|
pub enum Noop {}
|
||||||
impl MutexKind for Noop {
|
impl MutexKind for Noop {
|
||||||
type Mutex<T> = NoopMutex<T>;
|
type Mutex<T> = super::NoopMutex<T>;
|
||||||
}
|
}
|
||||||
|
@ -62,77 +62,84 @@ impl<T> Mutex for CriticalSectionMutex<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A "mutex" that only allows borrowing from thread mode.
|
#[cfg(any(cortex_m, feature = "std"))]
|
||||||
///
|
pub use thread_mode_mutex::*;
|
||||||
/// # Safety
|
#[cfg(any(cortex_m, feature = "std"))]
|
||||||
///
|
mod thread_mode_mutex {
|
||||||
/// **This Mutex is only safe on single-core systems.**
|
use super::*;
|
||||||
///
|
|
||||||
/// On multi-core systems, a `ThreadModeMutex` **is not sufficient** to ensure exclusive access.
|
|
||||||
pub struct ThreadModeMutex<T> {
|
|
||||||
inner: UnsafeCell<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: ThreadModeMutex only allows borrowing from one execution context ever: thread mode.
|
/// A "mutex" that only allows borrowing from thread mode.
|
||||||
// Therefore it cannot be used to send non-sendable stuff between execution contexts, so it can
|
///
|
||||||
// be Send+Sync even if T is not Send (unlike CriticalSectionMutex)
|
/// # Safety
|
||||||
unsafe impl<T> Sync for ThreadModeMutex<T> {}
|
///
|
||||||
unsafe impl<T> Send for ThreadModeMutex<T> {}
|
/// **This Mutex is only safe on single-core systems.**
|
||||||
|
///
|
||||||
|
/// On multi-core systems, a `ThreadModeMutex` **is not sufficient** to ensure exclusive access.
|
||||||
|
pub struct ThreadModeMutex<T> {
|
||||||
|
inner: UnsafeCell<T>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> ThreadModeMutex<T> {
|
// NOTE: ThreadModeMutex only allows borrowing from one execution context ever: thread mode.
|
||||||
/// Creates a new mutex
|
// Therefore it cannot be used to send non-sendable stuff between execution contexts, so it can
|
||||||
pub const fn new(value: T) -> Self {
|
// be Send+Sync even if T is not Send (unlike CriticalSectionMutex)
|
||||||
ThreadModeMutex {
|
unsafe impl<T> Sync for ThreadModeMutex<T> {}
|
||||||
inner: UnsafeCell::new(value),
|
unsafe impl<T> Send for ThreadModeMutex<T> {}
|
||||||
|
|
||||||
|
impl<T> ThreadModeMutex<T> {
|
||||||
|
/// Creates a new mutex
|
||||||
|
pub const fn new(value: T) -> Self {
|
||||||
|
ThreadModeMutex {
|
||||||
|
inner: UnsafeCell::new(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Borrows the data
|
||||||
|
pub fn borrow(&self) -> &T {
|
||||||
|
assert!(
|
||||||
|
in_thread_mode(),
|
||||||
|
"ThreadModeMutex can only be borrowed from thread mode."
|
||||||
|
);
|
||||||
|
unsafe { &*self.inner.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows the data
|
impl<T> Mutex for ThreadModeMutex<T> {
|
||||||
pub fn borrow(&self) -> &T {
|
type Data = T;
|
||||||
assert!(
|
|
||||||
in_thread_mode(),
|
|
||||||
"ThreadModeMutex can only be borrowed from thread mode."
|
|
||||||
);
|
|
||||||
unsafe { &*self.inner.get() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Mutex for ThreadModeMutex<T> {
|
fn new(data: T) -> Self {
|
||||||
type Data = T;
|
Self::new(data)
|
||||||
|
}
|
||||||
|
|
||||||
fn new(data: T) -> Self {
|
fn lock<R>(&self, f: impl FnOnce(&Self::Data) -> R) -> R {
|
||||||
Self::new(data)
|
f(self.borrow())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lock<R>(&self, f: impl FnOnce(&Self::Data) -> R) -> R {
|
impl<T> Drop for ThreadModeMutex<T> {
|
||||||
f(self.borrow())
|
fn drop(&mut self) {
|
||||||
|
// Only allow dropping from thread mode. Dropping calls drop on the inner `T`, so
|
||||||
|
// `drop` needs the same guarantees as `lock`. `ThreadModeMutex<T>` is Send even if
|
||||||
|
// T isn't, so without this check a user could create a ThreadModeMutex in thread mode,
|
||||||
|
// send it to interrupt context and drop it there, which would "send" a T even if T is not Send.
|
||||||
|
assert!(
|
||||||
|
in_thread_mode(),
|
||||||
|
"ThreadModeMutex can only be dropped from thread mode."
|
||||||
|
);
|
||||||
|
|
||||||
|
// Drop of the inner `T` happens after this.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Drop for ThreadModeMutex<T> {
|
pub fn in_thread_mode() -> bool {
|
||||||
fn drop(&mut self) {
|
#[cfg(feature = "std")]
|
||||||
// Only allow dropping from thread mode. Dropping calls drop on the inner `T`, so
|
return Some("main") == std::thread::current().name();
|
||||||
// `drop` needs the same guarantees as `lock`. `ThreadModeMutex<T>` is Send even if
|
|
||||||
// T isn't, so without this check a user could create a ThreadModeMutex in thread mode,
|
|
||||||
// send it to interrupt context and drop it there, which would "send" a T even if T is not Send.
|
|
||||||
assert!(
|
|
||||||
in_thread_mode(),
|
|
||||||
"ThreadModeMutex can only be dropped from thread mode."
|
|
||||||
);
|
|
||||||
|
|
||||||
// Drop of the inner `T` happens after this.
|
#[cfg(not(feature = "std"))]
|
||||||
|
return cortex_m::peripheral::SCB::vect_active()
|
||||||
|
== cortex_m::peripheral::scb::VectActive::ThreadMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn in_thread_mode() -> bool {
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
return Some("main") == std::thread::current().name();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
|
||||||
return cortex_m::peripheral::SCB::vect_active()
|
|
||||||
== cortex_m::peripheral::scb::VectActive::ThreadMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A "mutex" that does nothing and cannot be shared between threads.
|
/// A "mutex" that does nothing and cannot be shared between threads.
|
||||||
pub struct NoopMutex<T> {
|
pub struct NoopMutex<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
|
@ -2,12 +2,25 @@
|
|||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
#[cfg_attr(feature = "std", path = "arch/std.rs")]
|
cfg_if::cfg_if! {
|
||||||
#[cfg_attr(feature = "wasm", path = "arch/wasm.rs")]
|
if #[cfg(cortex_m)] {
|
||||||
#[cfg_attr(not(any(feature = "std", feature = "wasm")), path = "arch/arm.rs")]
|
#[path="arch/cortex_m.rs"]
|
||||||
mod arch;
|
mod arch;
|
||||||
pub mod raw;
|
pub use arch::*;
|
||||||
mod spawner;
|
}
|
||||||
|
else if #[cfg(feature="wasm")] {
|
||||||
|
#[path="arch/wasm.rs"]
|
||||||
|
mod arch;
|
||||||
|
pub use arch::*;
|
||||||
|
}
|
||||||
|
else if #[cfg(feature="std")] {
|
||||||
|
#[path="arch/std.rs"]
|
||||||
|
mod arch;
|
||||||
|
pub use arch::*;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub use arch::*;
|
pub mod raw;
|
||||||
|
|
||||||
|
mod spawner;
|
||||||
pub use spawner::*;
|
pub use spawner::*;
|
||||||
|
@ -13,6 +13,7 @@ pub mod channel;
|
|||||||
pub mod waitqueue;
|
pub mod waitqueue;
|
||||||
|
|
||||||
pub mod executor;
|
pub mod executor;
|
||||||
|
#[cfg(cortex_m)]
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
|
Loading…
Reference in New Issue
Block a user