计时(Time-keeping)

在嵌入式开发中,延迟任务是最常见的操作之一。在事件循环中,如果不执行其他I/O操作,需要加入延迟以确保其他任务有机会在下一次循环迭代调用之前运行。Embassy提供了延迟当前任务指定的时间间隔的抽象。

Embassy中的Time-keeping接口由 embassy-time crate处理。这些类型可以与 embassy-executor 的内部定时器队列或自定义定时器队列实现一起使用。

定时器(Timer)

定时器 embassy::time::Timer类型提供了两种计时方法。

Timer::at创建一个在指定的时刻完成的future(相对于系统启动时间)。 Timer::after创建一个在指定的延时之后完成的future(相对于future被创建的时间)。

以下是一个延迟的例子:

use embassy::executor::{task, Executor};
use embassy::time::{Duration, Timer};

#[task]
/// 定期运行的任务
async fn tick_periodic() -> ! {
    loop {
        rprintln!("tick!");
        // 异步睡眠原语(primitive),挂起任务500ms。
        Timer::after(Duration::from_millis(500)).await;
    }
}

延迟(Delay)

embassy::time::Delay 类型提供了对 embedded-halembedded-hal-async trait的实现。这可以用于那些需要通用延迟实现的驱动。

以下是如何使用它的一个例子:

use embassy::executor::{task, Executor};

#[task]
/// 定期运行的任务
async fn tick_periodic() -> ! {
    loop {
        rprintln!("tick!");
        // 异步睡眠原语(primitive),挂起任务500ms。
        generic_delay(embassy::time::Delay).await
    }
}

async fn generic_delay<D: embedded_hal_async::delay::DelayNs>(delay: D) {
      delay.delay_ms(500).await;
}