There are already some embedded rust projects such as tock-os or zync-rs. They all (AFAIK) took the path to a monolithic API in that sense that everything is provided as a single (potentially) heavy crate where all ports and their drivers are provided in the same crate.

A single dependency to all your projects can look appealing, but it has downsides that (IMHO) are making it unworthy. It greatly impairs maintainability and slows down the release pace because it makes the crate heavier (in features/targets) :

Decoupling

Splitting the framework in a “galaxy” of light weight crates allows adoption of updates of the main APIs to be propagated in some sort of waterfall kind of way. A team responsible of maintaining a certain set of target can use the semantic versioning to only update their release when they are ready. It adds latency between the main API & the target implementation updates but it prevents :

This would also help :

This diagram is here to give you a rough idea of what could be achieved. This would of course be extended by more crates dedicated to others tasks such has file system drivers, motor/sensor control (loops?)…

kind of UML diagram

For example here is how things could be spread :

Features

Rust’s Features are a nice & clean replacement for what used to be done with #define in C.
They could be used to select a specific implementation of a given feature.
The most obvious use case that comes to my mind is a bootloader application requiring that ‘no-os’ is provided to get the smallest footprint possible while another app would require a full featured ‘RTOS’ with system calls, os aware synchronisation primitive implementations primitives. Both apps would depend on the same target crate (e.g. silica_arduino_mega2560) but with slightly different implementations.


  1. silica-rs is something I initiated few years ago. It is inspired by something I realized with Makefiles & C in my first company. I wanted a framework that is target, os, ip stack […] agnostic.