Merge pull request #108 from theunkn0wn1/doc/util
Document embassy::util
This commit is contained in:
		| @@ -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: (), | ||||
| } | ||||
| @@ -10,6 +16,7 @@ impl DropBomb { | ||||
|         Self { _private: () } | ||||
|     } | ||||
|  | ||||
|     /// Diffuses the bomb, rendering it safe to drop. | ||||
|     pub fn defuse(self) { | ||||
|         mem::forget(self) | ||||
|     } | ||||
|   | ||||
| @@ -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<u32> =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<T> { | ||||
|     used: AtomicBool, | ||||
|     t: UnsafeCell<MaybeUninit<T>>, | ||||
| @@ -19,6 +38,11 @@ impl<T> Forever<T> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// 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 | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| //! Async utilities | ||||
| mod drop_bomb; | ||||
| mod forever; | ||||
| mod mutex; | ||||
|   | ||||
| @@ -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<T> { | ||||
|     state: UnsafeCell<State<T>>, | ||||
| } | ||||
| @@ -30,6 +33,7 @@ impl<T: Send> Signal<T> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Mark this Signal as completed. | ||||
|     pub fn signal(&self, val: T) { | ||||
|         cortex_m::interrupt::free(|_| unsafe { | ||||
|             let state = &mut *self.state.get(); | ||||
| @@ -64,10 +68,12 @@ impl<T: Send> Signal<T> { | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /// Future that completes when this Signal has been signaled. | ||||
|     pub fn wait(&self) -> impl Future<Output = T> + '_ { | ||||
|         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(_))) | ||||
|     } | ||||
| @@ -80,6 +86,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, | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user