There’s a lot of hype around the Rust programming language, and I’m seeing it being adopted by various projects, not least the Linux kernel. However, so far it was unclear to me whether it was suitable for embedded firmware development since the hardware resources are limited on microcontrollers. A low memory and storage footprint is required, and optimal performance may also be important, for example, to lower the power consumption of battery-powered devices.
A research paper by STMicroelectronics, Inria, and the Freie Universität Berlin, entitled “Lessons from an Industrial Microcontroller Use Case with Ariel OS” published on ArXiv hosted by Cornell University, attempts to answer this question using embedded C and Rust, and the conclusion is that Rust is a viable option:
As Rust gains traction for developing safer systems software, a reality check for the microcontroller hardware segment becomes necessary. How ready is the Rust ecosystem for this segment? Can Rust compete with C in practice?
This paper reports on an IoT industrial case study that contributes to answering these questions. Two teams concurrently developing the same functionality (one in C, one in Rust) are analyzed over a period of several months. A comparative analysis of their approaches, results, and iterative efforts is provided. The analysis and measurements on hardware indicate no strong reason to prefer C over Rust for microcontroller firmware on the basis of memory footprint or execution speed.
Furthermore, Ariel OS is shown to provide an efficient and portable system runtime in Rust whose footprint is smaller than that of the state-of-the-art bare-metal C stack traditionally used in this context. It is concluded that Rust is a sound choice today for firmware development in this domain.
But let’s not take the conclusion for granted, and check out the research (PDF) to understand the method and results better.
The hardware used was the SensorTile.box Pro devkit with an STMicro STM32U585AI Arm Cortex-M33 microcontroller, BLE and NFC connectivity (not used here), and a 6-axis LSM6DSV16X IMU3, and the ST AIoT Craft Edge AI Suite enabled AI processing of the captured sensor data.
The devkit runs the Vanilla Data Logger (VDL) firmware written in C or Rust and communicates with a PC running a GUI over the Vanilla Datalog Protocol (VDP) through a UART interface.

Each team worked independently for six weeks during Phase 1 of the implementation of the VDL firmware in C and Rust, and then collaborated for four more weeks to optimize each other’s work. The C implementation relies on STM32CubeMX, a Finite State Machine (FSM) written in bare-metal C, and the open-source Parson library for JSON de/serialization (note: uses dynamic memory allocation).

The Rust firmware relies on Ariel OS Rust RTOS for microcontrollers, and implements JSON serialization/deserialization using the serde crate, offering a serialization/deserialization framework, and the heapless crate for static memory allocation.

Since the architectures are fairly different, it’s not going to be a direct C vs Rust comparison, but here are the final results when it comes to 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 VDL firmware binaries are quite small, but the C firmware is still smaller than the Rust firmware. It does not matter much here since the STM32U585AI comes with 2MB flash, but it may matter if we get close to the storage limit on even more resource-constrained MCUs, and either more optimization is required or switching to a different part may be needed. The RAM comparison is more complex due to dynamic memory allocation, which requires heap RAM for the C implementation. The number shown is the max measured peak of heap. They also note that “there are less memory heavy options that do not require a heap at all” compared to the Parson library, since memory optimization was not the main goal.

Both Rust and C firmware ended up running at the same level of performance as measured by the Output Data Rate (ODR): 7,468 Hz. The chart below shows that 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.

The Rust implementation was twice as fast as the C implementation during the first test, and C and Rust traded the top spot in turns following optimizations, which included trivial changes such as disabling logging (for debugging) and enabling I-Cache and flash prefetch to lower I2C latency. You’ll learn more about caveats and pitfalls in the full PDF.
What I found interesting is that in the second phase, each team helped the other build a better firmware by comparing C and Rust firmware. In theory, the best is to select both C and Rust for your next product, but in practice, it’s unlikely to work due to budget constraints. The source code for the project will eventually be published on STM32 Hotspot.
Via Adafruit.

Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.
Support CNX Software! Donate via cryptocurrencies, become a Patron on Patreon, or purchase goods on Amazon or Aliexpress. We also use affiliate links in articles to earn commissions if you make a purchase after clicking on those links.




