1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#![cfg_attr(not(feature = "mock"), no_std)]
//! Async hardware abstraction layer for embedded devices
use core::task::{Context, Poll, Waker};
use futures::{
task::{noop_waker, AtomicWaker},
Future, FutureExt,
};
/// CAN bus
pub mod can;
/// Task executor
pub mod executor;
pub use executor::Executor;
/// Interrupt stream
mod interrupt;
pub use interrupt::Interrupt;
/// Asynchronous IO
pub mod io;
/// Serial port
pub mod serial;
/// Timers
pub mod delay;
pub use delay::DelayMs;
pub trait Scheduler {
fn schedule(&self, waker: &Waker);
}
impl Scheduler for AtomicWaker {
fn schedule(&self, waker: &Waker) {
self.register(waker)
}
}
impl<T: Scheduler> Scheduler for &'_ T {
fn schedule(&self, waker: &Waker) {
(*self).schedule(waker)
}
}
/// Run `future` to completion and return its output.
/// This will repeatedly poll the future and call `wait()`.
///
/// This is useful for microcontrollers that can be set into a low-power mode while waiting,
/// such as using Cortex-M's `wfi` instruction.
/// ```
/// use futures::pin_mut;
///
/// let task = async { true };
/// pin_mut!(task);
///
/// let output = async_hal::block_on(task, || {
/// dbg!("Waiting!");
/// });
/// assert!(output);
/// ```
pub fn block_on<F, W>(mut future: F, mut wait: W) -> F::Output
where
F: Future + Unpin,
W: FnMut(),
{
let waker = noop_waker();
loop {
let mut cx = Context::from_waker(&waker);
if let Poll::Ready(output) = future.poll_unpin(&mut cx) {
return output;
}
wait()
}
}