Wednesday 7 December 2016

State Machine Implementation Using Function Pointers

STATE Machine Implementation Using Function Pointer

In last blog we have discussed about state machines and implementation of state machine using Switch. State machine can be implemented using function pointer. Using function pointer it is easy to implement state a system with large no of states and complex code associated with each state.
We will take the same example of state machine that we have implemented in last blog. This time we will understand how to implement state machine using function pointers. 
 State Machine Diagram will be as shown in figure below:


In first step first we generate a enumeration of each main state and Sub State named as MAIN_STATE and SUB_STATE.

typedef enum {STATE1,STATE2,STATE3,STATE4} MAIN_STATE;
typedef enum {N0_SUB_STATE,SUB_STATE1, SUB_STATE2} SUB_STATE;

Next step will be storing the current Main State and Current Sub State.

MAIN_STATE CURRENT_STATE = STATE1;
SUB_STATE  CURRENT_SUB_STATE=N0_SUB_STATE;
MAIN_STATE NEXT_STATE;

I next step we will define the structure of state machine of Main State Machine and Sub State Machine. This structure will hold the function pointer associated to main State and Sub State.

typedef struct {
    void (*MAIN_STATE_FUCTIONS)(void);
                } MAIN_STATE_MACHINE;
               
       typedef struct {
    void (*SUB_STATE_FUCTIONS)(void);
                } STATE1_SUBSTATE_MACHINE;

Next Step Will be Function Declaration of associated with Step:

void STATE1_FUNC(void);
void STATE2_FUNC(void);
void STATE3_FUNC(void);
void STATE4_FUNC(void);
void SUB_STATE11_FUNC(void);
void SUB_STATE12_FUNC(void);

After this we will declare an array of MAIN_STATE_MACHINE  and STATE1_SUBSTATE_MACHINE Structure. This structure will contain the function for each Main State and Sub State.

  MAIN_STATE_MACHINE MAIN_STATE_MACHINE_ARRAY[]=
                                          {
                                            STATE1_FUNC,
                                            STATE2_FUNC,
                                            STATE3_FUNC,
                                            STATE4_FUNC
                                          };

  STATE1_SUBSTATE_MACHINE STATE1_SUBSTATE_MACHINE_ARRAY[]=
                {
                                                                                        SUB_STATE11_FUNC,
                                                                                        SUB_STATE12_FUNC
                };

/**********Function definition***************/
void STATE1_FUNC(void)
{
      //Function Code
     if (CURRENT_SUB_STATE!=N0_SUB_STATE)
      (*STATE1_SUBSTATE_MACHINE_ARRAY[CURRENT_SUB_STATE-1].SUB_STATE_FUCTIONS)();
// SUB STATE Function Call By Function Pointer
     else if (NEXT_STATE==STATE3)
            CURRENT_STATE = STATE2;
        else
                CURRENT_STATE = STATE2;
}
void STATE2_FUNC(void)
{
        //Function Code
    if (NEXT_STATE==STATE4)
        CURRENT_STATE=STATE4;
    else
         CURRENT_STATE=STATE3;
}
void STATE3_FUNC(void)
{
        //Function Code
    CURRENT_STATE=STATE4;
}
void STATE4_FUNC(void)
{
        //Function Code
      CURRENT_STATE=STATE1;
}
void SUB_STATE11_FUNC(void)
{
    //Function Code
    CURRENT_STATE=STATE2;
}
void SUB_STATE12_FUNC(void)
{
     //Function Code
        CURRENT_STATE=STATE1;
}
In main routine we will call state function using Function Pointer. To call function we point to the function pointer store  in the MAIN_STATE_MACHINE_ARRAY.
       (*MAIN_STATE_MACHINE_ARRAY[CURRENT_STATE].MAIN_STATE_FUCTIONS)();

Same procedure can be follow for using complex large number of STATES and Sub states.

No comments:

Post a Comment