web developer & system programmer

coder . cl

ramblings and thoughts on programming...


generalized state machines

published: 03-08-2012 / updated: 07-08-2012
posted in: c, c++, development, programming, projects, proview, tips
by Daniel Molina Wegener

Defining state machines is not so hard as it appears. Initially you can build constructs that can help on building automata processing much friendly than using plain code. Starting from the idea that you can place your state machine inside data structures allowing friendly editing without modifying the processing code. Any stateful processing can be migrated to state machines. As any automata can be represented in a state diagram and then it can be migrated to plain data structures. Even if you are using a purely functional programming language, you can place a stateful processing data structure to be processed as automata.

On a recent project, the project manager has requested to me to code a state machine. Its initial design is not generalized. Along two design sessions and some sample code and constructs I think that I have finally made an abstract state machine, with various reductions, based on the model designed by the project manager on the design sessions, structured mostly as automaton, with very simple state transitions, but I have added error and wait conditions, allowing more friendly error processing and wait events. Mainly because as ProView application it has several similarities to PLC programs, where each cycle can operate one time due to the protocol restrictions, but also it allows multiple operations in one cycle because it can send larger packages with multiple requests.

Generalized State Machine

Generalized State Machine

On each cycle, once the I/O layer is initialized, the device error state is checked, on failure it reports errors using ProView alarms, waits the next cycle and then operates again checking the device state. If no error is detected, it operates immediately once it can do it according to its cycle. And the state machine above is a generalized or abstract state machine, considering CST and OST as checking and operating states, where it is has a normalized transition between both states with the proper error handling states.


typedef struct fcu_sm_trans_s fcu_sm_trans_t;

struct fcu_sm_trans_s {
    fcu_op_state cst;
    fcu_op_state nst;
    fcu_op_state fst;
    bool alarm;
    bool wait;
};

/* pump and valve transtion table */
fcu_sm_trans_t AUTO_FCU_TRANSITION[] = {
    { FCU_ST_OFFLINE             , FCU_ST_DISCONNECTED      , FCU_ST_OFFLINE      , false, wait  }
    , { FCU_ST_DISCONNECTED      , FCU_ST_COPY_READ_POS_P   , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_READ_POS_P   , FCU_ST_COPY_WRITE_POS_P  , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_WRITE_POS_P  , FCU_ST_COPY_READ_POS_V   , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_READ_POS_V   , FCU_ST_COPY_WRITE_POS_V  , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_WRITE_POS_V  , FCU_ST_READ_POS_P        , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_POS_V        , FCU_ST_READ_POS_V        , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_POS_V        , FCU_ST_READ_BURN         , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_BURN         , FCU_ST_READ_PRES         , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_PRES         , FCU_ST_WRITE_POS_P       , FCU_ST_ERROR        , true , false }
    , { FCU_ST_WRITE_POS_P       , FCU_ST_WRITE_POS_V       , FCU_ST_ERROR        , true , false }
    , { FCU_ST_WRITE_POS_V       , FCU_ST_READ_POS_P        , FCU_ST_ERROR        , true , true  }
    , { FCU_ST_ERROR             , FCU_ST_OFFLINE           , FCU_ST_ERROR        , true , true  }
};

And here you have sample transition table for one the controlled devices — which is not the final transition table, because we still do not have the final model implemented, but we have the proper abstraction to implement it — with error handling and wait conditions. The model is very similar to functional guards, where there are some conditions checked, including the error condition, and then the state is processed passing to the next state in the next cycle. Seems that the original model for this kind of processing is present in this paper, and seems that it is fully meeting an IPO model.


No coments yet.

post a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>