aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-12-23 12:57:55 +0000
committerGitHub <[email protected]>2021-12-23 12:57:55 +0000
commit7561fa19348530ce85e2645e0be8801b9b2bbe13 (patch)
tree79d18cfbe2678306cb3d076033965837cb70ddc9
parent63d980df7ed9f946caeaae9ddf6f0ba1edbaf741 (diff)
parent79269570674ae0778fe4593037ec46bf46a3f06e (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.toml17
-rw-r--r--embassy/src/blocking_mutex/kind.rs13
-rw-r--r--embassy/src/blocking_mutex/mod.rs121
-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.rs25
-rw-r--r--embassy/src/lib.rs1
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 = []
29defmt = { version = "0.3", optional = true } 29defmt = { version = "0.3", optional = true }
30log = { version = "0.4.14", optional = true } 30log = { version = "0.4.14", optional = true }
31 31
32cortex-m = "0.7.3"
33futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } 32futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] }
34pin-project = { version = "1.0.8", default-features = false } 33pin-project = { version = "1.0.8", default-features = false }
35embassy-macros = { version = "0.1.0", path = "../embassy-macros"} 34embassy-macros = { version = "0.1.0", path = "../embassy-macros"}
@@ -38,12 +37,28 @@ atomic-polyfill = "0.1.5"
38critical-section = "0.2.5" 37critical-section = "0.2.5"
39embedded-hal = "0.2.6" 38embedded-hal = "0.2.6"
40heapless = "0.7.5" 39heapless = "0.7.5"
40cfg-if = "1.0.0"
41 41
42# WASM dependencies 42# WASM dependencies
43wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true } 43wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true }
44js-sys = { version = "0.3", optional = true } 44js-sys = { version = "0.3", optional = true }
45wasm-timer = { version = "0.2.5", optional = true } 45wasm-timer = { version = "0.2.5", optional = true }
46 46
47[target."thumbv6m-none-eabi".dependencies]
48cortex-m = "0.7.3"
49[target."thumbv7m-none-eabi".dependencies]
50cortex-m = "0.7.3"
51[target."thumbv7em-none-eabi".dependencies]
52cortex-m = "0.7.3"
53[target."thumbv7em-none-eabihf".dependencies]
54cortex-m = "0.7.3"
55[target."thumbv8m.base-none-eabi".dependencies]
56cortex-m = "0.7.3"
57[target."thumbv8m.main-none-eabi".dependencies]
58cortex-m = "0.7.3"
59[target."thumbv8m.main-none-eabihf".dependencies]
60cortex-m = "0.7.3"
61
47[dev-dependencies] 62[dev-dependencies]
48embassy = { path = ".", features = ["executor-agnostic"] } 63embassy = { path = ".", features = ["executor-agnostic"] }
49futures-executor = { version = "0.3.17", features = [ "thread-pool" ] } 64futures-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 @@
1use super::{CriticalSectionMutex, Mutex, NoopMutex, ThreadModeMutex};
2
3pub trait MutexKind { 1pub trait MutexKind {
4 type Mutex<T>: Mutex<Data = T>; 2 type Mutex<T>: super::Mutex<Data = T>;
5} 3}
6 4
7pub enum CriticalSection {} 5pub enum CriticalSection {}
8impl MutexKind for CriticalSection { 6impl 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"))]
12pub enum ThreadMode {} 11pub enum ThreadMode {}
12#[cfg(any(cortex_m, feature = "std"))]
13impl MutexKind for ThreadMode { 13impl MutexKind for ThreadMode {
14 type Mutex<T> = ThreadModeMutex<T>; 14 type Mutex<T> = super::ThreadModeMutex<T>;
15} 15}
16
16pub enum Noop {} 17pub enum Noop {}
17impl MutexKind for Noop { 18impl 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/// 66pub use thread_mode_mutex::*;
67/// # Safety 67#[cfg(any(cortex_m, feature = "std"))]
68/// 68mod 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.
72pub 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> {
79unsafe impl<T> Sync for ThreadModeMutex<T> {} 79 inner: UnsafeCell<T>,
80unsafe impl<T> Send for ThreadModeMutex<T> {} 80 }
81 81
82impl<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
100impl<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
112impl<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
127pub 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")] 5cfg_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"]
8mod 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
9pub mod raw; 23pub mod raw;
10mod spawner;
11 24
12pub use arch::*; 25mod spawner;
13pub use spawner::*; 26pub 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;
13pub mod waitqueue; 13pub mod waitqueue;
14 14
15pub mod executor; 15pub mod executor;
16#[cfg(cortex_m)]
16pub mod interrupt; 17pub mod interrupt;
17pub mod io; 18pub mod io;
18#[cfg(feature = "time")] 19#[cfg(feature = "time")]