From da59112e86d43efc070ae09197930023552638ca Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Wed, 24 Mar 2021 12:36:02 -0700 Subject: [PATCH 1/6] Document the DropBomb --- embassy/src/util/drop_bomb.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/embassy/src/util/drop_bomb.rs b/embassy/src/util/drop_bomb.rs index b2b0684e5..7f0cc5d9c 100644 --- a/embassy/src/util/drop_bomb.rs +++ b/embassy/src/util/drop_bomb.rs @@ -1,6 +1,12 @@ use crate::fmt::panic; use core::mem; +/// An explosive ordinance that panics if it is improperly disposed of. +/// +/// This is to forbid dropping futures, when there is absolutely no other choice. +/// +/// To correctly dispose of this device, call the [defuse](struct.DropBomb.html#method.defuse) +/// method before this object is dropped. pub struct DropBomb { _private: (), } @@ -9,7 +15,7 @@ impl DropBomb { pub fn new() -> Self { Self { _private: () } } - + // Diffuses the bomb, rendering it safe to drop. pub fn defuse(self) { mem::forget(self) } From a9e099c2151221f66571ab0001b77fe639c149ee Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Wed, 24 Mar 2021 12:36:17 -0700 Subject: [PATCH 2/6] Document embassy::util::Forever --- embassy/src/util/forever.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) 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; use atomic_polyfill::{AtomicBool, Ordering}; +/// Type with static lifetime that may be written to once at runtime. +/// +/// This may be used to initialize static objects at runtime, typically in the init routine. +/// This is useful for objects such as Embassy's RTC, which cannot be initialized in a const +/// context. +/// +/// Note: IF a global mutable variable is desired, use a CriticalSectionMutex or ThreadModeMutex instead. +/// +/// ``` +/// use embassy::util::Forever; +/// // Using an integer for the sake of keeping this example self-contained, +/// // see https://github.com/embassy-rs/embassy/wiki/Getting-Started for a more "proper" example. +/// static SOME_INT: Forever =Forever::new(); +/// +/// // put returns a mutable pointer to the object stored in the forever, which may then be passed +/// // around. +/// let mut x = SOME_INT.put(42); +/// assert_eq!(*x, 42); +/// ``` pub struct Forever { used: AtomicBool, t: UnsafeCell>, @@ -19,6 +38,11 @@ impl Forever { } } + /// Gives this `Forever` a value. + /// + /// Panics if this `Forever` already has a value. + /// + /// Returns a mutable reference to the stored value. pub fn put(&'static self, val: T) -> &'static mut T { if self .used From 62009150bd3655f36c3f6247d5d339258212cb2f Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Wed, 24 Mar 2021 12:36:29 -0700 Subject: [PATCH 3/6] Document embassy::util::InterruptFuture --- embassy/src/util/signal.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs index 41e27d4ca..e3c5fad1d 100644 --- a/embassy/src/util/signal.rs +++ b/embassy/src/util/signal.rs @@ -80,6 +80,25 @@ unsafe impl cortex_m::interrupt::Nr for NrWrap { } } +/// Creates a future that completes when the specified Interrupt is triggered. +/// +/// The input handler is unregistered when this Future is dropped. +/// +/// Example: +/// ``` no_compile +/// use embassy::traits::*; +/// use embassy::util::InterruptFuture; +/// use embassy::executor::task; +/// use embassy_stm32f4::interrupt; // Adjust this to your MCU's embassy HAL. +/// #[task] +/// async fn demo_interrupt_future() { +/// // Using STM32f446 interrupt names, adjust this to your application as necessary. +/// // Wait for TIM2 to tick. +/// let mut tim2_interrupt = interrupt::take!(TIM2); +/// InterruptFuture::new(&mut tim2_interrupt).await; +/// // TIM2 interrupt went off, do something... +/// } +/// ``` pub struct InterruptFuture<'a, I: Interrupt> { interrupt: &'a mut I, } From 40617fea043538833e40bec1694c17be6faf5077 Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Wed, 24 Mar 2021 13:19:05 -0700 Subject: [PATCH 4/6] Document embassy::util::signal & embassy::util --- embassy/src/util/mod.rs | 1 + embassy/src/util/signal.rs | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) 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 @@ +//! Async utilities mod drop_bomb; mod forever; mod mutex; diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs index e3c5fad1d..12dc7c318 100644 --- a/embassy/src/util/signal.rs +++ b/embassy/src/util/signal.rs @@ -10,6 +10,9 @@ use crate::executor; use crate::fmt::panic; use crate::interrupt::{Interrupt, InterruptExt}; +/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks. +/// +/// For more advanced use cases, please consider [futures-intrusive](https://crates.io/crates/futures-intrusive) channels or mutexes. pub struct Signal { state: UnsafeCell>, } @@ -29,7 +32,7 @@ impl Signal { state: UnsafeCell::new(State::None), } } - + /// Mark this Signal as completed. pub fn signal(&self, val: T) { cortex_m::interrupt::free(|_| unsafe { let state = &mut *self.state.get(); @@ -64,10 +67,12 @@ impl Signal { }) } + /// Future that completes when this Signal has been signaled. pub fn wait(&self) -> impl Future + '_ { futures::future::poll_fn(move |cx| self.poll_wait(cx)) } + /// non-blocking method to check whether this signal has been signaled. pub fn signaled(&self) -> bool { cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_))) } From 18d3c803deaf004114ec5f5bfd8de66bd241d2f4 Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Wed, 24 Mar 2021 13:21:32 -0700 Subject: [PATCH 5/6] Add missing newlines --- embassy/src/util/drop_bomb.rs | 1 + embassy/src/util/signal.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/embassy/src/util/drop_bomb.rs b/embassy/src/util/drop_bomb.rs index 7f0cc5d9c..6638a09cc 100644 --- a/embassy/src/util/drop_bomb.rs +++ b/embassy/src/util/drop_bomb.rs @@ -15,6 +15,7 @@ impl DropBomb { pub fn new() -> Self { Self { _private: () } } + // Diffuses the bomb, rendering it safe to drop. pub fn defuse(self) { mem::forget(self) diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs index 12dc7c318..0fd5c9275 100644 --- a/embassy/src/util/signal.rs +++ b/embassy/src/util/signal.rs @@ -32,6 +32,7 @@ impl Signal { state: UnsafeCell::new(State::None), } } + /// Mark this Signal as completed. pub fn signal(&self, val: T) { cortex_m::interrupt::free(|_| unsafe { From ea650b684c54fa5e1639e80e5f6300d640b3c9d3 Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Wed, 24 Mar 2021 13:31:08 -0700 Subject: [PATCH 6/6] its `///` not `//`. --- embassy/src/util/drop_bomb.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy/src/util/drop_bomb.rs b/embassy/src/util/drop_bomb.rs index 6638a09cc..388209a23 100644 --- a/embassy/src/util/drop_bomb.rs +++ b/embassy/src/util/drop_bomb.rs @@ -16,7 +16,7 @@ impl DropBomb { Self { _private: () } } - // Diffuses the bomb, rendering it safe to drop. + /// Diffuses the bomb, rendering it safe to drop. pub fn defuse(self) { mem::forget(self) }