背景
对于嵌入式工程师而言,也许对异步编程比较陌生,通常在大型复杂的的嵌入式应用中,采用 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);
}
}
测试结果
| 项目 | FreeRTOS | Embassy | 差异 | 比率 |
|---|---|---|---|---|
| 响应时间 | 1.5us | 1.8us | +0.3us | 120% |
| 程序大小 | 19378B | 12344B | -7044B | 63% |
| 静态 RAM 大小 | 1488b | 874B | -614B | 58% |
结论
通过以上的简单对比,在实验中可以知道 Embassy 与 FreeRTOS 的中断响应速度差异不大, 但FreeRTOS 响应更快。同时在 Ram 和 Flash 占用中 Embassy 反而更小。当然这个数据结果与代码的编译选项、库的驱动逻辑有较大关系,因此本结论仅供参考。