在前面幾篇文章中,我們已經知道如何點亮一個 LED 燈,那么在這一篇,我們即將提升難度,在不同的任務中點燈,感受并行編程的快樂。
請在你感到好奇或疑惑的地方修改代碼!
examples/embassy_blinky.rs
//! 在不同的任務中閃爍不同的 LED, 學習多任務操作
//!
#![no_std]
#![no_main]
use embassy_executor::Spawner;
use embassy_time::Timer;
use embedded_hal::digital::v2::ToggleableOutputPin;
use hal::gpio::{Output, PinIoType, PinSpeed};
use py32f030_hal::{
selfas hal,
gpio::{AnyPin, Pin},
};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::task(pool_size = 2)]
asyncfn run_led(led: AnyPin, delay_ms: u64) {
letmut led = Output::new(led, PinIoType::PullDown, PinSpeed::Low);
loop {
let _ = led.toggle();
Timer::after_millis(delay_ms).await;
}
}
#[embassy_executor::main]
asyncfn main(spawner: Spawner) {
let p = hal::init(Default::default());
defmt::info!("Testing the flashing of different LEDs in multi-tasking.");
let gpioa = p.GPIOA.split();
// spawner.must_spawn(run_led(gpioa.PA9.degrade(), 1000));
// spawner.must_spawn(run_led(gpioa.PA10.degrade(), 2000));
spawner.spawn(run_led_1(gpioa.PA9.degrade(), 1000)).unwrap();
spawner.spawn(run_led_1(gpioa.PA10.degrade(), 500)).unwrap();
loop {
Timer::after_secs(2).await;
}
}
也許你有疑惑的地方
pool_size = 2
表示異步任務async fn run_led(led: AnyPin, delay_ms: u64)
最多能被 2 個任務使用async
表示函數為異步函數embassy_executor::task
表示將定義一個異步任務Spawner
是異步執行器框架提供的一個類型,它的主要職責是在執行器的任務調度環境中創建新的異步任務。它封裝了任務創建的具體細節和邏輯,例如確定任務應該在哪個任務池中運行、分配任務所需的資源(如棧空間等)以及將任務注冊到執行器的任務隊列中以便后續調度執行。- embassy 的 異步入口函數定義為:
#[embassy_executor::main]
async fn main(spawner: Spawner) {
}
spawner.spawn()
:spawn
方法是將一個異步函數(或異步閉包)包裝成一個任務,并將其放入異步執行器的任務調度隊列中,以便在合適的時候執行。這個方法是異步執行器框架提供的關鍵接口,用于啟動新的異步任務并將其納入任務管理體系。let _ = led.toggle();
用于避免編譯器報警,忽視led.toggle()
的返回結果- 在例程中實際會有 3 個任務運行