#嵌入式设备 #运行时 #future #async #单线程 #栈分配 #小巧

embedded-runtime

为嵌入式设备提供的微型异步运行时

3 个版本 (重大更新)

0.3.0 2024 年 5 月 24 日
0.2.0 2023 年 7 月 21 日
0.1.2 2023 年 7 月 15 日

#307异步


2 crates 中使用

BSD-2-Clause OR MIT

17KB
167

License BSD-2-Clause License MIT AppVeyor CI docs.rs crates.io Download numbers dependency status

嵌入式运行时

此 crate 提供了一个微型异步运行时,针对嵌入式设备。因此,它提供了一个单线程的执行器以及用于 futures 的栈分配 box。

运行时设置

此 crate 与硬件无关,需要在目标硬件上进行一些依赖注入以执行信号/等待操作。

要提供这些依赖,您需要定义以下两个 extern "Rust" 函数

  • _runtime_waitforevent_TBFzxdKN: 阻塞直到发生事件(可能突然唤醒)。重要:事件不得丢失。如果自上次调用以来发生了一个事件,则此函数不得阻塞。
  • _runtime_sendevent_3YSaPmB7: 触发事件。重要:事件不得丢失。如果发送了事件,但接收者当前没有等待,则必须保留该事件,直到接收者再次尝试等待。

有关如何注入实现的示例,请参阅 embedded-runtime-rp2040,它基本上是这个 crate,为 rp2040 板提供了基于 wfe/sev 的运行时函数。

示例

# use core::{
#     future::Future,
#     pin::Pin,
#     task::{Poll, Context}
# };
#
# /// Blocks until an event occurs (may wake spuriously)
# #[no_mangle]
# #[allow(non_snake_case)]
# pub fn _runtime_waitforevent_TBFzxdKN() {
#     // No-op
# }
# 
# /// Raises an event
# #[no_mangle]
# #[allow(non_snake_case)]
# pub fn _runtime_sendevent_3YSaPmB7() {
#     // No-op
# }
use embedded_runtime::run;

/// A countdown future that resolves to pending until the poll-countdown becomes zero
struct CountdownFuture {
    /// The current countdown value
    countdown: usize
}
impl CountdownFuture {
    /// Creates a new countdown future
    pub const fn new(countdown: usize) -> Self {
        Self { countdown }
    }
}
impl Future for CountdownFuture {
    type Output = ();

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        // Decrement the value if we are still pending
        if self.countdown > 0 {
            // Print the countdown
            println!("{}!", self.countdown);

            // Decrement the future, wake the executor and return pending
            *self = Self::new(self.countdown - 1);
            cx.waker().wake_by_ref();
            return Poll::Pending;
        }

        // Return ready
        println!("Liftoff 🚀");
        Poll::Ready(())
    }
}

// This creates a new runtime and executes the given futures in an async context
run!(async {
    CountdownFuture::new(3).await;
    CountdownFuture::new(7).await;
}).expect("failed to perform countdowns");

无运行时依赖