Authors are from STMicro, polytechnic Turin, Freie universitat Berlin, and Inria. Examined writing firmware for an IOT sensor platform. From the abstract:
> 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.
I'm curious why I've seen this sentiment repeated in so many places, I learned Rust once 5 years ago and I haven't had to learn any new idioms and there have been no backwards incompatible changes to it that required migrating any of my code.
The code won't magically stop running because the Rust community continued evolving the language. The old toolchains will be available if there's a compatibility change.
> Rust is evolving far too fast to be used in code which needs to run for years to decades down the line.
Code doesn’t stop running on existing hardware when the language changes in a future compiler. You can still use the same old toolchain.
I’ve done a lot of embedded development in a past life. Keeping old tool chains around for each old platform was standard.
I would much rather go through the easy process of switching to an older Rust tool chain to build something than all of the games we played to keep entire VMs archived with a snapshot of a vendor tool chain that worked to build something.
I'm curious what the concern is with the rust editions mechanics in place. Each crate gets to define the language edition it is compiled with. Even if dependencies up convert to later editions they can still be linked against by crates that are an older edition.
As for the broader crate ecosystem, if crates you depend on drop support for APIs you depend on, that could cause you to get stuck on older unsupported releases. Though that is no different of a problem than any other language.
I only tried Rust for small hobby projects, but I did experience weird code rot when you just leave the code there and after a while it does not compile. Might have something to do with how Cargo manages dependencies
I've had issues compiling Python 3.12 on ArchLinux when Python 3.12 -> Python 3.13 happened, and few of important packages broke. So I had to compile older version of gcc and build Python 3.12
So, it can happen in any programming language, and to any large projects.
Rust allows me to handle this easily with rust.toolchain file, so, this concern is kinda overblown imo
> Might have something to do with how Cargo manages dependencies
Build against the lockfile to use the same versions.
Unless they were pulled from upstream, they won’t suddenly stop building against the same compiler version. Rustup makes it easy to switch compiler versions to get back to the same one you used, too.
This is not a Rust issue but an inherent issue with dependencies in all languages. External dependencies rot.
For Rust code for serious industrial use cases or firmwares, it's always best to minimize dependencies as much as possible to avoid this. Making local copies of dependencies is also a thing for certain use cases.
We have Rust code in a living code base that is more than 5 years old and it's required maybe one touch in the last 5 years to fix some issues due to stricter rules. It was simple enough it could have been automated.
Yeah, a common stupid requirement. Perhaps a selling point for any solution would be to deploy a common serialization/de-serialization package that can be used on both the cloud and end point side.
Why? In IoT stuff, its very useful if you can talk to your devices via standard internet protocols, otherwise you have to introduce some pointless 'gateway' node for that.
I mean sometimes efficiency matters a lot, but a lot of other times, interoperability is more important.
I mean, text based IO with microcontrollers over tty has been quite a standard thing even decades ago.
You mean with the "two teams" that were tasked to develop the C / Rust versions?
Yeah of course. Then again - they were one person teams, where the C "team" had years of experience in stm32 / embedded C / stm32 cube development and churned out that handwritten state machine in just days. The Rust "team" was a pre-masters intern with only minimal embedded Rust experience. They ran into all the pitfalls with (async) embedded Rust, but corrected towards the end.
That does not seem like even close to a fair comparison and makes me wonder how valid the conclusion is. Effectively this is two times n=1, if you use 'teams' when you actually mean 'individuals' then that's not really proper reporting.
I do applaud you for having the same work done twice but it would have been far more meaningful to have two actual teams of seasoned developers do this sort of thing side-by-side. The biggest item on the checklist would be the number of undiscovered UB or UB related bugs in the C codebase and to compare that with the Rust codebase on 'defect escape rate' or some other meaningful metric.
I think there’s another hidden issue of testing how new devs use the language vs. those seasoned devs. I expect someone with a few months of experience would prefer Rust (fewer footguns) but someone with more experience would prefer C (the sharper knife). The flavour of the thing changes as we age.
The problem with C - and I'm saying this as a life-long C programmer and not exactly a fan of Rust - is that C is indeed very sharp but it will cut other people just as easily even though they are far downstream of the original programmer, as well as the users of those programs. And it is extremely hard to not accidentally fall for one of the many pitfalls of C.
I've got my own set of restrictions for when I'm coding in C based on many nights spent poring over various pieces of code and trying to find a way to do it better and safer without outright switching languages. I do believe it is possible. But at the end of all that you have essentially redefined the language in a way that probably no other C programmer would like or agree with, and it would still require very good discipline.
So having languages with fewer footguns is good, as long as the lack of one kind of footgun isn't replaced by a other kinds of footguns. It is one of the reasons I'm interested in the FIL-C project.
1. So Ariel OS is based on Embassy - IIUC I2S and CAN has some support upstream. That can be used already, although not using Ariel's usually fully portable APIs.
2. Well, ST has released official Rust drivers for a bunch of their sensors. They're built on embedded-hal(-async), so can directly be used with Ariel OS. There is probably more.
I'm a big fan of Rust on embedded (and think embassy in particular is awesome, haven't tried this Ariel OS.)
I would say however that there's still toolchain issues here. There all kinds of MCUs that simply don't/won't have a viable compiler toolchain that would support Rust.
e.g. I recently came from a job where they built their own camera board around an older platform because it offered a compelling bundle of features (USB peripheral support and MIPI interface mainly). We were stuck with C/C++ as the toolchain there, as there was no reasonable way to make this work with Rust as it was a much older ARM ISA
> 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.
Rust is evolving far too fast to be used in code which needs to run for years to decades down the line.
I'm curious why I've seen this sentiment repeated in so many places, I learned Rust once 5 years ago and I haven't had to learn any new idioms and there have been no backwards incompatible changes to it that required migrating any of my code.
Where's the problem exactly?
Code doesn’t stop running on existing hardware when the language changes in a future compiler. You can still use the same old toolchain.
I’ve done a lot of embedded development in a past life. Keeping old tool chains around for each old platform was standard.
I would much rather go through the easy process of switching to an older Rust tool chain to build something than all of the games we played to keep entire VMs archived with a snapshot of a vendor tool chain that worked to build something.
That statement deserves support.
As for the broader crate ecosystem, if crates you depend on drop support for APIs you depend on, that could cause you to get stuck on older unsupported releases. Though that is no different of a problem than any other language.
So, it can happen in any programming language, and to any large projects.
Rust allows me to handle this easily with rust.toolchain file, so, this concern is kinda overblown imo
Build against the lockfile to use the same versions.
Unless they were pulled from upstream, they won’t suddenly stop building against the same compiler version. Rustup makes it easy to switch compiler versions to get back to the same one you used, too.
For Rust code for serious industrial use cases or firmwares, it's always best to minimize dependencies as much as possible to avoid this. Making local copies of dependencies is also a thing for certain use cases.
We have Rust code in a living code base that is more than 5 years old and it's required maybe one touch in the last 5 years to fix some issues due to stricter rules. It was simple enough it could have been automated.
I mean sometimes efficiency matters a lot, but a lot of other times, interoperability is more important.
I mean, text based IO with microcontrollers over tty has been quite a standard thing even decades ago.
Yeah of course. Then again - they were one person teams, where the C "team" had years of experience in stm32 / embedded C / stm32 cube development and churned out that handwritten state machine in just days. The Rust "team" was a pre-masters intern with only minimal embedded Rust experience. They ran into all the pitfalls with (async) embedded Rust, but corrected towards the end.
I do applaud you for having the same work done twice but it would have been far more meaningful to have two actual teams of seasoned developers do this sort of thing side-by-side. The biggest item on the checklist would be the number of undiscovered UB or UB related bugs in the C codebase and to compare that with the Rust codebase on 'defect escape rate' or some other meaningful metric.
I've got my own set of restrictions for when I'm coding in C based on many nights spent poring over various pieces of code and trying to find a way to do it better and safer without outright switching languages. I do believe it is possible. But at the end of all that you have essentially redefined the language in a way that probably no other C programmer would like or agree with, and it would still require very good discipline.
So having languages with fewer footguns is good, as long as the lack of one kind of footgun isn't replaced by a other kinds of footguns. It is one of the reasons I'm interested in the FIL-C project.
https://fil-c.org/
2. Well, ST has released official Rust drivers for a bunch of their sensors. They're built on embedded-hal(-async), so can directly be used with Ariel OS. There is probably more.
I would say however that there's still toolchain issues here. There all kinds of MCUs that simply don't/won't have a viable compiler toolchain that would support Rust.
e.g. I recently came from a job where they built their own camera board around an older platform because it offered a compelling bundle of features (USB peripheral support and MIPI interface mainly). We were stuck with C/C++ as the toolchain there, as there was no reasonable way to make this work with Rust as it was a much older ARM ISA
-> paper is not final. And IIUC ST will be releasing the code at some point.
https://info.arxiv.org/help/faq/whytex.html