These sections explain some concepts of Drogue Device.
An actor system is a framework that allows for isolating state within narrow contexts, making it easier to reason about system. Within a actor system, the primary component is an Actor, which represents the boundary of state usage. Each actor has exclusive access to its own state and only communicates with other actors through message-passing.
Each actor is single-threaded, able to process a single message at a time, allowing for lock-free processing of each event. As embedded processors are globally single-threaded, supporting multiple actors requires the usage of
.await within the Rust ecosystem. Each actor can therefore process each message either synchronously if its logic is non-blocking or using an
async block if complex processing is required.
Each event is fully processed, in the order in which it is received, before the next event is considered.
While processing an event, an actor may send a message to another actor, which itself is an asynchronous action, allowing the system to continue to make progress with actors that are able to.
All messages are sent using async channels attached to each actor. The channel depth is configurable based on const generics.
Each actor within the system has its own unique
Address which is used to communicate with the actor (through it’s FIFO).
There is an async
request(msg) method on each address to send a message asynchronously to the actor, which may only be used from another
async context, as the sender must
.await the response. There is also a sync
notify(msg) method on each address to send a message without awaiting a response.
Address for a given actor may expose additional async methods or wrap an
Address to facility fluent APIs for communicating with the underlying actor. For instance, the
Socket type wraps an
Address for actors that implement the
Each actor is wrapped in a state object which is executed by the embassy runtime. When each state is
mount(…)`ed into the system, its `Address<…> is made available.
Each Actor in the system defines the configuration it expects to get handed in its
Device struct created by the application writer, maintain members for each actor. A static instance of
DeviceContext is created to hold a static reference to the
The application entry point is specified using a function marked with
#[embassy::main], and it will be passed a
Spawner that is used when mounting actors and packages.