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 ostensibly single-threaded, able to process a single message at a time, allowing for lock-free processing of each event.
As embedded processors are ostensibly 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
heapless. Once const generics is used by heapless, we will
make the move as well.
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
send(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.
Address for a given actor may expose additional async methods to facility fluent APIs for communicating with the underlying actor.
For instance, the
Address<SimpleLED<…>> instance has a
turn_off() pair of methods for manipulating the underlying LED.
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
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.