aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2021-03-25 08:33:17 -0500
committerGitHub <[email protected]>2021-03-25 08:33:17 -0500
commit0de274800844ba9aa30bd21aa217642f109e8e7e (patch)
treeab990afab3b1465b110f390dc3f5777568172a7a
parent08990b2f6dcd0edad9b3feb4b993390738c49989 (diff)
parentea650b684c54fa5e1639e80e5f6300d640b3c9d3 (diff)
Merge pull request #108 from theunkn0wn1/doc/util
Document embassy::util
-rw-r--r--embassy/src/util/drop_bomb.rs7
-rw-r--r--embassy/src/util/forever.rs24
-rw-r--r--embassy/src/util/mod.rs1
-rw-r--r--embassy/src/util/signal.rs25
4 files changed, 57 insertions, 0 deletions
diff --git a/embassy/src/util/drop_bomb.rs b/embassy/src/util/drop_bomb.rs
index b2b0684e5..388209a23 100644
--- a/embassy/src/util/drop_bomb.rs
+++ b/embassy/src/util/drop_bomb.rs
@@ -1,6 +1,12 @@
1use crate::fmt::panic; 1use crate::fmt::panic;
2use core::mem; 2use core::mem;
3 3
4/// An explosive ordinance that panics if it is improperly disposed of.
5///
6/// This is to forbid dropping futures, when there is absolutely no other choice.
7///
8/// To correctly dispose of this device, call the [defuse](struct.DropBomb.html#method.defuse)
9/// method before this object is dropped.
4pub struct DropBomb { 10pub struct DropBomb {
5 _private: (), 11 _private: (),
6} 12}
@@ -10,6 +16,7 @@ impl DropBomb {
10 Self { _private: () } 16 Self { _private: () }
11 } 17 }
12 18
19 /// Diffuses the bomb, rendering it safe to drop.
13 pub fn defuse(self) { 20 pub fn defuse(self) {
14 mem::forget(self) 21 mem::forget(self)
15 } 22 }
diff --git a/embassy/src/util/forever.rs b/embassy/src/util/forever.rs
index ac23a3ce3..efa96f30e 100644
--- a/embassy/src/util/forever.rs
+++ b/embassy/src/util/forever.rs
@@ -3,6 +3,25 @@ use core::mem::MaybeUninit;
3 3
4use atomic_polyfill::{AtomicBool, Ordering}; 4use atomic_polyfill::{AtomicBool, Ordering};
5 5
6/// Type with static lifetime that may be written to once at runtime.
7///
8/// This may be used to initialize static objects at runtime, typically in the init routine.
9/// This is useful for objects such as Embassy's RTC, which cannot be initialized in a const
10/// context.
11///
12/// Note: IF a global mutable variable is desired, use a CriticalSectionMutex or ThreadModeMutex instead.
13///
14/// ```
15/// use embassy::util::Forever;
16/// // Using an integer for the sake of keeping this example self-contained,
17/// // see https://github.com/embassy-rs/embassy/wiki/Getting-Started for a more "proper" example.
18/// static SOME_INT: Forever<u32> =Forever::new();
19///
20/// // put returns a mutable pointer to the object stored in the forever, which may then be passed
21/// // around.
22/// let mut x = SOME_INT.put(42);
23/// assert_eq!(*x, 42);
24/// ```
6pub struct Forever<T> { 25pub struct Forever<T> {
7 used: AtomicBool, 26 used: AtomicBool,
8 t: UnsafeCell<MaybeUninit<T>>, 27 t: UnsafeCell<MaybeUninit<T>>,
@@ -19,6 +38,11 @@ impl<T> Forever<T> {
19 } 38 }
20 } 39 }
21 40
41 /// Gives this `Forever` a value.
42 ///
43 /// Panics if this `Forever` already has a value.
44 ///
45 /// Returns a mutable reference to the stored value.
22 pub fn put(&'static self, val: T) -> &'static mut T { 46 pub fn put(&'static self, val: T) -> &'static mut T {
23 if self 47 if self
24 .used 48 .used
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs
index e64e7f1f1..6917e9993 100644
--- a/embassy/src/util/mod.rs
+++ b/embassy/src/util/mod.rs
@@ -1,3 +1,4 @@
1//! Async utilities
1mod drop_bomb; 2mod drop_bomb;
2mod forever; 3mod forever;
3mod mutex; 4mod mutex;
diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs
index 41e27d4ca..0fd5c9275 100644
--- a/embassy/src/util/signal.rs
+++ b/embassy/src/util/signal.rs
@@ -10,6 +10,9 @@ use crate::executor;
10use crate::fmt::panic; 10use crate::fmt::panic;
11use crate::interrupt::{Interrupt, InterruptExt}; 11use crate::interrupt::{Interrupt, InterruptExt};
12 12
13/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks.
14///
15/// For more advanced use cases, please consider [futures-intrusive](https://crates.io/crates/futures-intrusive) channels or mutexes.
13pub struct Signal<T> { 16pub struct Signal<T> {
14 state: UnsafeCell<State<T>>, 17 state: UnsafeCell<State<T>>,
15} 18}
@@ -30,6 +33,7 @@ impl<T: Send> Signal<T> {
30 } 33 }
31 } 34 }
32 35
36 /// Mark this Signal as completed.
33 pub fn signal(&self, val: T) { 37 pub fn signal(&self, val: T) {
34 cortex_m::interrupt::free(|_| unsafe { 38 cortex_m::interrupt::free(|_| unsafe {
35 let state = &mut *self.state.get(); 39 let state = &mut *self.state.get();
@@ -64,10 +68,12 @@ impl<T: Send> Signal<T> {
64 }) 68 })
65 } 69 }
66 70
71 /// Future that completes when this Signal has been signaled.
67 pub fn wait(&self) -> impl Future<Output = T> + '_ { 72 pub fn wait(&self) -> impl Future<Output = T> + '_ {
68 futures::future::poll_fn(move |cx| self.poll_wait(cx)) 73 futures::future::poll_fn(move |cx| self.poll_wait(cx))
69 } 74 }
70 75
76 /// non-blocking method to check whether this signal has been signaled.
71 pub fn signaled(&self) -> bool { 77 pub fn signaled(&self) -> bool {
72 cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_))) 78 cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_)))
73 } 79 }
@@ -80,6 +86,25 @@ unsafe impl cortex_m::interrupt::Nr for NrWrap {
80 } 86 }
81} 87}
82 88
89/// Creates a future that completes when the specified Interrupt is triggered.
90///
91/// The input handler is unregistered when this Future is dropped.
92///
93/// Example:
94/// ``` no_compile
95/// use embassy::traits::*;
96/// use embassy::util::InterruptFuture;
97/// use embassy::executor::task;
98/// use embassy_stm32f4::interrupt; // Adjust this to your MCU's embassy HAL.
99/// #[task]
100/// async fn demo_interrupt_future() {
101/// // Using STM32f446 interrupt names, adjust this to your application as necessary.
102/// // Wait for TIM2 to tick.
103/// let mut tim2_interrupt = interrupt::take!(TIM2);
104/// InterruptFuture::new(&mut tim2_interrupt).await;
105/// // TIM2 interrupt went off, do something...
106/// }
107/// ```
83pub struct InterruptFuture<'a, I: Interrupt> { 108pub struct InterruptFuture<'a, I: Interrupt> {
84 interrupt: &'a mut I, 109 interrupt: &'a mut I,
85} 110}