Crate sfsm[][src]

Expand description

Static finite state machine

Sfsm tries to achieve these objectives, by providing a state machine generator in sfsm-proc and a transition as well as state trait in sfsm-proc. With this, the user can specify the whole state machine on a few lines that are easy to review. From this definition, the whole state machine can be generated without relying on dynamic mechanisms and thus allows to be fully static. All that is left to do, is to implement the states and transition necessary to fulfill the Transition and State traits.

State machines are an essential part of many software architectures and are particularly common on low level systems such as embedded systems. They allow a complicated system to be broken down into many small states with clearly defined transitions between each other. But while they help to break down complexity, they must also be well documented to be understandable.

Rust is well suited to implementing state machines thanks the way its enums are designed. Unfortunately this still comes with a large amount of boilerplate.

Sfsm aims to let the user implement simple, efficient and easy to review state machines that are usable on embedded systems. The main objectives therefore are:

The main objectives therefore are:

  • no_std compatibility
  • Self documenting
  • Easy to use
  • Low cost

Sfsm tries to achieve these objectives by providing a state machine generator in sfsm-proc and a transition as well as state trait in sfsm-proc. With this, the user can specify the whole state machine on a few lines that are easy to review. From this definition, the whole state machine can be generated without relying on dynamic mechanisms and thus allows to be fully static. All that is left to do is to implement the states and transition necessary to fulfill the Transition and State traits.

Example usage

A state machine can be defined with the following macro call.

add_state_machine!(
     Rocket,                                   // Name of the state machine. Accepts a visibility modifier.
     Grounded,                                 // The initial state the state machine will start in
     [Grounded, MoveUp],                       // All possible states
     [
         Grounded => MoveUp,                   // All transitions
     ]
 );

This will define a state machine called Rocket with an initial state in Grounded. There are two possible states the state machine will be in. Grounded and MoveUp. Grounded is the initial state and can transit to MoveUp due to the Grounded => MoveUp transition defined. A state machine can have as many states and transitions as desired but all of they must implement the State and the according Transition traits. Additionally, messages to be passed into, or polled from the states can be defined.

add_messages!(
     Rocket,
     [
         StartLiftoff -> Grounded,               // Command the CountDownToLiftoff state to liftoff
         Status <- Liftoff,                      // Poll the status of the lift
     ]
 );

This creates the code to pass StartLiftoff into the Grounded state and allows to poll Status from the Liftoff state. Each state can have multiple receive and return messages, but it must implement the according ReturnMessage and ReceiveMessage traits. For more information, take a look at the examples or at the doc.

Modules

Macros

Generates code to push messages into states or poll messages from states.

Generates a state machine from a given state machine definition.

Generate the enum entry of a state. Expects the name of the sfsm and the name (and type args) of the state as well as the desired name of the variable to work with as arguments. Can be used to generate match branches for example.

Enums

Error type that will be returned if an error during the message polling or pushing occurred. It will indicate what the cause for the error was and return the original message in the push case.

An error type that will be returned by the state machine if something goes wrong. Specifically, when the state machine gets stuck in a state due to an internal error. The state machine is designed in a way where this should not happen, so this can largely be ignored. It is used in situations that are other wise hard to avoid without a panic!. It might be extended in the future to contains custom error codes generated from the states themselves

Enum used to indicate to the guard function if the transition should transit to the next state or remain in the current one.

Traits

An implementation of this trait will be implemented for the state machine for every state. This allows to test if the state machine is in the given state.

The PollMessage trait implementation will be generated by the add_message! macro and is used to return messages from states.

The PushMessage trait implementation will be generated by the add_message! macro and is used to send messages into the state machine where they will then be forwarded to the correct state.

Allows a state to declare that it can receive a message. Note: for the state to actually be able to receive a message, the message has to be added with the add_message! macro

Allows a state to declare that it can return a message. Note: for the state to actually be able to receive a message, the message has to be added with the add_message! macro

Trait that must be implemented by all states

Trait that must be implemented by a state that want to transition to DestinationState.