在前面幾篇文章中,我們已經(jīng)知道如何點亮一個 LED 燈,那么在這一篇,我們即將提升難度,在不同的任務(wù)中點燈,感受并行編程的快樂。
請在你感到好奇或疑惑的地方修改代碼!
examples/embassy_blinky.rs
//! 在不同的任務(wù)中閃爍不同的 LED, 學(xué)習(xí)多任務(wù)操作
//!
#![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
表示異步任務(wù)async fn run_led(led: AnyPin, delay_ms: u64)
最多能被 2 個任務(wù)使用async
表示函數(shù)為異步函數(shù)embassy_executor::task
表示將定義一個異步任務(wù)Spawner
是異步執(zhí)行器框架提供的一個類型,它的主要職責(zé)是在執(zhí)行器的任務(wù)調(diào)度環(huán)境中創(chuàng)建新的異步任務(wù)。它封裝了任務(wù)創(chuàng)建的具體細(xì)節(jié)和邏輯,例如確定任務(wù)應(yīng)該在哪個任務(wù)池中運行、分配任務(wù)所需的資源(如棧空間等)以及將任務(wù)注冊到執(zhí)行器的任務(wù)隊列中以便后續(xù)調(diào)度執(zhí)行。- embassy 的 異步入口函數(shù)定義為:
#[embassy_executor::main]
async fn main(spawner: Spawner) {
}
spawner.spawn()
:spawn
方法是將一個異步函數(shù)(或異步閉包)包裝成一個任務(wù),并將其放入異步執(zhí)行器的任務(wù)調(diào)度隊列中,以便在合適的時候執(zhí)行。這個方法是異步執(zhí)行器框架提供的關(guān)鍵接口,用于啟動新的異步任務(wù)并將其納入任務(wù)管理體系。let _ = led.toggle();
用于避免編譯器報警,忽視led.toggle()
的返回結(jié)果- 在例程中實際會有 3 個任務(wù)運行