This is a collection of things that are not yet awesome in Embedded Rust. We need your help to capture all of the things that are not yet awesome, and to start making them awesome!
This project is developed and maintained by the Resources team.
Are you interested in:
- Adding something to this list that is not yet awesome?
- Tell people you are working on making something on this list awesome?
- Tell people you have made something on this list awesome already?
Check out our Contributing Guide for how to get started.
And don't forget to check our Awesome Embedded Rust list! The thing you are looking for may already exist!
- Useful Links
- Not Yet Awesome List
Currently, it is not convenient to share non-atomic or non-Sync
data with an interrupt using safe Rust. Because interrupt handlers are functions that take no arguments, all data consumed by interrupts must either be global or module scoped Atomics (e.g. AtomicBool
), local static
variables, or global or module scoped static
variables.
Global variables are not great in Rust, because:
- All mutable access (of non-
Sync
/Atomic
data) must beunsafe
- Not all data can be initialized in a
const
context, so it's often necessary to use anOption<T>
to delay the initialization to runtime - Global variables aren't typically idiomatic Rust.
Frameworks like cortex-m-rtic achieve this in a zero cost fashion by using a Domain Specific Language to automatically provide safe access to shared resources between tasks and interrupts, however these tools can not be used by applications not using RTIC, or by libraries such as HAL or BSP crates.
Useful Links
- wg#294 - An Embedded-WG issue discussing this topic
- bare-metal#15 - One proposed solution hiding the un-idiomatic syntax
Ideally, we would be able to support all of the following use cases:
- Sharing a variable between the main thread and only one interrupt handler
- Sharing a variable between the main thread and one or more interrupt handlers
- Moving a variable from the main thread to one interrupt handler
We should be able to serve the three use cases listed above, while:
- Using only safe Rust (at least as a user of the library)
- Add only minimal overhead, if not "zero cost"
For embedded systems that send or receive data to other devices, or who read/write data to a medium such as an SD card or other Flash memory, it is useful to have automatic serialization and deserialization support to turn structured data into a binary format.
While tools like serde
are widely used in Rust (and already support no_std
), few of the the backends (like serde_json
) are supported in a no_std
environment.
We should be able to serialize and deserialize data in an automatic way, either using a frontend like serde
, or with a simple and convenient serialize
and deserialize
method. To use these, we should not need heap allocations, and it should be possible to detect when serialization and deserialization have failed.
Additionally, all common datatypes used in embedded Rust should be supported, as well as a (preferrably automatic) way to add support for custom data types. Common data types include:
- Fixed point signed/unsigned numbers like
u8..u64
ori8..i64
- Floating point numbers like
f32..f64
- Booleans
- Variable length types, like
[u8]
and&str
- Tuples
- Enumerated types
We should also have support for different ways of serializing data, primarily:
- Self-describing schemas, such as JSON or CBOR
- Non-self-describing schemas, such as binary packed data or ProtoBufs
serde
already has support forno_std
environments, when using a feature flag- Serde welcomes contributions
ssmarshal
has support for basic types, but does not support enums with more than 255 variants, or variable sized types like slices. This covers only the non-self-describing use case.- ssmarshal welcomes contributions
ujson
supports JSON serialization and deserialization forno_std
environments, but is experimental (and not on crates.io), and is unlikely to be stabilized as-is- It is unknown if ujson welcomes contributions
- There are a number of forks of
std
-onlyserde
backends, though they do not seem to have official support from the upstream libraries. These forks include:
The USB standard has a fair bit of commonality between USB Devices (like Mice, Printers, and Webcams) and USB Hosts (like Laptops and Raspberry Pis), but each specific microcontroller has a slightly different implementation of the USB Controller at the bottom of the stack. It would make bringing up a USB stack on a new chip much easier if there was a #[no_std]
crate which defined some common traits, enumerations and structures at the bottom, and then provided support for various device classes above that.
I'd like to be able to implement USB Host and USB Device support on the Texas Instruments Tiva-C line and the STM32F4 line by only implementing a thin shim around each device's USB OTG Controller registers. The USB Host should be able to handle a USB Keyboard and the USB Device should enumerate as a Communications Class Device (two of the most common use-cases).
- The tm4c123x-hal crate has svd2rust definitions for the USB controller's registers.
- There is a branch looking at adding USB Host support.
- usb-device crate and corresponding device-specific implementations for STM32:
- stm32-usbd (USBFS peripheral in F0, F1, F3, L0, L4 families)
- synopsys-usb-otg (OTG peripheral in F1, F4, F7, H7 families)
- usbd-serial crate implements USB CDC for serial communication.
- usbd-hid crate implements USB HID, providing a way to implement keyboard and mouse drivers on top of it.
- usbd-human-interface-device crate implements various keyboards, mice and consumer control devices on top of
usb-device
- Keyberon project uses
usb-device
to implement its own HID support for USB keyboard firmware. This project usually serves as a starting point for those willing to implement their own USB keyboard firmware.
So far there seem to be no libraries to do anything with displays or gui's. However in C some libraries have already been written. Rust could interface with these libraries if bindings were made.
- https://github.com/rust-lang/rust-bindgen to help out making bindings
- LittlevGL, an Open-source Embedded GUI Library written in C.
- GuiLite, a small GUI library of 5000 lines of C++ code that runs on all platforms, including MCU's.
Bindings to C libraries or a Rust library that is meant for Displays and/or GUIs.
- Rafael Carício is working on lvgl-rs, which are safe bindings for Rust to use LittlevGL (see also the annoucement on the LVGL forums). LVGL can now also compile to WASM thanks to Rust.
There is a large amount of accessible libraries and projects involving the esp32-cam in c++, and a few projects for rust using esp-idf-std (listed below), however there are no no_std crates with this support. A repository of information, including pin defintions, can be found (here)[https://github.com/raphaelbs/esp32-cam-ai-thinker/blob/master/docs/esp32cam-pin-notes.md].
A library with bindings to the esp32-cam camera, accessible in a no_std environment.
- The ChenHuaYou/esp-cam-rs and Jlocash/esp-camera-rs repositories support esp32-cam using esp-idf-std bindings.
Here's an example for something that is not yet awesome:
IETF RFC -1 states that you should be able to Foo with either a Bar, Bib, Bim, or Bap. However in all of these rust crates, you're required to have a Bar!
I'd like to be able to Foo using only a Bib, Bim, or Bap.
- The foobar crate has Issue #1337 open to add support for Foo-ing with a Bim or Bap.
- The
foobar
crate is on on github - They are looking for contributors (see issue #1338)
- They have a Code of Conduct
- The
The Not Yet Awesome Embedded Rust list (this project) is distributed under the terms of the Creative Commons CC-BY-SA v4.0 license.
Copies of the license used by this project may also be found here: CC-BY-SA v4.0 Hosted.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be licensed as above, without any additional terms or conditions.
Contribution to this crate is organized under the terms of the Rust Code of Conduct, the maintainers of this crate, the Resources team, promises to intervene to uphold that code of conduct.