Rust bindings to nrf52 series

In mid-2017, I came across this project by James Munns. It essentially wraps the C SDK for nRF52 development boards, and provides bindings that can be called from Rust. James gave a talk to the Rust DC Meetup, remotely over video conference. This talk inspired me to buy a couple of nRF52 dev boards.

I'd like to announce that here, in Nordic's official channels, because I'd like more embedded developers to become aware of it. Rust is a language that has the ability to compile down to native code with zero runtime, and no operating system. In other words, Rust can run on bare metal hardware. Today.

My ultimate dream is for hardware manufacturers themselves to provide official support. My understanding is that supporting Rust will be much more akin to supporting C, and not really like providing a special runtime for embedded Python or JavaScript.

Some challenges we will face (you can help!):

  1. We do not have a clear path for upgrading our Nordic SDK. We simply check in the C code, and there's some manual work around collecting all the headers for input to code generation.
  2. Speaking of code generation, bindgen, the tool that takes C header files and generates rust types, has been evolving rapidly. On one occasion the changes to generated code caused breaking changes in our nrf52 bindings library.
  3. We have a few examples to test blinking lights and connecting via bluetooth, but perhaps we might benefit from a more structured list of things to test to ensure we provide working bindings to the whole nrf52 dev kit.
  4. Related to 3, just kick the tires and open issues if you need help!

If you are interested, here are some links to learn more:

Here is a link to the GitHub repository

Here is a link to the full video recording of the DC Meetup talk. It offers a detailed overview of our embedded development workflow.

Finally, here is a recent talk about using "unsafe" code in Rust. This is relevant, because in the embedded context a lot of code involves usage of the unsafe keyword. This talk explains why that's necessary and not as scary as it sounds.

  • If you want to work on 30 year old code then I highly recommend sticking to C. Lots of job security and plenty of bugs to fix for decades to come.

    30 years ago I wrote BASIC. 25 years ago I wrote C+BASIC. 20 years ago I wrote C+C++, 15 years ago I wrote PHP+C++, 10 years ago I wrote Ruby+C++, 5 years ago I wrote Javascript+C++, today I write Rust+Elixir.

  • Manufacturer support? Ha! C++ has been a far better choice for embedded code for a very long time, but the industry still insists on C. I use C++ exclusively on Çortex-M devices, and have benefited greatly in terms of development time, reliability, readability, maintainability, and so on. Rust is interesting, but immature. C programmers can segue into C++ much more easily and gain essentially all the same benefits.

  • I was about to post in the forums asking for Rust support and found this. Let me add a data point: there are (many) of us who, while writing lots of code in C, appreciate recent advancements and would *love* to switch to Rust, at least for some of the code.

  • Great to see, that already someone started this. I thought about doing something like this when I took a first look at rust some years ago (I think I even tested something on a STM32). I hope I can find some time in the future to contribute to this - until then - good luck and thumbs up! ;-)

  • Rust targets the LLVM, which is the compilation toolchain used for industry standard languages such as C++, Obj-C and Swift and is very mature + highly optimized at this point, with support from companies such as Microsoft, Apple, etc.

    Rust ensures zero-cost abstractions, pattern matching, memory safety (no dangling pointers, etc), at compile time rather than at run-time.

    Rust's procedural macro system is much more powerful than C macros, and enables you to create things like "futures" which can abstract away things like manually coded state machines. The closest thing in C I've found are "protothreads" which are still not "zero-cost".

    If you need to drop down to manual memory manipulation and ignore Rust's safety guarantees around memory and data races, they provide an escape hatch keyword called "unsafe", which doesn't tend to need to be used.

    I do agree, the tooling around Rust on the embedded side needs improvement, and James Munns's wrapper around the nRF52 SDK needs another layer to abstract the unsafe calls, but I'd be very happy to use Rust to create useful libraries which I'd call into from C at this point, just not as the application level code as well. I've been experimenting with calling into cbindgen to build a no-std library to integrate with C code as Rust has a very good FFI thanks to it's lack of a runtime.