论文:Embedded Rust or C Firmware? Lessons from an Industrial Microcontroller Use Case with Ariel OS
作者:Bipin Thapa, Daniele Alfonso, Lorenzo Bini, Licio Mapelli, Kaspar Schleiser, Romain Fouquet, Emmanuel Baccelli
来源:arXiv:2604.25679 | DCOSS-IoT 2026 机构:STMicroelectronics, Inria, Freie Universität Berlin
一、先说结论
Rust 在工业微控制器固件开发中已经是一个靠谱的选择。
ST和法国国立信息与自动化研究所(Inria)的研究人员,让两个团队并行开发同一个固件功能,一个用 C,一个用 Rust,跑了 10 周,在实际硬件上实测。
结果:Rust 总内存占用比 C 少了 45%,执行速度打平,而且 Rust 团队成员的 Rust 经验还不如 C 团队的 C 经验丰富。
二、怎么做的?——实验设计
硬件平台
项目 | 规格 |
|---|---|
开发板 | SensorTile.box Pro (STEVAL-MKBOXPRO) |
MCU | STM32U585AI,ARM Cortex-M33 内核 |
Flash | 2 MB |
传感器 | LSM6DSV16X 六轴 IMU |
通信接口 | I2C(传感器)+ UART(数据流上传 PC) |
实验流程
第一阶段(6 周):两个团队独立并行开发同一功能——Vanilla Data Logger (VDL),一个传感器数据采集和上传的固件
第二阶段(4 周):两个团队交叉对比、互相优化
两个团队的技术栈
| VDL-C(C 团队) | VDL-Rust(Rust 团队) |
|---|---|---|
| 工具链 | STM32CubeMX + STM32CubeIDE | Ariel OS + Embassy 异步框架 |
| 架构 | 事件驱动 FSM + 手动中断控制 | async/await 异步任务模型 |
| JSON 处理 | Parson 库(动态内存分配,堆上操作) | serde + serde-json-core(零堆反序列化) |
| 内存模型 | newlib 标准库 + 堆分配 | no_std + no_alloc,纯静态分配 |
| 数据结构 | 动态分配 | heapless crate(固定容量、静态分配) |
这里有个关键区别:C 版本用了堆(heap),Rust 版本完全不用堆。
三、核心数据——内存对比
这是最硬核的部分,直接上数字:
RAM 占用对比
指标 | VDL-C | VDL-Rust | 差值 |
|---|---|---|---|
栈(Stack) | 2,048 B | 10,240 B | +8,192 B(Rust 多) |
静态区(Static) | 14,960 B | 14,400 B | −560 B(Rust 少) |
堆(Heap) | 25,600 B | 0 B | −25,600 B(Rust 无堆) |
| 总 RAM | 44,656 B | 24,640 B | −20,016 B(Rust 少 45%) |
解读:
- C 版本因为用了 Parson JSON 库,堆上峰值占 25,600 字节
- Rust 版本用 heapless crate 完全不分配堆,堆 = 0 字节
- 虽然 Rust 栈用量是 C 的 5 倍(10,240 vs 2,048),但堆的节省远大于栈的开销
- 总 RAM Rust 少用了 45%,这在资源受限的 MCU 上意义重大
Flash/ROM 占用对比
指标 | VDL-C | VDL-Rust | 差值 |
|---|---|---|---|
.text 段 | 66,240 B | 69,764 B | +3,524 B |
| 总 ROM | 76,744 B | 84,100 B | +7,356 B(Rust 多 ~10%) |
Rust 的 ROM 大了约 10%,主要原因是:
1)单态化膨胀
——泛型在编译期展开为多个具体类型
2)async 状态机膨胀
——每个 async 函数编译为状态机,增加了代码体积
但注意:在 STM32U585 的 2MB Flash 面前,7KB 的差距可以忽略不计。
而且有个反直觉的发现:Ariel OS 运行时本身的体积比传统 bare-metal C 栈还小约 10%。Rust 系统运行时比裸机 C 还省空间,这是怎么做到的?因为去掉了 newlib 开销 + 更高效的 HAL 抽象。
四、执行速度——打平
指标 | 数值 |
|---|---|
最终输出数据率(ODR) | 7,468 Hz(两者完全一致) |
UART 流式任务耗时(调优后) | ~120 μs(两者一致) |
Rust async 任务切换延迟 | 1.7–4.0 μs |
有趣的过程:
- 初始阶段:Rust 版本反而比 C 快 2 倍
- 调优过程:双方交替领先
- 最终状态:打平
调优手段包括:调整 I2C TIMINGR 寄存器、开启 I-Cache、开启 Flash 预取、关闭 UART FIFO、移除调试日志。
论文的原话值得品味:
"Whether you select C or Rust for your next embedded project, firmware won't automagically be optimized for size and/or performance without serious work."
不管选 C 还是 Rust,固件不会自动优化好,都得认真干。
五、Rust 版本的瘦身之路
Rust 初始 ROM 偏大,研究团队通过以下步骤逐步收敛:
减少 heapless 类型实例化(降低单态化膨胀)减少枚举使用减少跨 await 点保留的状态大缓冲区改用引用传递不需要真正并发的地方,用同步驱动替换异步驱动优化缓冲区大小
最终结果:Flash 需求收敛到与 C 版本差距 10% 以内。
六、可移植性——Rust 碾压
维度 | VDL-Rust (Ariel OS) | VDL-C (STM32CubeMX) |
|---|---|---|
更换目标板 | 改配置 + 一条编译命令 | 重新建 CubeMX 工程,大量手动复制 |
项目结构 | 单一代码库 + | 每个板子一个独立 CubeIDE 工程 |
驱动复用 | crates.io 拉取 | 逐项目手工集成 |
跨平台测试 | 同套 crate 可编译到嵌入式、桌面、WASM | 无对应能力 |
这一点对做产品的团队尤其重要——换颗芯片不用推倒重来。
七、安全与合规
Rust 的编译期安全保证不是新话题,但在当前环境下有两个新意义:
1)零堆 = 可预测的内存行为:不会碎片化、不会运行时 OOM,这在 7×24 运行的工业设备上至关重要
2)欧盟网络弹性法案(CRA):正在推动使用内存安全语言,Rust 天然符合趋势
论文特别指出:C 版本的 Parson JSON 库存在堆碎片化风险,虽然未做对抗性测试验证,但风险确实存在。
八、诚实地说——研究局限
论文本身也坦诚列出了未覆盖的领域,这里挑重要的说:
未测试领域 | 说明 |
|---|---|
低端 MCU | Cortex-M0/M0+(32-64KB Flash, 8-16KB RAM),Rust 能否塞进去未知 |
非 ARM 平台 | RISC-V 实测缺失 |
网络协议栈 | BLE、Wi-Fi、LoRaWAN 等对 RAM/ROM/功耗的影响未测 |
功耗 | 完全没有功耗数据 |
长期稳定性 | 没有做 24-72 小时耐久测试 |
RTOS 对比 | 没有对比 FreeRTOS、Zephyr |
实时抖动 | 只测了平均周期,最坏情况 ISR 延迟和抖动分布未报 |
JSON 公平性 | C 用了堆分配的 Parson,如果换 jsmn/frozen 等零堆方案,RAM 差距可能缩小 |
九、Ariel OS 是什么?
简单介绍下这个 Rust 运行时:
- 定位:轻量级 Rust 库操作系统,面向 IoT 微控制器
- 架构支持:ARM Cortex-M、RISC-V、ESP32 Xtensa
- 调度:支持单核和多核抢占式调度(这是 Rust 嵌入式 OS 首创)
- 异步:基于 Embassy 异步框架
- 构建方式:基于 Embassy HAL 和 OS 抽象
- 代码开源:GitHub 上可获取
这篇论文的价值在于——这是工业界的真实数据,不是学术 benchmark。
三个核心 takeaway:
1)RAM 省 45% 是真金白银。在 MCU 上,RAM 比 Flash 金贵得多。Rust 的零堆模型在这里优势明显。
2)ROM 大 10% 不是大问题。现代 MCU Flash 越来越大,7KB 的差距在 2MB 面前微不足道。但如果你的项目跑到 32KB Flash 的 M0 上,这个差距就需要掂量了——论文也没敢下这个结论。
3)可移植性优势被低估了。做产品的都知道,换芯片是刚需。Rust 的 crate 生态 + cfg 特性开关,比 CubeMX 一把梭 + 手工移植香太多了。
但也要保持清醒:
- C 版本如果换成零堆 JSON 方案(jsmn/frozen),RAM 差距会缩小
- 低端 M0/M0+ 上 Rust 能否胜任,目前还是问号
- 网络协议栈(BLE/Wi-Fi)的内存开销完全没测,而这恰恰是很多 IoT 项目的大头
总而言之:中高端 Cortex-M 项目,Rust 已经可以认真考虑了;超低端项目,先等等更多数据。
来源:安富莱电子
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。