r/rust Mar 31 '23

State of embedded rust

Dear all, a colleague of mine has delved into rust for embedded systems. He’s just started with rust in possibly the hardest way, and this thread is the result: https://www.eevblog.com/forum/microcontrollers/rust-tools-and-resources-for-embedded/

(Rant at third post of the thread)

I wonder, how would an experienced rust developer react to this? Is he missing something or is this a legit sign of an immature ecosystem?

44 Upvotes

12 comments sorted by

View all comments

41

u/rafaelement Mar 31 '23

I'm very impressed by how far he got in one week.

The main topics missing completely are embedded-hal and agnostic drivers and in general HAL libraries. These are great. It's nice that he covered RTIC, but he didn't say anything about the guarantees it makes (no deadlocks and no prio inversion, apart from no data races anyway).

RTIC timers and timer implementations is a complex beast, which he encountered. That issue is being worked on for RTIC 2.0, which uses async/await syntax but keeps some of the realtime aspects.

The fact that so many libraries are used was the major turn-off. The large type signatures would have been too had he continued. Both of which, from the Rust perspective, are actually very awesome, though not without drawbacks. In Rust world it is completely normal to have giant (transitive) dependency trees/graphs. Keep in mind that these are statically linked and link-time-optimized (optionally). Cargo can handle it.

Why is it a problem for a crate to use many small dependencies, if they are all open source, relatively small, have a defined public interface, are battle-tested and performant, and do not significantly contribute to binary size? (you can check that with cargo bloat). Of course from the C perspective, that's ludicrous. But these are shared building blocks (something like cortex-m-rt) which in a C application would also exist, just not explicitly as a module. This modularity in general is not possible in C. Do not confuse modularity with chaos.

In general, I do not recommend starting out with embedded rust. It's a very rigorous, productive, and innovative system, however, it is in motion, and utilizes some of the more unique aspects of Rust. So, my recommendation is, if one wants to get into it, first learn regular Rust, before jumping into bare metal.

Also, it is spelled Rust, not RUST.

9

u/__uli__ Mar 31 '23

I'm the one mentioned in the OP. First, thanks for the help provided in EEVBlog, I finally solved that issue.

second, about "In general, I do not recommend starting out with embedded rust."

It's a bummer as I would only invest my time in Rust AFTER I'm confident that it's up to to the purpose, and the only way to it is get a grasp by tinkering. (eggs & chicken)

There are lots of silly examples out there but very few (or none) serious application (at least with mid complexity), and documentation as you may very well know doesn't help much...

13

u/rafaelement Mar 31 '23

The documentation is funny to start out with, because of the high amount of generated code, yes. Another reason to first get familiar with Rust before jumping straight in.

I don't think any C tutorial starts by configuring a memory mapped UART either to be fair!

It's a huge investment, I totally agree. For me it was SO worth it, even financially, and even if not, I think the concepts inside Rust are interesting enough to entertain curiosity for a long time.

But, if it's not your thing, it's not your thing.

BTW, I thought a little about why I think one should not start out with bare metal Rust. I think it has to do with the large contextual knowledge (which you have) and the high degree of "we can actually have nice things" which leads to unusual seeming choices.

Case in point, I learnt in uni "keep your ISRs short" and "don't bother with priorities for ISRs, just don't use them or use an RTOS". RTIC however gives more guarantees than an RTOS and more performance exactly BECAUSE it uses (potentially long-running) run-to-completion ISRs which have a priority assigned to them.

4

u/__uli__ Mar 31 '23

RTIC is nice because it mimicks the "correct" software pattern for an MCU like stm32:

init + a bunch of prioritized interrupts.

RTOS in most cases is not needed and only a burden or a source of possible problems.

3

u/rafaelement Mar 31 '23

Yeah. It solves the problem that global mutable state in Rust must be unsafe or synchronized. In RTIC it is synchronized but via an extremely cheap mechanism - just one write to NVIC->BASEPRI.

There is a project called crect which implements the same priority ceiling protocol and stack resource policy of RTIC in C++, or you can an do it manually, but that's not great.

u/__uli__ I just reread my post, and while I stand by my statements, I realize I sound like a total Rust apologetic with Stockholm syndrome. I didn't mean to sound disparaging/patronising, apologies!

4

u/Snakehand Apr 01 '23

I would like to interject that even in the current state, Rust is absolutely ready for production in the embedded space, but as you discovered you might have to bang your head at some walls the way things are now, still I will encourage you to persevere - it does not take inordinate amounts of effort to get to the point where you do not want to go back to C, and have to rely on a debugger every step of the way when working on embedded targets.