嵌入式单片机固件开发,Rust 真的能替代 C 吗?来自ST和各大学的工业级实测报告
硬汉嵌入式
2026年05月08日 11:54
收录于文集
共11篇

论文: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 经验丰富。

二、怎么做的?——实验设计

硬件平台

实验流程

  • 第一阶段(6 周):两个团队独立并行开发同一功能——Vanilla Data Logger (VDL),一个传感器数据采集和上传的固件

  • 第二阶段(4 周):两个团队交叉对比、互相优化

两个团队的技术栈

这里有个关键区别:C 版本用了堆(heap),Rust 版本完全不用堆。

三、核心数据——内存对比

这是最硬核的部分,直接上数字:

RAM 占用对比

解读:

  • C 版本因为用了 Parson JSON 库,堆上峰值占 25,600 字节

  • Rust 版本用 heapless crate 完全不分配堆,堆 = 0 字节

  • 虽然 Rust 栈用量是 C 的 5 倍(10,240 vs 2,048),但堆的节省远大于栈的开销

  • 总 RAM Rust 少用了 45%,这在资源受限的 MCU 上意义重大

Flash/ROM 占用对比

Rust 的 ROM 大了约 10%,主要原因是:

  1. 单态化膨胀——泛型在编译期展开为多个具体类型

  2. async 状态机膨胀——每个 async 函数编译为状态机,增加了代码体积

但注意:在 STM32U585 的 2MB Flash 面前,7KB 的差距可以忽略不计。

而且有个反直觉的发现:Ariel OS 运行时本身的体积比传统 bare-metal C 栈还小约 10%。Rust 系统运行时比裸机 C 还省空间,这是怎么做到的?因为去掉了 newlib 开销 + 更高效的 HAL 抽象。

四、执行速度——打平

有趣的过程:

  • 初始阶段: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 偏大,研究团队通过以下步骤逐步收敛:

  1. 减少 heapless 类型实例化(降低单态化膨胀)

  2. 减少枚举使用

  3. 减少跨 await 点保留的状态

  4. 大缓冲区改用引用传递

  5. 不需要真正并发的地方,用同步驱动替换异步驱动

  6. 优化缓冲区大小

最终结果:Flash 需求收敛到与 C 版本差距 10% 以内。

六、可移植性——Rust 碾压

维度VDL-RUST (ARIEL OS)VDL-C (STM32CUBEMX)更换目标板改配置 + 一条编译命令重新建 CubeMX 工程,大量手动复制项目结构单一代码库 + #[cfg] 特性开关每个板子一个独立 CubeIDE 工程驱动复用crates.io 拉取逐项目手工集成跨平台测试同套 crate 可编译到嵌入式、桌面、WASM无对应能力

这一点对做产品的团队尤其重要——换颗芯片不用推倒重来。


七、安全与合规

Rust 的编译期安全保证不是新话题,但在当前环境下有两个新意义:

  1. 零堆 = 可预测的内存行为:不会碎片化、不会运行时 OOM,这在 7×24 运行的工业设备上至关重要

  2. 欧盟网络弹性法案(CRA):正在推动使用内存安全语言,Rust 天然符合趋势

论文特别指出:C 版本的 Parson JSON 库存在堆碎片化风险,虽然未做对抗性测试验证,但风险确实存在。

八、诚实地说——研究局限

论文本身也坦诚列出了未覆盖的领域,这里挑重要的说:

未测试领域说明低端 MCUCortex-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 已经可以认真考虑了;超低端项目,先等等更多数据。