Embassy 是一个专为嵌入式设备设计的异步编程框架,基于 Rust 语言的 async/await 特性。它通过提供硬件抽象层(HAL)和任务执行器,简化了嵌入式异步编程的复杂性。在本文中,我们将介绍如何使用 Embassy 创建一个简单的异步主循环。
环境准备
在开始编写代码之前,确保你已经安装并配置了 Rust 的 nightly 版本,因为本文中的示例代码依赖一些 nightly 特性。另外,你需要配置 Embassy 框架,并确保项目中包含以下依赖项:
[dependencies]
embassy = "0.8"
embassy-executor = "0.8"
embassy-time = "0.8"
log = "0.4"
env_logger = "0.9"
主循环示例解析
让我们从一个简单的异步主循环示例开始,代码如下:
#![feature(type_alias_impl_trait)]
use embassy_executor::Spawner;
use embassy_time::Timer;
use log::*;
#[embassy_executor::task]
async fn run() {
loop {
info!("tick");
Timer::after_secs(1).await;
}
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
env_logger::builder()
.filter_level(log::LevelFilter::Debug)
.format_timestamp_nanos()
.init();
spawner.spawn(run()).unwrap();
}
1. 特性标记和依赖导入
在文件的开头,我们启用了 Rust 的 nightly 特性 type_alias_impl_trait
,该特性允许在 type alias 中使用 impl Trait。
接着,我们导入了 Embassy 的执行器(executor)、时间(time)模块,以及日志库 log
和 env_logger
。这些库将帮助我们管理任务执行、计时和日志记录。
2. 异步任务定义
#[embassy_executor::task]
async fn run() {
loop {
info!("tick");
Timer::after_secs(1).await;
}
}
这里定义了一个名为 run
的异步任务,该任务通过 #[embassy_executor::task]
宏标记。这个宏告诉 Embassy 将该函数作为任务运行。任务的核心是一个无限循环,循环内每秒钟记录一次 tick
消息。Timer::after_secs(1).await;
用于在每次循环之间等待 1 秒钟,这是通过 Embassy 的异步时间模块实现的。
3. 主函数
#[embassy_executor::main]
async fn main(spawner: Spawner) {
env_logger::builder()
.filter_level(log::LevelFilter::Debug)
.format_timestamp_nanos()
.init();
spawner.spawn(run()).unwrap();
}
main
函数是整个应用程序的入口点。它被 #[embassy_executor::main]
宏标记,表示这是一个异步主函数,并由 Embassy 的执行器运行。
在 main
函数中,我们首先配置并初始化了日志记录器 env_logger
,设置日志级别为 Debug
,并使用纳秒级时间戳记录日志。然后,我们使用 spawner.spawn(run()).unwrap();
启动了之前定义的 run
任务。spawner
是 Embassy 提供的一个任务生成器,用于启动新的异步任务。
运行示例
要运行此示例,请确保你使用了 Embassy 支持的目标板或模拟器。例如,如果你使用的是某个支持的嵌入式平台,请确保正确配置了 target。如果你在主机上运行,可以直接通过 cargo run
执行。
在运行时,终端会每秒打印一行 tick
,表示主循环每秒钟完成一次迭代。
深入理解
这个简单的例子展示了如何在嵌入式系统中使用 Embassy 实现异步任务。虽然示例代码很简短,但它展示了异步编程的核心概念:
- 任务:通过
async fn
定义的异步函数,可以被 Embassy 的执行器调度执行。 - 任务生成:
Spawner
是一个任务生成器,负责启动和管理异步任务。 - 时间管理:通过
Timer
模块,开发者可以方便地实现定时任务,这对于实时系统非常重要。 - 日志记录:在嵌入式开发中,日志记录是调试和监控系统行为的重要手段。
扩展应用
虽然此示例只是一个简单的主循环,但你可以将其扩展为更复杂的异步系统。你可以同时运行多个任务、处理异步 I/O 操作,甚至创建复杂的状态机来管理设备的行为。Embassy 提供了强大的工具,帮助你构建高效、低功耗的嵌入式应用程序。
总结
本文介绍了如何使用 Embassy 在嵌入式系统中创建一个简单的异步主循环。通过这个例子,我们了解了异步任务的基本概念、任务生成器的使用以及如何管理时间和日志记录。Embassy 的设计简化了异步编程的复杂性,使开发者能够专注于构建高效的嵌入式系统。
如果你对异步编程感兴趣,建议继续探索 Embassy 提供的更多功能,并尝试将其应用到你的项目中。Embassy 是一个非常灵活且强大的工具,特别适合资源受限的嵌入式环境。
这篇博客详细解析了 Embassy 的异步主循环示例,并探讨了其背后的原理和应用场景。希望这对你理解和应用 Embassy 有所帮助!