diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-12-23 12:57:55 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-12-23 12:57:55 +0000 |
| commit | 7561fa19348530ce85e2645e0be8801b9b2bbe13 (patch) | |
| tree | 79d18cfbe2678306cb3d076033965837cb70ddc9 | |
| parent | 63d980df7ed9f946caeaae9ddf6f0ba1edbaf741 (diff) | |
| parent | 79269570674ae0778fe4593037ec46bf46a3f06e (diff) | |
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 <[email protected]>
| -rw-r--r-- | embassy/Cargo.toml | 17 | ||||
| -rw-r--r-- | embassy/src/blocking_mutex/kind.rs | 13 | ||||
| -rw-r--r-- | embassy/src/blocking_mutex/mod.rs | 121 | ||||
| -rw-r--r-- | embassy/src/executor/arch/cortex_m.rs (renamed from embassy/src/executor/arch/arm.rs) | 0 | ||||
| -rw-r--r-- | embassy/src/executor/mod.rs | 25 | ||||
| -rw-r--r-- | embassy/src/lib.rs | 1 |
6 files changed, 107 insertions, 70 deletions
diff --git a/embassy/Cargo.toml b/embassy/Cargo.toml index bbe657f40..611c35eed 100644 --- a/embassy/Cargo.toml +++ b/embassy/Cargo.toml | |||
| @@ -29,7 +29,6 @@ executor-agnostic = [] | |||
| 29 | defmt = { version = "0.3", optional = true } | 29 | defmt = { version = "0.3", optional = true } |
| 30 | log = { version = "0.4.14", optional = true } | 30 | log = { version = "0.4.14", optional = true } |
| 31 | 31 | ||
| 32 | cortex-m = "0.7.3" | ||
| 33 | futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } | 32 | futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } |
| 34 | pin-project = { version = "1.0.8", default-features = false } | 33 | pin-project = { version = "1.0.8", default-features = false } |
| 35 | embassy-macros = { version = "0.1.0", path = "../embassy-macros"} | 34 | embassy-macros = { version = "0.1.0", path = "../embassy-macros"} |
| @@ -38,12 +37,28 @@ atomic-polyfill = "0.1.5" | |||
| 38 | critical-section = "0.2.5" | 37 | critical-section = "0.2.5" |
| 39 | embedded-hal = "0.2.6" | 38 | embedded-hal = "0.2.6" |
| 40 | heapless = "0.7.5" | 39 | heapless = "0.7.5" |
| 40 | cfg-if = "1.0.0" | ||
| 41 | 41 | ||
| 42 | # WASM dependencies | 42 | # WASM dependencies |
| 43 | wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true } | 43 | wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true } |
| 44 | js-sys = { version = "0.3", optional = true } | 44 | js-sys = { version = "0.3", optional = true } |
| 45 | wasm-timer = { version = "0.2.5", optional = true } | 45 | wasm-timer = { version = "0.2.5", optional = true } |
| 46 | 46 | ||
| 47 | [target."thumbv6m-none-eabi".dependencies] | ||
| 48 | cortex-m = "0.7.3" | ||
| 49 | [target."thumbv7m-none-eabi".dependencies] | ||
| 50 | cortex-m = "0.7.3" | ||
| 51 | [target."thumbv7em-none-eabi".dependencies] | ||
| 52 | cortex-m = "0.7.3" | ||
| 53 | [target."thumbv7em-none-eabihf".dependencies] | ||
| 54 | cortex-m = "0.7.3" | ||
| 55 | [target."thumbv8m.base-none-eabi".dependencies] | ||
| 56 | cortex-m = "0.7.3" | ||
| 57 | [target."thumbv8m.main-none-eabi".dependencies] | ||
| 58 | cortex-m = "0.7.3" | ||
| 59 | [target."thumbv8m.main-none-eabihf".dependencies] | ||
| 60 | cortex-m = "0.7.3" | ||
| 61 | |||
| 47 | [dev-dependencies] | 62 | [dev-dependencies] |
| 48 | embassy = { path = ".", features = ["executor-agnostic"] } | 63 | embassy = { path = ".", features = ["executor-agnostic"] } |
| 49 | futures-executor = { version = "0.3.17", features = [ "thread-pool" ] } | 64 | futures-executor = { version = "0.3.17", features = [ "thread-pool" ] } |
diff --git a/embassy/src/blocking_mutex/kind.rs b/embassy/src/blocking_mutex/kind.rs index 30fc90497..a4a45605f 100644 --- a/embassy/src/blocking_mutex/kind.rs +++ b/embassy/src/blocking_mutex/kind.rs | |||
| @@ -1,19 +1,20 @@ | |||
| 1 | use super::{CriticalSectionMutex, Mutex, NoopMutex, ThreadModeMutex}; | ||
| 2 | |||
| 3 | pub trait MutexKind { | 1 | pub trait MutexKind { |
| 4 | type Mutex<T>: Mutex<Data = T>; | 2 | type Mutex<T>: super::Mutex<Data = T>; |
| 5 | } | 3 | } |
| 6 | 4 | ||
| 7 | pub enum CriticalSection {} | 5 | pub enum CriticalSection {} |
| 8 | impl MutexKind for CriticalSection { | 6 | impl MutexKind for CriticalSection { |
| 9 | type Mutex<T> = CriticalSectionMutex<T>; | 7 | type Mutex<T> = super::CriticalSectionMutex<T>; |
| 10 | } | 8 | } |
| 11 | 9 | ||
| 10 | #[cfg(any(cortex_m, feature = "std"))] | ||
| 12 | pub enum ThreadMode {} | 11 | pub enum ThreadMode {} |
| 12 | #[cfg(any(cortex_m, feature = "std"))] | ||
| 13 | impl MutexKind for ThreadMode { | 13 | impl MutexKind for ThreadMode { |
| 14 | type Mutex<T> = ThreadModeMutex<T>; | 14 | type Mutex<T> = super::ThreadModeMutex<T>; |
| 15 | } | 15 | } |
| 16 | |||
| 16 | pub enum Noop {} | 17 | pub enum Noop {} |
| 17 | impl MutexKind for Noop { | 18 | impl MutexKind for Noop { |
| 18 | type Mutex<T> = NoopMutex<T>; | 19 | type Mutex<T> = super::NoopMutex<T>; |
| 19 | } | 20 | } |
diff --git a/embassy/src/blocking_mutex/mod.rs b/embassy/src/blocking_mutex/mod.rs index 8ada27cb3..949531392 100644 --- a/embassy/src/blocking_mutex/mod.rs +++ b/embassy/src/blocking_mutex/mod.rs | |||
| @@ -62,75 +62,82 @@ impl<T> Mutex for CriticalSectionMutex<T> { | |||
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /// A "mutex" that only allows borrowing from thread mode. | 65 | #[cfg(any(cortex_m, feature = "std"))] |
| 66 | /// | 66 | pub use thread_mode_mutex::*; |
| 67 | /// # Safety | 67 | #[cfg(any(cortex_m, feature = "std"))] |
| 68 | /// | 68 | mod thread_mode_mutex { |
| 69 | /// **This Mutex is only safe on single-core systems.** | 69 | use super::*; |
| 70 | /// | 70 | |
| 71 | /// On multi-core systems, a `ThreadModeMutex` **is not sufficient** to ensure exclusive access. | 71 | /// A "mutex" that only allows borrowing from thread mode. |
| 72 | pub struct ThreadModeMutex<T> { | 72 | /// |
| 73 | inner: UnsafeCell<T>, | 73 | /// # Safety |
| 74 | } | 74 | /// |
| 75 | 75 | /// **This Mutex is only safe on single-core systems.** | |
| 76 | // NOTE: ThreadModeMutex only allows borrowing from one execution context ever: thread mode. | 76 | /// |
| 77 | // Therefore it cannot be used to send non-sendable stuff between execution contexts, so it can | 77 | /// On multi-core systems, a `ThreadModeMutex` **is not sufficient** to ensure exclusive access. |
| 78 | // be Send+Sync even if T is not Send (unlike CriticalSectionMutex) | 78 | pub struct ThreadModeMutex<T> { |
| 79 | unsafe impl<T> Sync for ThreadModeMutex<T> {} | 79 | inner: UnsafeCell<T>, |
| 80 | unsafe impl<T> Send for ThreadModeMutex<T> {} | 80 | } |
| 81 | 81 | ||
| 82 | impl<T> ThreadModeMutex<T> { | 82 | // NOTE: ThreadModeMutex only allows borrowing from one execution context ever: thread mode. |
| 83 | /// Creates a new mutex | 83 | // Therefore it cannot be used to send non-sendable stuff between execution contexts, so it can |
| 84 | pub const fn new(value: T) -> Self { | 84 | // be Send+Sync even if T is not Send (unlike CriticalSectionMutex) |
| 85 | ThreadModeMutex { | 85 | unsafe impl<T> Sync for ThreadModeMutex<T> {} |
| 86 | inner: UnsafeCell::new(value), | 86 | unsafe impl<T> Send for ThreadModeMutex<T> {} |
| 87 | |||
| 88 | impl<T> ThreadModeMutex<T> { | ||
| 89 | /// Creates a new mutex | ||
| 90 | pub const fn new(value: T) -> Self { | ||
| 91 | ThreadModeMutex { | ||
| 92 | inner: UnsafeCell::new(value), | ||
| 93 | } | ||
| 87 | } | 94 | } |
| 88 | } | ||
| 89 | 95 | ||
| 90 | /// Borrows the data | 96 | /// Borrows the data |
| 91 | pub fn borrow(&self) -> &T { | 97 | pub fn borrow(&self) -> &T { |
| 92 | assert!( | 98 | assert!( |
| 93 | in_thread_mode(), | 99 | in_thread_mode(), |
| 94 | "ThreadModeMutex can only be borrowed from thread mode." | 100 | "ThreadModeMutex can only be borrowed from thread mode." |
| 95 | ); | 101 | ); |
| 96 | unsafe { &*self.inner.get() } | 102 | unsafe { &*self.inner.get() } |
| 103 | } | ||
| 97 | } | 104 | } |
| 98 | } | ||
| 99 | 105 | ||
| 100 | impl<T> Mutex for ThreadModeMutex<T> { | 106 | impl<T> Mutex for ThreadModeMutex<T> { |
| 101 | type Data = T; | 107 | type Data = T; |
| 102 | 108 | ||
| 103 | fn new(data: T) -> Self { | 109 | fn new(data: T) -> Self { |
| 104 | Self::new(data) | 110 | Self::new(data) |
| 105 | } | 111 | } |
| 106 | 112 | ||
| 107 | fn lock<R>(&self, f: impl FnOnce(&Self::Data) -> R) -> R { | 113 | fn lock<R>(&self, f: impl FnOnce(&Self::Data) -> R) -> R { |
| 108 | f(self.borrow()) | 114 | f(self.borrow()) |
| 115 | } | ||
| 109 | } | 116 | } |
| 110 | } | ||
| 111 | 117 | ||
| 112 | impl<T> Drop for ThreadModeMutex<T> { | 118 | impl<T> Drop for ThreadModeMutex<T> { |
| 113 | fn drop(&mut self) { | 119 | fn drop(&mut self) { |
| 114 | // Only allow dropping from thread mode. Dropping calls drop on the inner `T`, so | 120 | // Only allow dropping from thread mode. Dropping calls drop on the inner `T`, so |
| 115 | // `drop` needs the same guarantees as `lock`. `ThreadModeMutex<T>` is Send even if | 121 | // `drop` needs the same guarantees as `lock`. `ThreadModeMutex<T>` is Send even if |
| 116 | // T isn't, so without this check a user could create a ThreadModeMutex in thread mode, | 122 | // T isn't, so without this check a user could create a ThreadModeMutex in thread mode, |
| 117 | // send it to interrupt context and drop it there, which would "send" a T even if T is not Send. | 123 | // send it to interrupt context and drop it there, which would "send" a T even if T is not Send. |
| 118 | assert!( | 124 | assert!( |
| 119 | in_thread_mode(), | 125 | in_thread_mode(), |
| 120 | "ThreadModeMutex can only be dropped from thread mode." | 126 | "ThreadModeMutex can only be dropped from thread mode." |
| 121 | ); | 127 | ); |
| 122 | 128 | ||
| 123 | // Drop of the inner `T` happens after this. | 129 | // Drop of the inner `T` happens after this. |
| 130 | } | ||
| 124 | } | 131 | } |
| 125 | } | ||
| 126 | 132 | ||
| 127 | pub fn in_thread_mode() -> bool { | 133 | pub fn in_thread_mode() -> bool { |
| 128 | #[cfg(feature = "std")] | 134 | #[cfg(feature = "std")] |
| 129 | return Some("main") == std::thread::current().name(); | 135 | return Some("main") == std::thread::current().name(); |
| 130 | 136 | ||
| 131 | #[cfg(not(feature = "std"))] | 137 | #[cfg(not(feature = "std"))] |
| 132 | return cortex_m::peripheral::SCB::vect_active() | 138 | return cortex_m::peripheral::SCB::vect_active() |
| 133 | == cortex_m::peripheral::scb::VectActive::ThreadMode; | 139 | == cortex_m::peripheral::scb::VectActive::ThreadMode; |
| 140 | } | ||
| 134 | } | 141 | } |
| 135 | 142 | ||
| 136 | /// A "mutex" that does nothing and cannot be shared between threads. | 143 | /// A "mutex" that does nothing and cannot be shared between threads. |
diff --git a/embassy/src/executor/arch/arm.rs b/embassy/src/executor/arch/cortex_m.rs index d23a595ff..d23a595ff 100644 --- a/embassy/src/executor/arch/arm.rs +++ b/embassy/src/executor/arch/cortex_m.rs | |||
diff --git a/embassy/src/executor/mod.rs b/embassy/src/executor/mod.rs index 3ec24c13c..5b53b8d0b 100644 --- a/embassy/src/executor/mod.rs +++ b/embassy/src/executor/mod.rs | |||
| @@ -2,12 +2,25 @@ | |||
| 2 | 2 | ||
| 3 | #![deny(missing_docs)] | 3 | #![deny(missing_docs)] |
| 4 | 4 | ||
| 5 | #[cfg_attr(feature = "std", path = "arch/std.rs")] | 5 | cfg_if::cfg_if! { |
| 6 | #[cfg_attr(feature = "wasm", path = "arch/wasm.rs")] | 6 | if #[cfg(cortex_m)] { |
| 7 | #[cfg_attr(not(any(feature = "std", feature = "wasm")), path = "arch/arm.rs")] | 7 | #[path="arch/cortex_m.rs"] |
| 8 | mod arch; | 8 | mod arch; |
| 9 | pub use arch::*; | ||
| 10 | } | ||
| 11 | else if #[cfg(feature="wasm")] { | ||
| 12 | #[path="arch/wasm.rs"] | ||
| 13 | mod arch; | ||
| 14 | pub use arch::*; | ||
| 15 | } | ||
| 16 | else if #[cfg(feature="std")] { | ||
| 17 | #[path="arch/std.rs"] | ||
| 18 | mod arch; | ||
| 19 | pub use arch::*; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 9 | pub mod raw; | 23 | pub mod raw; |
| 10 | mod spawner; | ||
| 11 | 24 | ||
| 12 | pub use arch::*; | 25 | mod spawner; |
| 13 | pub use spawner::*; | 26 | pub use spawner::*; |
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs index a74d1a514..9d8ef3888 100644 --- a/embassy/src/lib.rs +++ b/embassy/src/lib.rs | |||
| @@ -13,6 +13,7 @@ pub mod channel; | |||
| 13 | pub mod waitqueue; | 13 | pub mod waitqueue; |
| 14 | 14 | ||
| 15 | pub mod executor; | 15 | pub mod executor; |
| 16 | #[cfg(cortex_m)] | ||
| 16 | pub mod interrupt; | 17 | pub mod interrupt; |
| 17 | pub mod io; | 18 | pub mod io; |
| 18 | #[cfg(feature = "time")] | 19 | #[cfg(feature = "time")] |
