Rust is gaining attention in the programming community, with projects like the Linux kernel adopting it. However, its suitability for embedded firmware on microcontrollers has been questioned due to limited hardware resources. Optimal memory usage and performance are crucial to reduce power consumption in battery-powered devices. A research paper by STMicroelectronics, Inria, and the Freie Universität Berlin, titled “Lessons from an Industrial Microcontroller Use Case with Ariel OS,” explores this question by comparing embedded C and Rust, concluding Rust is viable:
As Rust becomes popular for developing safer systems software, evaluating its readiness for microcontroller hardware segment is essential. Can Rust effectively compete with C? This paper presents an IoT industrial case study of two teams developing the same functionality in C and Rust. Their approaches, results, and iterative efforts are compared over several months. Hardware analysis shows no strong reason to favor C over Rust in terms of memory footprint or execution speed.
Additionally, Ariel OS demonstrates an efficient, portable system runtime in Rust with a smaller footprint than the traditional bare-metal C stack. Rust proves to be a sound choice for firmware development in this field.
It’s advisable to check the research paper for a deeper understanding of the methods and results.
The SensorTile.box Pro devkit was used in the study, featuring an STMicro STM32U585AI Cortex-M33 microcontroller with BLE and NFC connectivity (not utilized here), a 6-axis LSM6DSV16X IMU3, and the ST AIoT Craft Edge AI Suite for AI processing of sensor data.
The Vanilla Data Logger (VDL) firmware runs on the devkit, written in either C or Rust, and communicates with a PC via the Vanilla Datalog Protocol (VDP) through UART interface.
Both teams worked independently for six weeks on Phase 1 of implementing the VDL firmware in C and Rust, then collaborated for four weeks to optimize each other’s work. The C firmware employs STM32CubeMX, a Finite State Machine (FSM) in bare-metal C, and the open-source Parson library for JSON de/serialization, which uses dynamic memory allocation.
The Rust firmware utilizes Ariel OS, a Rust RTOS for microcontrollers, implementing JSON serialization/deserialization with the serde crate, providing a serialization framework, and the heapless crate for static memory allocation.
Though the architectures differ significantly, here’s a comparison of memory and storage footprints.
| Metric (bytes) | VDL-C | VDL-Rust | Δ (Rust − C) |
|—————-|——–|———-|————–|
| .text | 66,240 | 69,764 | 3,524 |
| Total ROM | 76,744 | 84,100 | 7,356 |
| Stack RAM | 2,048 | 10,240 | 8,192 |
| Static RAM | 14,960 | 14,400 | -560 |
| Heap RAM | 25,600 | 0 | -25,600 |
| Total RAM | 44,656 | 24,640 | -20,016 |
Both firmware binaries are small, yet the C firmware is smaller than the Rust variant. This difference is negligible for the STM32U585AI with 2MB flash, but may matter with more constrained MCUs, necessitating further optimization or a different part. The RAM comparison is more complex due to dynamic memory allocation requiring heap RAM for C implementation. They note there are options not requiring a heap compared to Parson library, as memory optimization wasn’t a primary goal.
Both Rust and C firmware reached identical performance levels, measured at 7,468 Hz Output Data Rate (ODR). Whether using C or Rust, serious optimization efforts are necessary for size and performance improvements.
The Rust implementation was twice as fast as C during the initial test. Both alternated in taking the lead following optimizations, such as disabling logging and enabling I-Cache and flash prefetch to reduce I2C latency. The full PDF details caveats and pitfalls.
Interestingly, in the second phase, the teams improved each other’s firmware by comparing C and Rust versions. Ideally, choosing both C and Rust benefits product development, but budget constraints may pose challenges. The source code will eventually be available on STM32 Hotspot.
Via Adafruit.
