Rust for embedded development: Where we are and what's missing

Hello Rustaceans,

Today I'm here to ask a favor: I would like you to help me identify the areas where the embedded Rust tooling and ecosystem need more work before Rust can be more widely used in embedded systems. This information will help me prioritize my work on the embedded Rust space during the following months.

(Full disclosure: I'm under a contract to improve Rust's embedded support. Yay!)

My current focus is on the ARM Cortex-M microcontroller space as the tooling and crate ecosystem has been shaping up quite well for some time, and it's close to being usable in production or it's already being used in production but not as extensively as it could be. But I'd be happy to help with other areas (e.g. AVR, MSP430, etc.) as time allows.

My goal is unblocking you from building embedded applications with Rust by improving the tooling, the development workflows, documentation and the crate ecosystem. So feel free to message me on IRC (japaric on #rust-embedded @ irc.mozilla.org) or via e-mail (see GitHub profile) if you need help.

Informal survey

Here are some questions for you to get an idea of what the existing blockers are:

If you are planning, contemplating or discarded the idea of using Rust for your next embedded application, I have two questions for you:

  • How do you plan to use Rust in your embedded application? Some alternatives:

    • I want to write pure Rust applications
    • I want to write Rust code on top of a C/C++ framework
    • I want to use Rust as a component of a C/C++ application
  • And, what's preventing you from using Rust? Some possible reasons:

    • I don't know where to start
    • Rust doesn't support my target device architecture (e.g. AVR, Xtensa)
    • There's no support on crates.io for my development board / device
    • Key tooling is missing:
      • How do I test my code?
      • How do I manage several build configurations (different boards, different devices, etc.)?
    • I want to see more successful applications before I hop on the bandwagon
    • I want to use stable Rust for embedded development

And if you are using or have used Rust on an embedded system please share your story! I'm sure it will encourage others to give Rust a try, and I would love to hear what difficulties you ran into.

Current status

This is where we are now. What do you think is missing in the ecosystem and tooling?

Existing frameworks and supported hardware

  • TockOS

    • An embedded operating system with a focus on security
    • Status: You'll soon be able to write userland applications in Rust
    • Application space: IoT
    • Supported hardware: mainly SAM4L microcontrollers; check their hardware page.
  • Real Time For the Masses

    • Framework for building concurrent applications
    • Status: You can build robots with it
    • Application space: real time systems, control systems, robotics
    • Supported hardware:
      • Any Cortex M3, M4 or M7 microcontroller at a register level; you'll have to do extra work to build higher level abstractions, unless someone else already did the job.
      • Boards with higher level support: STM32F3DISCOVERY, STM32VLDISCOVERY, Blue Pill
  • Photon

  • Teensy

    • Rust API on top of the Teensyduino library
    • Status: A clock has been put in production
    • Application space: general purpose
    • Supported hardware: Teensy 3.2

Getting started guides

Existing tooling

  • Xargo. Cargo drop-in replacement that compiles core on the fly. Required for almost all embedded development as there's no rustup target / rust-std component for most embedded targets.

  • svd2rust. Generates a Rust API to access a device hardware from a System View Description file. Simplest way to bootstrap support for a device.

  • dslite2svd. Converts TI's version of SVD files into standard SVD files which then you can feed into svd2rust.

  • utest. no-std unit testing framework. You can run the unit tests on real hardware or simulated hardware (QEMU).

Existing crates

Here's a list of crate used in embedded development

What's in the pipeline

Rust support for existing development boards

One of my tasks is making embedded development for these 4 boards as easy and painless as possible:

  • Blue Pill + Real Time For the Masses
  • Hail + Tock OS
  • Particle Photon + Rust on top of the Spark firmware
  • BLE400 + Rust on top of ??? (one of nRF51 SDK, MyNewt, Zephyr, etc.)

This board selection tries to exercise different frameworks (TockOS and Real Time For the Masses) and different approaches to development (pure Rust vs Rust on top of C/C++).

This past week I have been working on the photon, and I've created a Cargo project template that works on Linux and Windows (and likely on macOS too), plus I have created some safe bindings to their C HAL. Future work involves extending the safe HAL.

I have a sizable HAL for the Blue Pill on my hard drive that I haven't published yet. Future work involves documenting the process of developing a robotic application with this board and the Real Time For the Masses framework.

Work on the Hail is blocked on getting my hands on some hardware, but I want to take a close look at their kernel and userland development workflows.

And I have a BLE400 board but I haven't tried anything with it yet.

Getting rid of Xargo

If we start producing binary releases of core for the thumbv*m-none-eabi targets installable via rustup then we can use those (rustup target add) with normal Cargo instead of having to use Xargo. That should make development for those targets more similar to development for std targets. I hope to start work on this soon-ish.


I will be using the rust-embedded/rfcs issue tracker to track progress on the problems raised here so keep an eye on that.

Let's improve the state of embedded Rust!

cc @alevy @thejpster @whitequark

61 Likes

I write pure Rust applications. This is most of the selling point of Rust on Embedded to me. In general, we do greenfield implementations, so we can experiment quite a bit.

I'm already quite happy with Rust on Embedded overall! There are a few pain points left:

  • Something faster than semihosting, but as available as it. I could not get ITM working on any of the adapters I laid my hands on.
  • An explanation on how to perform cooperative multitasking in the RTFM idle thread. I know, futures and stuff, but honestly I find Rust's futures impenetrable. Going to no_std makes it harder.
  • Careful attempts at producing HALs. At first, just something to manipulate clocks ergonomically and with more portability across series, in a standardized way. I'm wary of overly brazen attempts in this area so I'll watch from afar for now :slight_smile:
  • The tools don't fit together very well just yet. The autocomplete is broken in ST3 and I don't know why--I may be missing something obvious. .cargo/config isn't the right place and form for target configuration (as discussed elsewhere). A few other things locked on Cargo that are also (less) relevant on hosted platforms, e.g. sorting out the profiles mess.

Overall we are already very productive and Rust (with the exception of one issue I'm still looking into) or @japaric's crates were never the cause of a problem and rather more often they helped fix it or eliminated it in the first place. The amount of boilerplate I don't have to write anymore is mindboggling.

13 Likes

How do you plan to use Rust in your embedded application?

I want to write pure Rust applications in a real-time context.

And, what's preventing you from using Rust?

You already know my problem here :slight_smile: - lack of MSP430 support. We're working on it! It's probably in a usable state now actually, but I've been successfully nerd-sniped into LLVM.
There's also some tooling support that I'd like to work on but I feel blocked due to the lack of basic platform support (and the fact that I don't get paid to do this, sadly). Test is a big one - I need to try out utest and see what it would take to get it working on a non-ARM platform.
I'm not too worried about support on crates.io - I figure I'm going to have to write 90+% of what I want anyway. I am however excited about some rumors that @pftbest and @whitequark are working to get dslite2svd2rust support for the MSPs.

3 Likes

I'm really keen to start using Rust embedded, mostly on STM32 devices. A lot of the work so far looks very exciting, thanks for everything you've been doing!

Right now I use ChibiOS a lot and it's really convenient to have a HAL that's well integrated with the RTOS -- operations like "stream this buffer out over SPI, using the DMA, and block this thread until that's done" are a single function call. Some kind of cooperative multitasking that's easy to use from Rust would be ace to make headway in this direction, as I find having a reasonable number of threads that are not necessarily driven by interrupts makes a lot of problems simpler.

I also almost entirely develop on custom hardware -- I get that the dev board support isn't for me, but it seems some things that are more MCU-centric are ending up in dev board crates. For example the f3 crate has this nice Serial struct but really that's useful for any hardware with an STM32F3, not just the discovery board. I know I'm basically asking for a HAL here so... I look forward to seeing what happens with HALs :slight_smile:

Ok, to answer your questions..

I want to write pure Rust applications, but I expect to start with I'll be using Rust to build libraries to link in to C applications, where the C ends up doing the HAL and possibly the multithreading and the Rust handles the interesting logic, and hopefully move more and more into Rust over time.

I would love to have a better answer to managing multiple build configurations well but it's not super important. Being able to use stable Rust would be really nice (I already try to use it for no_std libraries and just make the final executable with nightly). I like the idea of using stable being the norm for developing applications, keeping nightlies for hacking on Rust itself.

4 Likes

@whitequark

Thanks for the kind words!

I'm already quite happy with Rust on Embedded overall!

Yay!

Something faster than semihosting, but as available as it. I could not get ITM working on any of the adapters I laid my hands on.

Yeah, I have also found out that external SWD programmers don't support ITM. Of all the boards I have only the on-board ST-LINK on the STM32F3DISCOVERY has working ITM. Maybe we can hack the adapters' firmware and add ITM support.

An explanation on how to perform cooperative multitasking in the RTFM idle thread.

That's on my TODO list but I planned to use futures :laughing:. Prof. Lindgren has mentioned using libfringe in the idle loop but I haven't look at that library yet.

The autocomplete is broken in ST3

In any case today's racer doesn't autocomplete svd2rust generated API at all because of the closures and method chaining :-/.

@awygle

I want to thank you and @pftbest for all the great work you have been doing on the MSP430 front :heart:. Let me know if I can help with anything.

@adamgreig

I'm really keen to start using Rust embedded, mostly on STM32 devices. A lot of the work so far looks very exciting, thanks for everything you've been doing!

Thanks!

I know I'm basically asking for a HAL here so... I look forward to seeing what happens with HALs

Right, there should be a HAL crate between the device crate (stm32f30x) and the board crate (f3) that's usable from any f30x device but it doesn't exist yet.

Being able to use stable Rust would be really nice

Stable Rust for embedded seems unlikely to happen this year but we are always making progress. Dropping the Xargo dependency would get us closer to that for instance.

4 Likes

A common programming paradigm that I have for my bare-metal embedded development is to write unit tests for as much as possible that can be run on the host machine. By using fixed-width types, this is pretty easy, even in C, and I've found it a nice first-step towards proving a lot of your code is correct. Also makes it possible to run tests in CI. But anyways, doing this with Rust right now isn't very ergonomic. You can set #![no_std], but then you have a terrible time debugging unit tests with cargo test. I also tried #![cfg_attr(test, no_std)], but that doesn't seem to work either. The utest crate doesn't touch on this subject, and I don't ever see other embedded devs talk about this, so I wanted to bring it up here.

6 Likes

@susurrus Thanks for the comment.

A common programming paradigm that I have for my bare-metal embedded development is to write unit tests for as much as possible that can be run on the host machine

Yes, that's a pretty good approach.

But anyways, doing this with Rust right now isn't very ergonomic

Can you elaborate on this point? I use cargo test to test the cortex-m crate, which is a no-std crate, and didn't have to use #![cfg_attr(test, no_std)] or add #[cfg(test)] extern crate test. I did have to cfg away some asm! blocks which contain ARM assembly.

but then you have a terrible time debugging unit tests with cargo test.

Do you mind literally running the unit tests under GDB? Or that the test runner output looks different somehow? I haven't done the former but the test runner output looks normal.

and I don't ever see other embedded devs talk about this

See the non-host testing section of this excellent blog post :-).

The utest crate doesn't touch on this subject

utest is for running unit tests that have been compiled to no-std targets so it doesn't dwell on that subject. Though it seems that the cargo test no-std crates approach could be publicized more?

1 Like

I'm a hobbyist and a Rust beginner, so probably ignore me, but I will throw in my vote anyway:
I have a bunch of old esp8266's lying around that I would LOVE to Rustify...
But LLVM needs fraking Xtensa support :frowning:

There were some rumors on the Espressif forum of somebody working on the project, but it seems to have died.
:frowning2:

Either way, better tooling for embedded in general is always a good thing!

4 Likes

Hello @japaric !

Congratulations for your new contract, you deserve it. I am glad to know that Rust is making serious step toward embedded.

As I don't know Rust enough to seriously produce something, I am just snicking around the web to read about people using Rust in embedded.

I am definitly planning to use Rust in embedded, in the first place, I will do it as a hobby until I feel confortable with this.

I would like to be able to use pure Rust because Rust seems capable to handle it entirely and and I mostly work on little applications from scratch so I like to keep things light and simple. What I like is to have a minimal environment (vim, cli) to write, compile, test and load my apps.

Cheers !

1 Like

Well, “production” is my bedroom wall, but still :slight_smile: Anyway, update on that: my clock had an outage recently.

Feel free to skip the details in the next paragraph:

I changed the way it is hung on the wall to reduce physical strain on small wires, without turning it off. In doing so I must has short-circuited something, I’m not sure. The RTC chip (which my Rust program talks to over SPI) got in a weird state where, whenever asked for the current date-time, the response would say month zero, which is out of the normal 1..12 range. So my date handling library (which is needed to handle daylight saving time) panicked. Rebooting the system did not help, the Rust program would immediately panic again. (At the time I did not think of removing the RTC’s backup battery.) It took me a while to debug understand what was going on, though. I had to upload a temporary firmware that would reset the date without trying to read/decode the previous one first.

I think the lesson is that panics in embedded contexts are much more problematic than in other contexts. I’m used sprinkle assert! statements that might help catch bugs, but when there is no OS and a panic crashes the whole system it might be better to print some diagnostics (if there’s a serial port available that’s not blocking when disconnected) and carry on, even with values that are known to be incorrect.

What does this mean? In libraries, return Result or Option instead of panicking, as much as possible. That’s better design in any context, not just embedded. In applications, avoid assert!, unwrap, expect, etc. Consider unwrap_or, unwrap_or_else, unwrap_or_default etc instead. Or some version of those that print some diagnostics message somewhere.

It would be nice to have a library for that, but where would it print. Perhaps another library could provide something like static STDERR: Mutex<Option<&'static mut core::io::Write>> and eprint! / eprintln! macros that use it? Better yet would be to have that in the standard library, perhaps stabilizing a version of std::io::set_print that could work in core without memory allocation… What do you think @japaric? Does I/O in libcore and pluggable stdio in particular seem worth pursuing?

8 Likes

I write pure Rust applications at home. At work, for pragmatic reasons I'm looking at ways to use Rust with RTOSes we already know like Mentor Graphics Nucleus and MyNewt project (I'm very excited about that one).

I'm keen to see support for multiple platforms, and to agree some kind of HAL (in the form of discrete crates, like embedded-serial with Windows/Linux/Mac support. As a professional embedded engineer for a product design company I also need client buy-in.

You can add the TI Stellaris Launchpad / Tiva-C Launchpad to your list of supported hardware, using stellaris-launchpad.

+1000

JP

1 Like

Amazing to see money invested in embedded Rust development, that's why I'm also a patron :slight_smile:

For me, even if I develop lots of Rust, I still lack the knowledge for embedded applications. The nearest boards I have are Raspberry Pis (Zero, B+, 2 B and 3B) and an Arduino. I have recently bought the same board @japaric is using in his blog to be able to learn embedded Rust following the blog, should arrive in 2-3 weeks. Amazing work, btw.

Nevertheless, one of the things I would like is some tutorials on how to start. If I have a Rpi, what do I need to create a target specification? I want bare metal, but the only targets in Rust are for arm in Linux (the closest thing I can find). If I created a target, I saw in the cross repo that I needed a bunch of information (at least for the optional part) that I didn't know where to get.

Once the setup is done, what information about the board is relevant? How should I find it? And tutorials explaining how to manage memory, how to create a small kernel and so on would be amazing.

I feel that the tooling is pretty good already, and for new boards, I guess I could help developing once I understood how things work, but the main problem I see is that all embedded tools/tutorials assume you know about embedded development, and it's not my case. I finished my master's degree a year ago and never learned about embedded. I would like to start learning with Rust.

So, from my side, newbie tutorials for common user-oriented boards (such as C.H.I.P., Pine64, Raspberry Pi, Arduino) would be awesome. I would also like to learn some real-time development for powerful boards (things like video processing).

9 Likes

At work we're using a STM32 controller with a fairly large and complex C codebase. I've used a lot of Rust in my spare time, released a crate or two, and even wrote up a bit of a tutorial for using unsafe code to help with incorporate Rust into existing (desktop) projects.

I also played around with Rust on a dev board at home (discovery and copper are awesome resources, keep it up!) and found the experience quite nice compared to using the STM32 C HAL.

How do you plan to use Rust in your embedded application?

I want to use Rust as a component of a C/C++ application.

Embedded Rust on its own, while not fully mature yet, is fairly straightforward to do. The real challenge will be embedding it into an existing C codebase. In an ideal world want to be able to drop the compiled Rust library into the build directory, add the relevant linker stuff, have a nice auto-generated header file the calling C code can #include (I've looked at rusty-cheddar but it seems to still be very much a work in progress), then hit build and everything should Just Work.

And, what's preventing you from using Rust?

It's mostly human reasons (lack of familiarity, inertia, etc) rather than technical ones at the moment. Dealing with that is probably going to be a case of more documentation, blog posts, and tutorials than anything else, but being able to show Rust is being used for embedded stuff elsewhere will go a long way when selling it to the rest of the team. Your blog will do a lot to help out with that, but it'd be useful if there were a couple more in-depth articles on how you may integrate rust code into an existing embedded codebase.

It'd also be nice if testing was easier to do on the microcontroller, utest looks hopeful but it probably needs a bit more work before it's production ready. Otherwise I'd just use cargo test on my dev machine and #[cfg(test)] bits out, then you can cover the rest with manual testing.

TL; DR: We need more resources like tutorials, docs, and blog posts. Existing microcontroller companies set a pretty low standard for docs, so if Rust shows itself to be easier to use in embedded applications than C/C++ that'd do wonders for adoption.

3 Likes

How do you plan to use Rust in your embedded application?

I want to write pure Rust applications

And, what's preventing you from using Rust?

Rust doesn't support my target device architectures, in my case AVR and older ARM (pre Cortex).

1 Like

At one point I really wanted rust for the ESP8266 chips that are popular among hobbyists. I even went so far as to investigate exactly what would need to be added to LLVM to support the extensa CPU. In the end, I couldn't justify the cost.

Since then I've started moving towards arm chips because they have much better rust support already. In particular, I've got STM32M042 boards and the Padi IoT stamp from pine64.

My dream for the hobbyists market would be a rust framework with similar abstraction level to Arduino wiring, but for the Padi board with full wifi support.

I could then help write the docs and IDEs, libraries, etc to build a rust maker community to rival esp8266.

Going back to the professional side for the STM32 M0 board, I'd probably want something a little lower level similar to what others here have asked for.

2 Likes

(I thought of a couple more things, hope that's OK)

Something else that would be helpful would be a small IP stack written in Rust (something like uIP or lwip). If you were courting me specifically it would include link-local addressing and mDNS support.

I'll +1 the HAL as well - I'd love one of these if it were well-designed. Off the top of my head I suggest two interfaces for many peripherals, one interrupt-driven and one DMA-driven. Trying to combine those two things together tends to be where the lack of usefulness of overly-abstracted HALs comes in, IME.

Assuming we had a HAL, a nice collection of drivers for external peripherals using those HAL crates for interfacing would be great. I'm thinking of (say) a CC1101 wireless chip driver using an abstracted SPI HAL crate. This might be somewhat far up the stack for the current discussion, though.

1 Like

I'm a former web / enterprise developer that has switched to working almost 100% on Rust embedded development. There are a number of projects that I've been working on that a few people in the Boston area have seen, and I'm in the middle of a push to clean them up to the point where I'm comfortable publishing them. One big challenge is that @japaric's projects have such a high standard of documentation and user friendliness - I always feel that I have more work to do!

My first project has to do with a command-line tool to improve the build / load / run workflow when interacting with most of the broadly available embedded debuggers and bootloaders such as ST-Link, JLink, Arduino and Teensy - in particular in situations where you may have many devices connected at once and when you want to do automated testing. I'm hoping to have a preliminary public release for OSX in a few weeks, followed by Linux and Windows support soon afterwards.

My other project is a bit broader and has a bit further to go, but has to do with the tooling and work needed to build and maintain HALs (including peripheral drivers) within and across device families, with the goal being a hierarchy of crates comparable to existing vendor-provided SDKs. I currently have about 20 different development boards across six vendor families that I'm writing for, and I'm adding more all the time. My work on the command-line tools is driven in part by the need to build a continuous-integration environment that can support this.

As that progresses, I've also been building a cross-platform networking stack (IPv4 + IPv6, minus TCP for now) and cross-platform device drivers for external peripherals such as sensors and radios. This is all mostly for dogfooding at the moment, but I expect that within a few years there will be an extremely strong Rust ecosystem of well-tested, well-documented, cross-platform embedded drivers built around a core set of traits.

I expect that it will be a long time (10+ years) before much of the existing traditional embedded C / C++ market will consider Rust as a serious alternative - there's deep conservatism and a lot of inertia in the industry. But I see a huge opportunity for Rust both in clean-sheet IoT product development and also where the amount of developer effort needed to produce safety-critical code in C / C++ is really hurting time-to-market.

One of the biggest attractions to me of Rust (besides the core language itself) is the chance to build a true cross-platform, open source embedded ecosystem where you don't have to lock yourself into a single vendor's toolchain and libraries. I think that's something that has to happen so that the embedded industry attract more of the best programming talent, and it's necessary if we want safer and more reliable embedded devices.

8 Likes

Probably a long shot, but is there any chance to have Rust for the PRU, the micro-controllers embedded into TI's Sitara, as found in the BeagleBone Black ?

2 Likes

Answering for myself, but you may choose to read it as being on behalf of other Tock developers and users...

How do you plan to use Rust in your embedded application? Some alternatives:

  • I want to write pure Rust applications
  • I want to write Rust code on top of a C/C++ framework
  • I want to use Rust as a component of a C/C++ application

All three. The primary goal of my use Rust for embedded is that the type system is a much lighter weight isolation primitive relative to process/hardware isolation. So this manifests in various ways. The Tock kernel is entirely in Rust, and it's very important for us to keep it that way. However, in some cases, it seems unavoidable to deal with low-level C (or just precompiled) libraries from chip vendors (we haven't actually run into this yet, but it will be unavoidable in some cases, specifically where NDAs would otherwise be involved). Finally, even in userspace where processes are hardware isolated, I want to use Rust to replace certain bug-prone components (think X.509 serialization/deserialization) or to interact with C-libraries that just won't be replaced anytime soon (think fftw).

And, what's preventing you from using Rust?

Nothing technically (we're using Rust!!), but key priorities for us are:

  • Testing (especially if possible testing without cross-compiling if possible)

  • Stable Rust support (we're unlikely to care in the kernel, but I really want userland Rust processes to be able to use stable)

  • Embedded specific crates ecosystem---this one is hard because I don't want to pollute the namespace with a bunch of tock-some-peripheral crate on crates.io, but getting to totally common interfaces across frameworks seems like it will definitely challenging, and maybe impossible (or undesriable at least).

And if you are using or have used Rust on an embedded system please share your story!

This is longer than should fit in a post, but Rust is essential to the design of Tock OS. The goal of Tock was to update the design of embedded/sensor-network OSs to the constraints of new applications and hardware, and a key missing property was isolation and safety. We really strongly wanted to avoid hardware isolation as the main isolation mechanism (because of the large resource overhead relative to small microcontroller sizes), but most type-safe languages are garbage collected and more or less fundamentally rely on heap allocation, so they are not good options for a low-resource, high reliability embedded system.

So we chose Rust because it was by far the best option. The idea that we're able to build a system like Tock in a reasonably main-stream language was (and still is) incredibly exciting for us.

Since most of the collaborators working on Tock come from the embedded systems world, mostly write in C and don't have much prior knowledge with, e.g., functional languages (I'm meant to be the PL-person in the group, which is kind of a joke), we were a bit concerned about what adoption would look like. But we've been really pleasantly surprised. Contributors who were knew to languages like Rust picked it up very quickly and have reacted really favorably to it. It also has not been a particularly large barrier to adoption outside the core contributors. For whatever reason, people are actually quite excited to learn Rust and seem to pick it up fairly quickly.

For a bit of motivation for others, I've been seeing a lot of excitement from big companies in the industry about Rust in general, but specifically about using it for security in embedded systems. I ended up working on Tock at an internship at Google last summer, and the work there is still on-going (I hope I'll be able to share more details soon, but if you looked at my GitHub history and poked around other open source embedded software projects from Google you be able to make some educated guesses). Both Intel and Analog Devices are (partially) funding our research on Tock, and folks in both of those companies have been really excited about using Rust for low-level systems.

The high bit is that the success of Rust really opens the door to writing low-overhead embedded software that none-the-less has strong safety guarantees.

11 Likes

@whitequark

I know, futures and stuff, but honestly I find Rust's futures impenetrable.

I was wondering what about futures you don't like? The excessive use of
closures and adapters, that you have pass everything by value to not get
yelled at by the borrow checker, or something else?

What approach would you prefer to use for cooperative multitasking? Something
more like coroutines / generators (yield)?

BTW, will you continue working on your port of libfringe to ARM? I'm looking
forward to trying it out on ARM Cortex microcontrollers.

@rayman22201

I'm a hobbyist and a Rust beginner, so probably ignore me

No, no. I listen to everyone who's interested in embedded systems and Rust.

I have a bunch of old esp8266's lying around that I would LOVE to Rustify...

Sadly we can't do much if there's no support for that architecture in LLVM
:-(. Let's hope that it will happen someday.

@jeko

Thank you!

What I like is to have a minimal environment (vim, cli) to write, compile,
test and load my apps.

You are covered; that's how I like to do my development.

@SimonSapin

I think the lesson is that panics in embedded contexts are much more
problematic than in other contexts

nods I routinely check that the generated code (when compiled in release mode)
is free of calls to rust_begin_unwind, and thus free of panics. If not I trace
it down and see what's causing it. I sometimes find contract violations
(assert!s hit due to programmer error), and sometimes LLVM needs some help to
optimize away panics.

Perhaps another library could provide something like ..

Yeah that sounds reasonable. I didn't realize you could create trait objects in
static context. Nice! We could use a symbol to achieve dependency inversion:

// in e.g. cortex-m crate
macro_rules! eprint {
    (..) => {
        extern "C" {
            __STDERR__: Mutex<Option<&'static fmt::Write>>;
        }

        unsafe { /* use __STDERR__ here */ }
    }
}

macro_rules! set_stderr {
    ($STDERR:expr) => {
        #[used]
        #[no_mangle]
        static __STDERR__: Mutex<Option<&'static fmt::Write>> = Mutex::new(Some(&$STDERR))
    }
}

then in the application crate:

struct Serial { .. }
impl fmt::Write for Serial { .. }
static SERIAL: Serial = Serial::new();

set_stderr!(SERIAL);

do_thing().unwrap_or_else(|| eprintln!("something went wrong"));

The set_stderr! macro is there to make sure that what will become the
__STDERR__ symbol has the right type. Perhaps the type of __STDERR__ can
just be Option<&'static fmt::Write + Sync>? I think that could also work and
wouldn't need to depend on the Mutex type.

But please if we do this let's make it clear that libraries should not
implicitly be using eprint! in their implementation, unless they do that in a
way that can be disabled via some Cargo feature. Some applications are time
critical and can't afford this kind of logging. Libraries should be returning
Results to indicate error conditions.

@therealjpster (Sorry, I think I cc-ed the fake @thejpster :laughing:)

in the form of discrete crates, like embedded-serial with Windows/Linux/Mac
support

With Linux support; that's an interesting requirement. You want to be able to
test the logic of embedded applications on Linux?

You can add the TI Stellaris Launchpad / Tiva-C Launchpad to your list of
supported hardware

Sorry, I forgot about that one. I think we should have a list of supported
hardware in the rust-embedded/rfcs issue tracker. At least until we get a proper
website.

@Razican

Amazing to see money invested in embedded Rust development, that's why I'm
also a patron

:heart:

If I have a Rpi, what do I need to create a target specification?

You can start from the ARM Linux one: rustc -Z unstable-options --print target-spec-json --target armv7-unknown-linux-gnueabihf (needs nightly). I
don't think you'll have to change too many things: probably just set os to
none and env to eabihf

I want bare metal

The RPi, having a Cortex-A processor, is a very different animal from Cortex-M
microcontrollers. The boot process is more complicated; you'll have to deal with
the MMU; etc. I can't give you too many pointers; the folks at #rust-osdev
probably know the processor better than I as some of them probably have
developed general purpose OSes for ARM.

but the main problem I see is that all embedded tools/tutorials assume you
know about embedded development

I hope the Discovery book helps you with that :slight_smile:

@Michael-F-Bryan

I want to use Rust as a component of a C/C++ application.

We don't have many examples of that I think. Less so in the embedded space.

TL; DR: ..

I agree. Documentation is key.

@jolson

Rust doesn't support my target device architectures, in my case AVR and older
ARM (pre Cortex).

AVR support is on the works. I hope to produce material on that once the AVR backend is
merged into rustc because, currently, the entry bar (a custom rustc) is too high
for all of us.

By pre Cortex ARM do you mean ARMv5 processors that run embedded Linux? I got an
e-mail asking about support for that this week. I should probably an issue about
that if there's more than one person interested in it.

@creationix

The Padi board has a RTL8710 chip in it, right? I think I have one of those
chips sitting in my drawer.

I could then help write the docs and IDEs, libraries, etc to build a rust
maker community to rival esp8266.

Are you volunteering? :slight_smile: (I already wrote down your name)

What I find frustrating about the RTL chip is that there seems to be zero
documentation about it: No description of the registers, no SVD files, no
reference manual, no open source code. You have no choice but to use their SDK.

3 Likes