I've been working in embedded for 5 years and am curious how rust could solve my biggest headaches: * Managing build configurations - I use CMake to build a single application for multiple hardware platforms. This is accomplished almost exclusively through linking, e.g., a single header file "ble-ncp-driver.h" with multiple "ble-ncp-driver.cpp" files for each target platform. I call this the "fat driver" approach whi…
Ask HN: Has any Rust developer moved to embedded device programming?
11–20 of 64 posts
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#12I've been working in embedded for 5 years and am curious how rust could solve my biggest headaches: * Managing build configurations - I use CMake to build a single application for multiple hardware platforms. This is accomplished almost exclusively through linking, e.g., a single header file "ble-ncp-driver.h" with multiple "ble-ncp-driver.cpp" files for each target platform. I call this the "fat driver" approach whi…
Not an embedded systems developer so an honest question. What do you do instead of malloc? Have a large array on stack and manage memory within that manually?
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#13I've been working in embedded for 5 years and am curious how rust could solve my biggest headaches: * Managing build configurations - I use CMake to build a single application for multiple hardware platforms. This is accomplished almost exclusively through linking, e.g., a single header file "ble-ncp-driver.h" with multiple "ble-ncp-driver.cpp" files for each target platform. I call this the "fat driver" approach whi…
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#14I've been working in embedded for 5 years and am curious how rust could solve my biggest headaches: * Managing build configurations - I use CMake to build a single application for multiple hardware platforms. This is accomplished almost exclusively through linking, e.g., a single header file "ble-ncp-driver.h" with multiple "ble-ncp-driver.cpp" files for each target platform. I call this the "fat driver" approach whi…
> (easy to do if you never, ever malloc) Not an embedded systems developer so an honest question. What do you do instead of malloc? Have a large array on stack and manage memory within that manually?
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#15Rust-embedded is an easy ecosystem to work with (if immature), and if you want more flexibility, Tock OS [0] is trying to cover that space (also immature, but I'm working on it).
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#16STM32s however are a different story... I'm using the stm32h7 microcontroller with Rust in a production product. Its really great.
Hopefully the ESP32 support matures sooner rather than later, which I think would be great for more Rust IoT uptake and Rust embedded as a whole.
I would love to see Rust become the defacto standard in embedded development.
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#17I've been working in embedded for 5 years and am curious how rust could solve my biggest headaches: * Managing build configurations - I use CMake to build a single application for multiple hardware platforms. This is accomplished almost exclusively through linking, e.g., a single header file "ble-ncp-driver.h" with multiple "ble-ncp-driver.cpp" files for each target platform. I call this the "fat driver" approach whi…
In terms of package management, you can apply rules to what crates you want to include; including specific platform constraints.
[target.'cfg(target_os = "linux")'.dependencies]
nix = "0.5"
On the code side it's pretty much the same as C++. You have a module that defines an interface and per-platform implementations that are included depending on a "configuration conditional check" #[cfg(target_os = "linux")] macro.https://github.com/tokio-rs/mio/blob/c6b5f13adf67483d927b176...
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#18It's very hard to unlatch your brain from some of the common C/C++ embedded principles of static context variables and thinking of the hardware registers as "owned" memory, which you have to do in Rust. The auto-generated HAL crates aren't that great unless you're using the most common ones like stm32f4 or RP2040. Even then, it's hard to create a portable device driver without delving into generic-hell.
That all said, the ecosystem is moving fast, and a lot of my gripes above are just a product of the embedded rust ecosystem being very new in comparison to C. I do love rtic as a framework, and while I've given embassy a try I think it's trying to do too much aside from being a good async runtime, it should just focus on the runtime and not with stuff like creating its own entire HAL. Hubris and humility are fascinating but I just haven't gotten around to tinkering with them yet.
Lots of good tooling too, and the fact that most of your original C/C++ debugging tools are compatible with rust binaries is just the icing on the cake.
I know that there's the whole Ferrocene project, but until that produces results, stick with C if you're doing safety-critical applications, especially if they need to be certified
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#19Not exactly embedded but I'm writing an operating system kernel in Rust, having done so previously with C. I love it so far. There are still some rough edges in the tooling, but overall I'm very happy. The resulting binaries are much larger than C projects, but I'm also opting into a lot of functionality you probably wouldn't always need in smaller environments.
Can you name a few of those rough edges in the tooling? Thanks
Cargo recently got multi-target builds which is great, and makes this way less of a headache before (usually had to run cargo once per target, now it can do all of them at once).
The next challenge is packaging things up. Cargo gives you a hook for running things prior to the actual crate compilation (e.g. using it plus graphicsmagick to generate a bit font for the boot sequence rasterizer) but lacks the ability to run anything after the build, which means no development disk image building or any image checking can occur without a second command.
There's an open issue tracking this with countless use cases but the cargo team seems reluctant to "replace build systems" (which is ludicrous to me).
Re: Ask HN: Has any Rust developer moved to embedded device programming?
#20I've been working in embedded for 5 years and am curious how rust could solve my biggest headaches: * Managing build configurations - I use CMake to build a single application for multiple hardware platforms. This is accomplished almost exclusively through linking, e.g., a single header file "ble-ncp-driver.h" with multiple "ble-ncp-driver.cpp" files for each target platform. I call this the "fat driver" approach whi…
At work I had the same stance as you, and pushed against adding rust to our ecosystem (to avoid fragmenting what was 100% C++/python): - memory ownership bugs are not a problem (and even on the host, with unique_ptr and shared_ptr you can really get quite far) - C++ meta programming is really quite expressive to nip most bugs in the bud (say, writing to the wrong port, adding an i16 to an i32, or adding ms to us), - C++ meta programming is pretty good at building bigger abstraction, such as monadic tasks
Here's the main advantages I see and which convinced me to take it seriously.
- cargo for package management and building. It's extremely easy and "nice" to add packages, manage multiple configurations, build additional tools as part of the building, but run them on the host (say, a protocol parser generator etc...)
This is just huge. I basically almost never reused any code except copy pasting source from other projects or from the vendor lib straight into the project, because anything else was just too brittle, even with CMake. Most embedded projects I worked on had their own idiosyncratic build system based on make, and you had to relearn it every time.
- macros that are actually worth it. THis might be the most exciting thing. I often use patterns such as state machines and other formalisms, but the best I can do in C++ to make them nice to write is mix up some ugly ass macros with some templating, and it always ends up being a mess in the error messages. Rust gives you some really decent "lisp"-y metaprogramming.
- rust works equally well for the bare metal and the highest level scripting. That means that my projects won't end up being a mix of cmake + bash + python + C++, I can do everything in rust.
- the embedded code with an abstracted HAL looks REALLY nice. It's almost arduino-like, except this is actually the real thing. This is what my pairing partner and I came up with to control a SPI display:
fn new(
spim: spim::Spim,
timer: &'a mut hal::Timer,
cs: gpio::Pin>,
rst: gpio::Pin>,
dc: gpio::Pin>,
busy: gpio::Pin>,
) -> Display {
return Display {
spim,
timer,
cs,
rst,
dc,
busy,
};
}
fn init(&mut self) {
self.reset();
// BOOSTER SOFT START
self.spi(&[0x06u8, 0x17, 0x17, 0x17]);
// POWER ON
self.spi(&[0x04]);
// CHECK NOT BUSY
self.check_not_busy();
Not only is every GPIO configuration typechecked, but the HAL layer takes care of initializing the abstracted HAL peripheral correctly for this chip architecture (nrf52833). This is of course not rocket science, but dang it just felt nice to have it work, and not have to wrestle with some mud-tier vendor HAL monstrosity.- the community has reached critical mass, and I think it won't be too long until there are actually more rust developers on the market than C++ developers. Plus you kind of get the full-stack experience.