This example demonstrate a simple state machine of a process as shown below.
-
Idle state
This state waits for the Start event to occur. On Start event, it starts the process for defined period and switch to Active state. -
Active state
This state supports Stop, Pause and Timeout events.
- The stop event causes the process to stop and return to idle state.
- The Pause event causes the process to pause and switch to Paused state.
- When process period elapses it triggers the Timeout event. The Timeout event causes the process to stop and return to idle state.
- Paused state
This state supports Resume and Stop events.
- The Resume event causes the process to resume and returns to active state.
- The Stop event causes the process to stop and switch to Idle state.
- Start
- Stop
- Pause
- Resume
- Timeout
process.c and process.h files contains an implementation of demo state machine.
- Compiler configuration
- Define
HSM_CONFIG
in the compiler preprocessor (-D option) to include hsm_config.h file. - Provide the
hsm_config.h
andhsm.h
file path in the compiler include path option (-I).
- Disable hierarchical state machine support by setting
HIERARCHICAL_STATES
to 0. - Set
STATE_MACHINE_LOGGER
to 1 to enable logging of state machine for debug purpose.
Define the list of supported events as enumeration in the header file of your state machine process.h
.
event value must be non-zero. Hence initialize the first enum value to 1.
//! List of process events
typedef enum
{
START = 1,
STOP,
PAUSE,
RESUME,
TIMEOUT,
}process_event_t;
Create a structure derived from the state_machine_t
that contains all the required variables for your state machine.
//! process state machine
typedef struct
{
state_machine_t; //!< Abstract state machine
uint32_t Set_Time; //! Set time of a process
uint32_t Resume_Time; //!< Remaining time when the process is paused
uint32_t Timer; //!< Process timer
}process_t;
Make sure that state_machine_t
must be the first element in the derived structure.
Define the list of states as enumeration in the source file of state machine process.c
.
//! List of states the process state machine
typedef enum
{
IDLE_STATE,
ACTIVE_STATE,
PAUSE_STATE
}process_state_t;
Create a structure of states and initialize it with handlers.
static const state_t Process_States[] =
{
[IDLE_STATE].Handler = idle_handler,
[IDLE_STATE].Entry = idle_entry_handler,
[IDLE_STATE].Exit = idle_exit_handler,
[IDLE_STATE].Id = IDLE_STATE,
[ACTIVE_STATE].Handler = active_handler,
[ACTIVE_STATE].Entry = active_entry_handler,
[ACTIVE_STATE].Exit = active_exit_handler,
[ACTIVE_STATE].Id = ACTIVE_STATE,
[PAUSE_STATE].Handler = paused_handler,
[PAUSE_STATE].Entry = paused_entry_handler,
[PAUSE_STATE].Exit = paused_exit_handler,
[PAUSE_STATE].Id = PAUSE_STATE,
};
each state has function pointers to its event handler, entry and exit actions.
If logger is enabled, then initialize the Id with respective state enum process_state_t
as unique id.
The event handler must be initialized for each state.
the entry and exit actions are optional, if not required then can be initialized as NULL.
Define event handler, entry and exit action's based on following function signature
typedef state_machine_result_t (*state_handler) (state_machine_t* const state);
If handler supports the passed event then consume the event and return status as EVENT_HANDLED
.
Use switch_state
for the event that triggers state transition.
If handler doesn't support the passed event then return result as EVENT_UN_HANDLED
.
If the handler consumes the event and generates the new event then return the status as TRIGGERED_TO_SELF
.