|
Embedded developer here, ARM Cortex-M4 microcontrollers. I've been keeping an eye on Rust for the embedded space and although there has been a lot of movement in that area--particularly in the last couple of months--I'm not sure the value proposition fits the microcontroller market, where of course C is king. While Rust has much to offer as a programming paradigm in general, the main value is in the borrow-checker (the linked transcript cites 'memory bugs' as the most common class of bugs). Embedded software practitioners long ago abandoned dynamic memory allocation and with it the 'use-after-free' and 'out-of-bounds access' bugs, instead re-defining the problem as one of latency (e.g. you'll need to process that static buffer before it gets re-used by your UART interrupt). Take away the borrow-checker, and Rust looks less compelling. In time, Rust will find its niche in the embedded space, most likely occupying the high-level RPi/BBB/iMX SoC layer and perhaps working its way down to microcontrollers. As wiremine points out, it will require vendor support--moving away from your vendor's toolchain is a world of hurt that seasoned embedded developers just won't even consider. Pragmatism reigns: time-to-market and a cheap BoM are the main metrics, programming language a distant 10th. |
So much of our code is centered around taking measurements with a bare metal system and then transmitting them to a linux box for processing. Being able to just write `#[derive(Serialize, Deserialize)]` above a struct and then be able to send/receive it across the channel via `rpmsg.send(mystruct)` or `let mystruct: MyStruct = rpmsg.recv()` is magic. Furthermore, by encapsulating each possible message type as an enum variant, match statements provide a really great way for dispatching the message to the appropriate handler after we deserialize it.
As for the borrow checker, I actually did find it useful in bare metal. But more for handling hardware resources. Different measurements require different sets of power supplies to be activated, and exclusive control over different I/Os, etc. The ownership model made it easier to ensure statically that we sequence the measurements in a way such that the different measurement routines can never reconfigure resources that are in use by a different routine.
Anyway, we sadly aren't using Rust yet in production, even after that. Holding off until we start the next product.