I have a statemachine in a real-time system with very few (3) states.
typedef enum {
STATE1,
STATE2,
STATE3
} state_t;
However, the transitions between those states need considerable time and have their own subdivisions. So I have two choices, either I extend the main statemachine such that all the intermediate states are represented:
typedef enum {
STATE1,
STATE1_PREPARE_TRANSITION_TO_STATE2,
STATE1_DO_TRANSITION_TO_STATE2,
STATE1_PREPARE_TRANSITION_TO_STATE3,
STATE1_DO_TRANSITION_TO_STATE3,
STATE2,
...
} state_t;
or I create a nested statemachine for the relevant main states:
typedef enum {
STATE1_NOT_ACTIVE,
STATE1_NORMAL,
STATE1_PREPARE_TRANSITION_TO_STATE2,
STATE1_DO_TRANSITION_TO_STATE2,
STATE1_PREPARE_TRANSITION_TO_STATE3,
STATE1_DO_TRANSITION_TO_STATE3
} sub_state1_t;
...
Both possibilities have their advantages and drawbacks. The big statemachine gets messy and complicated very easily. However, having all the states consistent in the second case isn't trivial either and many functions would need information about both the global state and the substates.
I'd like to avoid complicated code which has to handle several parallel states, like:
if ((global_state == STATE1) &&
(sub_state_1 == STATE1_DO_TRANSITION_TO_STATE2))
{
...
if (transition_xy_done(...))
{
global_state = STATE2;
sub_state_1 = STATE1_NOT_ACTIVE;
sub_state_2 = STATE2_NORMAL;
}
}
What is the general best approach for such a problem: many small and nested statemachines (with many invalid combinations), one big statemachine or anything else?