1. 25
  1. 4

    I’ve been following Rust for a while and it’s shaping up to be a very interesting language. Focusing on polish also seems like a sign of maturity, which is welcome.

    Is anyone familiar with embedded & bare metal applications of Rust? How does it compare with C++?

    1. 12

      My company, Ferrous Systems, actually does it’s main business in embedded. We didn’t expect that, expecting Rust on microcontrollers to be something to carry for a while, making our money with database development and stuff. We run trainings, which sell extremely well. Also, we have a couple of clients where we prototype new platforms.

      The current state of Rust on embedded is: If you have no problem writing some drivers on your own, or linking C libraries for that, we’re there on ARM and some other microcontrollers. RISC-V and ESP support is coming. There’s patterns, even higher-level libraries like RTFM and small RTOS available and in use. Cargo and the whole stack supports cross compilation and is really clean and nice to work with. There’s an professional ecosystem, even if it is young.

      Language-wise, we’re done and stable, though.

      This year, the goal is to make Rust embedded more featureful, by supporting more devices. Next year, the goal is to make it as convenient as desktop Rust.

      Adding to what @iswrong is writing, I can also highly recommend the the Decawave DW1000 boards, which we have great support for, if radio applications are interesting to you.

      Rust lands somewhere between C and C++: It has abstractions like C++ and uses them to full effect, but it is fundamentally a “functions and data” language like C, without classes and (automatic) dynamic dispatch.

      I’m happy to answer any specific questions!

      1. 2

        That is actually very encouraging, thank you for your answer! My workplace has been using IAR for their bare metal work, and it’s left a bad taste in my mouth - we stumbled into a compiler bug that could only be fixed by disabling a specific optimisation, or by spending thousands on a new version of the compiler. I feel like Rust’s development model would’ve given us a lot more agency in solving that particular problem.

        If we end up going for an ARM micro for a future project, I will definitely start a discussion on Rust.

        Concerning C++ vs. Rust, I was mostly curious about how they compare in terms of cross-platform capability. For instance, IAR doesn’t have the best support for modern C++ features, so we have mostly been using GCC whenever we can get away with it. In your experience, how does Rust adoption compare to modern C++ (C++11 or 14)?

      2. 6

        I did some embedded Rust on STM32 (Blue Pill) and the Micro:Bit for fun recently. The basic stuff is in place: you can compile for embedded ARM targets, the binaries (with no_std) are lean enough to put on flash. You can debug programs on-device with e.g. STM-Link v2 or a Black Magic Probe. Library-wise there is also quite a lot of plumbing, such as the heapless library for basic containers that do not do dynamic allocations. Obviously, you also get a lot of the safety benefits from Rust, this goes deeper than one might expect. The device peripherals are types such that it is hard to use them incorrectly. E.g., if you use a pin as an input pin, it gets an input-specific type:

        https://docs.rs/stm32f1xx-hal/0.2.1/stm32f1xx_hal/gpio/gpioc/struct.PC13.html#method.into_pull_up_input

        Where it is still quite lacking is support for drivers: there are drivers out there, most of which are listed on the page that @nickpsecurity links to. But they vary from full-fledged (e.g. the SSD1306 OLED display driver worked pretty well) to very rudimentary. Networking is also limited, there is japaric’s stack, but japaric states that it is mostly a personal experimental thing. smoltcp looks promising, but it’s still quite a bit of work to hook it up with drivers, e.g. I tried to use smoltcp with an ENC28J60, which entails writing some low-level code yourself. The same is true for e.g. Bluetooth support, what is out there is still rudimentary.

        So, it very much depends on what you want to do. If you have some application that primarily uses the microcontroller or some basic peripherals (LEDs, LDRs, or whatever), you are fine. If you want to do more, do some investigation before buying specific I2C devices.

        If your goal is just to play a little with Rust on embedded, you can do it now. Just get an STM discovery board, Blue Pill (with the right resistors and a good regulator), or a Micro:Bit. Blue Pills can be had for a few dollars. So, you can play around with embedded Rust without breaking the bank. If you go for a Blue Pill, also get an STMLink v2 (clone) device, it makes your life much easier for flashing and debugging than the STM32Duino bootloader that some devices come pre-flashed with.

        1. 6

          Check this out.

        2. 1

          I’m really excited to try rust. I haven’t touched it in a while and wanted to build a project (pijul). However, cargo actually segfaulted on me! So my first impression after not looking at it in a while is that rust segfaults. Which is crazy considering the language tries really hard not to do that.

          I have rust 1.32. I guess I need to upgrade…

          1. 4

            As a counterpoint: I’ve never seen Cargo segfault since it came into existence. You might consider filing a bug, since a seg fault is pretty serious in the Rust ecosystem if it’s related to memory safety.

            1. 1

              Well, rust has plenty of open issues related to segfaults like this one opened only a week ago. It’s clear it’s still maturing, which is fine, even gcc still gets segfault bug reports!

              I also can’t reproduce the problem, it happened twice but then it worked. I’d rather upgrade and assume it’s been fixed. If it happens again using the latest version then I’ll file a report.

              1. 3

                Well, rust has plenty of open issues related to segfaults like this one opened only a week ago.

                That looks like a stack overflow. (Indeed, trying that OP’s program yields a stack overflow in debug mode.)

                See also: https://users.rust-lang.org/t/rust-guarantees-no-segfaults-with-only-safe-code-but-it-segfaults-stack-overflow

                1. 2

                  Well, that’s the thing right, Rust solves a very specific set of memory safety issues but not everything. It would be wonderful if there was a holistic solution to these things. For example, people had issues with leaking memory, so people created garbage collected languages which solved a subset of memory leaks, but things like cyclic memory dependencies still cause leaks in most garbage collected languages. Garbage collection also doesn’t solve managing non-memory resources. C++ (and Rust) use RAII to solve a more general resource management problem which handles many more cases than garbage collection.

                  It would be great if there was a more general solution to memory issues. The borrow checker was Rust’s attempt, so maybe they can extend the idea further because it seems it’s close.

                  1. 4

                    No, of course Rust doesn’t solve every problem. I don’t know why that would be the default standard to assume? Anyway, A seg fault is a symptom, but not in and of itself an indicator of memory unsafety. I was also just trying to provide a counterpoint. Getting a seg fault from Cargo is a pretty bad look. I just wanted to provide a counterpoint.

                    1. 1

                      Yeah, I totally get it. I am seeing lots of cool projects written in rust now. So I’m cheering from the sidelines here. I’ll stick with C++ for now but may use rust in the future. Strangely the language I am most excited about is Perl 6, because, it’s just so crazy. I’ve had rakudo crash on me too. It’s not easy being on the cutting edge right?

                    2. 4

                      It would be great if there was a more general solution to memory issues. The borrow checker was Rust’s attempt, so maybe they can extend the idea further because it seems it’s close.

                      Which memory issues are you referring to here, memory leaks / memory management, or memory unsafety? The rust borrow checker doesn’t really make an attempt to solve the first set of issues, only the second, and at least in theory it does completely prevent memory unsafety.

                      Just to make sure everyone’s on the same page here, safe Rust as a concept is always memory safe, and is in practice memory safe modulo current unsoundness bugs in the rust compiler. A stack overflow is not memory unsafe if it deterministically causes a segfault (see burntsushi’s linked post). You probably already know this, I just wanted to make that point completely clear for anybody who doesn’t read the linked post.

                      RAII and the borrow checker do to an extent help memory management (you don’t have to allocate if you can instead borrow), but Rust definitely does NOT prevent you from leaking memory or running out of stack space, Box::leak is safe for a reason, and in order to prevent stack overflows you would have to forbid general recursion?

                      Like the others said it could also be that cargo legitimately has a memory safety issue in unsafe rust or one of its dependencies also, I’m not claiming it doesn’t, but in either case it sounds like a serious issue.

                      Rust guarantees are at once both extremely valuable but also kind of subtle, so I just wanted to provide some extra context for anybody else reading.

                      1. 1

                        Thanks for the clarification, this helps a lot. There is no way to prevent stack-overflow just as there is no way to prevent out of memory systematically. And the correct behavior is definitely to abort.

                        A thought I had when looking back at this discussion is that from a users perspective when a program quits via segfault, they really don’t care if it’s because of a stack overflow or invalid access, or whatever. Which brings us back to the limit of tools and that in the end, the most important thing is correct design and UX. Tools can help here, for example TLA+ can help debug a design. But as much as us programmers want to remove humans out of the equation, it’s strictly impossible and we shouldn’t confuse things like memory safety (or any other property) as an end in itself but a tool in the toolbox in expressing more clear metal models.

                  2. 3

                    A report would definitely be interesting. cargo also links a number of C libs (most notably libgit2), which might also be the culprit, they would probably also love reports :).