背景
對于嵌入式工程師而言,也許對異步編程比較陌生,通常在大型復雜的的嵌入式應用中,采用 FreeRTOS 或 Rtthread 嵌入式操作系統編程,采用 C/C++ 編寫驅動或應用邏輯。本文則介紹在 Rust 嵌入式中非常流行的 Embassy
異步操作系統。Embassy
是采用 Rust 語言編寫的異步操作系統,目前有很多芯片已經支持 embassy
異步操作系統,如 NRF、STM32、ESP32、WCH 等,本文將基于 STM32F446ZET6 單片機測試 Embassy 和 FreeRTOS 下的響應性能和資源占用大小。
兩者都在180MHz 的主頻下運行。測試采用簡單的按鍵響應與 LED 翻轉的程序,通過示波器記錄按鍵電平翻轉與 LED 電平響應的間隔。
Embassy
Embassy
的機制與 FreeRTOS
等 C 語言寫的嵌入式操作系統不一樣,它通過輪詢機制,各任務都是靜態分配,所有任務在編譯時已經確認所需的資源,任務間的切換無需進行線程堆棧上下文的切換,提高了CPU 的有效使用率。Rust 測試任務如下:
#[embassy::task]
async fn blink_led(mut led: Output<'static, PB0>, button_high: &'static AtomicBool) {
loop {
Timer::after(Duration::from_millis(100)).await;
if !button_high.load(Ordering::SeqCst) {
led.set_high().unwrap();
}
Timer::after(Duration::from_millis(100)).await;
led.set_low().unwrap();
}
}
FreeRTOS
在 FreeRTOS 中,通過中斷檢測按鍵的變化,將按下和釋放事件發送給原子變量,主任務代碼如下。
void StartBlinkLedTask(void *argument)
{
for (;;) {
osDelay(100);
if (atomic_load(&buttonPressed) == GPIO_PIN_RESET) {
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET);
}
osDelay(100);
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
}
}
測試結果
結論
通過以上的簡單對比,在實驗中可以知道 Embassy 與 FreeRTOS 的中斷響應速度差異不大, 但FreeRTOS 響應更快。同時在 Ram 和 Flash 占用中 Embassy 反而更小。當然這個數據結果與代碼的編譯選項、庫的驅動邏輯有較大關系,因此本結論僅供參考。