Embassy文档-基本应用
基本应用示例
我们已经正常运行了一个示例程序。接下来,我们通过一个运行在nRF52套件环境下的Embassy程序来更深入地了解它。
详细内容
本章的代码都在这里
Rust Nightly
首先,需要Rust工具链的Nightly版本。Embassy的一些状态定义用到了nightly中的某些特性,比如:
错误处理
接下来是关于错误和恐慌(panic)的处理,在开发过程中,比较好的做法是依靠defmt_rtt和panic_probe将诊断信息输出到终端:
use ; // global logger
任务定义
通过添加属性宏的方式,任务定义如下:
async
Embassy中,任务必须被定义为异步的,不能带有泛型参数。在本例中,我们传入了两个参数:要操作的LED设备和闪烁的间隔时间。
注意
Embassy并没有采用空转等待的方式,而是采用内部的计时器来实现出让执行(yield),在闪烁周期内允许微处理器进入睡眠状态。(译者注:busy waiting going no,这里结合下文按意思来译的)
main函数
Embassy应用的入口函数用[embassy_executor::main]宏来定义,要求传入两个参数:Spawner、Peripherals。Spawner用于应用创建任务,Peripherals来自HAL,它负责沟通可能用到的外设。本例中我们配置其中一根引脚,把它当作GPIO输出来驱动LED。
async
在blinker任务已经生成、main函数返回时,究竟发生了什么?主入口看起来跟其他任务没什么不同,除了它只能存在一个并且需要一些特殊类型的参数。主要的魔法来自[embassy_executor::main]宏,它做了以下的事情:
- 创建了一个Embassy执行器。
- 初始化了硬件层并通过Peripherals参数提供交互。
- 为程序入口定义了主任务。
- 运行执行器生成了主任务。
不使用宏也可以运行执行器。这种情况下,需要您手动实现执行器实例。
Cargo.toml
项目定义需要引入embassy相关的依赖:
= { = "0.1.0", = "../../../../../embassy-executor", = ["defmt", "nightly", "integrated-timers"] }
= { = "0.1.0", = "../../../../../embassy-time", = ["defmt", "nightly"] }
= { = "0.1.0", = "../../../../../embassy-nrf", = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] }
根据您的微处理器型号,选择相应的crate替换embassy-nrf,比如STM32用embassy-stm32,记得设置合适的features标记。
在上面的示例中,使用了nrf52840芯片,选择了RTC1作为时间驱动器。