Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Why Rust is a great fit for embedded software – 2023 update (tweedegolf.nl)
51 points by kristianpaul on July 22, 2023 | hide | past | favorite | 29 comments


Still waiting on Rust. I have attempted to use it beyond toy programs, and it wasn't clicking for me.

I am using SPARK2014[0], a big subset of Ada, that has a 25-year track record in high-integrity, safety-critical applications in civil and military applications in many fields. It's also very easy to pick up with integrated tooling and a package manager called Alire.

I used to despise verbose syntax, and when I first tried learning Ada over 12 years ago, I now see SPARK2014's syntax and methods as much easier and to work with especially with the surrounding and supportive ecosystem.

I worked through the book, "Building High Integrity Applications with Spark"[1] that is a very nice summary and intro to SPARK based on its use in the CubeSAT program.

Here's a cute little article on how SPARK2014 was used to replace some low-level stabilization routine in a bigger C program for a specific consumer drone:

https://blog.adacore.com/how-to-prevent-drone-crashes-using-...

[0] https://www.adacore.com/about-spark

[1] https://a.co/d/fgtRXxt


I miss coding in Ada. I wish Rust would pillage more of its features. Range types especially seem like they would be at home in the Rust ecosystem.


I have good news for you then-- there already is some experimental[0] work towards this, under the name of "pattern types" (although I believe it's on pause at the moment). The idea seems to be to pull some of the pattern semantics into the type system, allowing for more than just range types, based on a series of blog posts[1] by the author of the PR. Additionally, Yoshua Wuyts has another blog post[2] which gives a decent intro on the concept and what it could be used for down the line.

[1]: https://github.com/rust-lang/rust/pull/107606 [2]: https://cohost.org/oli-obk/post/165584-ranged-integers-via [3]: https://blog.yoshuawuyts.com/pattern-extensions/#pattern-typ...


Rust does have ranges? (They have their problems, namely that they're Iterator instead of IntoIterator and all the problems that entails, but they certainly exist.)


Rust ranges aren't types. In Ada you can specify a type like:

  type Temperature is range -100 .. 300; -- in Celsius, operating range for an aircraft or system perhaps
You cannot assign anything outside that range to variables of that type, if the value is known at compile time it won't compile otherwise you get a runtime error (unless you disable checks). You cannot assign an arbitrary integer variable's value (that holds a value in that range) into a variable of type Temperature, you have to cast it.

  T : Temperature := 500; -- won't compile
  ...
  T : Temperature;
  N : Integer := 50;
  ...
  T := N; -- won't compile
  T := T1 + T2; -- two other temperatures; runtime error if sum is outside -100 .. 300

If you want a subtype range you might do something like:

  type Days is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); -- an enumeration
  subtype Weekdays is Days range Monday .. Friday; -- ranges are inclusive in Ada
Now you can have a variable of type Days and try to put its value into a variable of type Weekdays and you'll get a runtime error if it's Saturday or Sunday. And you can use these for array indices. These are actual arrays, not dictionaries, so you don't get the performance penalty of a map/dictionary (though generic maps are also available):

  Schedule : array (Weekdays) of ...; -- fill in with some useful type; Weekdays is the index range

  D : Days;
  W : Weekdays;
  ...
  W := D; -- will compile, may error at runtime
  D := Saturday;
  W := D; -- will error at runtime
  W := Sunday; -- won't compile
  W := Monday; -- will compile
  Schedule(W) := ...;


As an addendum, this is something that most Pascal derived languages also support, Object Pascal, Mesa, Modula variants, (with exception of Oberon and its linage), and sadly many associate only to Ada.


> It wasn't clicking for me.

Out of curiosity, was the problem with the language itself, the embedded library/tooling ecosystem, or something else?


To be fair, I started programming back in 1978 with Commodore PET 2001 and went into C and assembly (6502) after that. I then picked up Pascal. Then J and APL after that. While trying Rust for the first time, nailing some of the concepts and syntax (borrow checker, etc.) to express those concepts was very confusing or too verbose to me. Then the second time I tried Rust, I was also learning Zig, and Zig came much easier to me and I could program things quicker albeit without the features of SPARK2014 or Rust for that matter, but a nice sweet spot. But when I saw the goals of Rust and I had already tried SPARK2014, it became apparent that the wish list for Rust was a reality in SPARK2014 and its tooling. The safety, integrity, verifiability, clear and simple syntax along with the formally proven language of SPARK2014, and Ada's legacy seemed the obvious choice to get actual software written for safety-critical applications. I am working on Show Control software which demands high integrity and safety. One leading package, Navigator, runs on QNX. When you are flying things over people's heads at high speeds and accelerations or flying people, you need something that is track proven for such applications. I think Rust can get there someday. I have put Rust on shelf until it matures more on this front. As others have mentioned, Adacore is not so much an PL evangelist as might be thought of by its name, but is cooperating with Ferrous Systems and others to bring Ada/SPARK2014 goodness to Rust. Rust just isn't there yet, and I am a bit too far along to devote my next 10 years to growing and learning Rust when I can apply SPARK2014 today. PL syntax is subjective, and I just find myself tripping over the verbosity in a C++/C-like syntax that Rust adds. I know there are strides to improve this, but


One interesting development is the collaboration between the Ada/spark communities and the Rust community. For example, Adacore is releasing a certified Rust compiler pretty soon [1].

I seem to recall they were using Spark for some of the core libraries then exposing all the goodness to the Rust code.

[1]https://www.adacore.com/gnatpro-rust


Don't disagree with you about Rust, but the Spark website has no download link, just a link to "Request Pricing", which requires a "professional" email. As much as I'd like to, don't think I'm going to spend my Saturday morning playing with it.


This is something which I think has really hurt Ada adoption, even though in theory it is now available in open-source. I tried to evaluate it for some embedded hobby project a while ago and I could not figure out whether the open-source options supported both SPARK and cross-compiling to a cortex m3, and if so how on earth I was supposed to get ahold of the right version and use it. I think this may have improved, but I think there are a huge number of potential Ada users who have written it off because of this (even with an admittedly quite cursory browse of the links below I get the idea that this works, but still no concrete idea of how: lots of examples of code for embedded systems but none I could find of how its built!).



Or use Alire which wraps it up and manages multiple installations for you. This is my preferred way to install it, and it makes it easy to select compilers for cross-compilation (like for embedded targets) or to select particular compiler versions.

https://alire.ada.dev/


Is Ada really as good as its touted to be? How good is the cross compilation, metaprogramming and FFI story?


FFI is described here: http://www.ada-auth.org/standards/22rm/html/RM-B.html

Here with some examples using gcc and gnat: https://gcc.gnu.org/onlinedocs/gnat_ugn/Mixed-Language-Progr...

And finally here with the Adacore learning site: https://learn.adacore.com/courses/intro-to-ada/chapters/inte...

I have limited experience with FFI in Ada, but never had any issues. Cross compilation is about the same as you'd expect from any mature language ecosystem. Metaprogramming, it does not have macros but it has a very good generics systems.

Also for some reason your comment was dead (not flagged dead) so you may want to email the HN mods (see contact at the bottom of the page) about that.


"alr is tailored to userspace, in a similar way to Python’s virtualenv. A project or workspace will contain all its dependencies."

So, each time I create a new project with alr, an Ada toolchain will be downloaded into its project directory?


Last time I tried Rust on bare metal it needed a bunch of hacks or C code to glue it all together. It's just too high level for the most bare metal applications.


This hasn't been true for a long time. Stable rust can do bare metal armv7m or risc-v development without any C code; just a bit of (inline) assembly to call into a rust main() function using the C ABI.


security and memory safety are non issues in most embedded devices


That certainly appears to be what embedded developers think, given how many issues there have been with IoT security.


Yes, and the salaries are really poor. I make more money writing javascript than I ever did with embedded C.


Because that's where the money is. You don't get paid for your technical abilities but for how much value you bring to an employer. There are probably a good chunk of researchers that still eat instant ramen at the end of the month that were involved with all those AI algorithms that are all the rage right now for Google Bard, ChatGPT and whatever MS calls their Bing stuff.

I thought about switching to something more low level but as long as I can stomach my current job I don't really see a good reason why. I don't even earn that much money but I'd probably still take a pay cut going into embedded.


I need to regularly reboot my smart bulbs and power sockets. There's definitely room for a more reliable firmware on these things.


We all know that S in IoT stands for security.


And the R for reliability.


It would be nice to find a good rundown of how much of the memory safety properties are preserved at stages in the microcontroller/linux driver development.


What does verified C offer that rust doesn't? Is Ferrocene addressing that requirement?


what is "verified C"?


Probably C that has been audited and certified that it follows a standard designed for safety critical systems like MISRA.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: