FSM on the C language and Detailed

Recently there is a demand for a project, consider for a moment the decision to use a state machine to achieve after completion demand, had mixed feelings, the state machine to implement the very edge processing logic above, but also easy to manage.

Here I share the modified state machine. Changes in few places, refer to the " C language optimized state machine specification - the speculators '

And realization of the same author, the state machine jumps achieved through a function pointer, the function implements the relevant state entry into an array, in order to facilitate maintenance, the array index variable corresponds taken enumeration.

As long as indexed sequential array of function pointers and a corresponding enumeration, the function returns a state status, to read the last state in the main function, the state machine can be completed.

In order to facilitate control and external calls, I introduced into the data field of a dedicated recording state (ST), stored for the current state and the next state, also leads to a state machine can be reset interface;

 

Here is what I realized, when using the easiest method is to modify the header file step_ * function, as well as an array of Steps and states. High point After 2 can be drawn out, it is achieved by way of the external parameter passing.

/*
# File    :   fsm.h
# Author: toujizhe, schips
# Git     :   https://gitee.com/schips/
# Ref     :   https://www.cnblogs.com/toujizhe/articles/5473489.html
# Date    :   2016-05-09 12:20, 2019-05-20 13:14:52  
# Describe:     
              It can be reset to a state machine, in accordance with improvement of the source ref
              In theory, the state machine can be set to any state,
              But only now reset to initialize the state of the interface.
*/
#ifndef __FSM_H_
#define __FSM_H_
 / * ----------------------- Defines --------------------- --------------------- * / 
// data type definition area 
typedef unsigned char State;
typedef State(*Procedure)(void *);
typedef struct _SM_STATE {
    CS State;        // current state 
    State NS;        // next state 
} SM_STATE;

typedef struct _SM_VALUE {
     // custom data structure 
    int CNT;
} SM_VALUE;

// state machine parameters 
typedef struct _SM_VAR {
     // current state and next state 
    SM_STATE st;

    // state machine data area 
    SM_VALUE var ;
} SM_ARG;

/* ----------------------- Static functions ---------------------------------*/

static inline void SetNextState(void*arg, State st);
static inline void EmyptData(void *arg);
static inline State step_init(void * arg);
static inline State step_count(void * arg);//计数
static inline State step_done(void * arg);//计数完成
static inline State step_default(void * arg);//错误过程

// state definition (where the order request [] is consistent with Steps) 
enum States {s_init, s_count, s_done, s_default};
 // function pointer (equivalent function entry) 
static Procedure Steps [] = {step_init, STEP_COUNT, step_done, step_default};


/* ----------------------- Start implementation -----------------------------*/
static inline void SetNextState(void*arg, State st)
{
    SM_ARG * p = (SM_ARG * ) arg;
    p->st.ns = st;
}

static inline void EmyptData(void *arg)
{
    SM_ARG * p = (SM_ARG * ) arg;
    p -> was .cnt = 0 ;
}

// initialize 
static inline State step_init ( void * Arg)
{
    SM_ARG * p = (SM_ARG * ) arg;

    // state processing 
    SetNextState (arg, s_count);

    // data processing 
    EmyptData (arg);

    return p->st.ns;
}

// normal operation 
static inline State STEP_COUNT ( void * Arg) // count 
{
    SM_ARG * p = (SM_ARG * ) arg;
    if (p-> was .cnt < 3 )
    {
        p -> was .cnt ++ ;
        SetNextState(arg, s_count);
    }
    else
    {
        SetNextState(arg, s_done);
    }

    return p->st.ns;
}

// task completion 
static inline State step_done ( void * Arg) // count is completed 
{
    SM_ARG * p = (SM_ARG * ) arg;

    // resident 
    SetNextState (Arg, s_done);
     // can be allowed to jump to the required s_init 
    return p-> st.ns;
}

static inline step_default State ( void * Arg) // error process 
{
    SM_ARG * p = (SM_ARG * ) arg;
    SetNextState(arg, s_done);
    return p->st.ns;
}


// reset to the initial condition 
static inline void ResetStateMachine ( void * Arg)
{
    SM_ARG * p = (SM_ARG * ) arg;
    p->st.ns = s_init;
}

static inline void InitStateMachine(void *arg)
{
    ResetStateMachine(arg);
    EmyptData (Arg);
}

static inline int BestStateMachine(void *arg)
{
    SM_ARG * p = (SM_ARG * ) arg;

    // record the current state of the 
    p-> = p-st.cs> st.ns;

    // Now the case the next stage obtained according to the state 
    p-> Steps st.ns = [p-> st.cs] (Arg);
    
    // Returns the current state (which can be modified as required) 
    return p-> st.cs;
}

#endif /* __FSM_H_ */

Usage examples.

/*
# File    :   fsm_demo.c
# Author  :   SCHIPS
# Mail    :   [email protected]
# Git     :   https://gitee.com/schips/
# Date    :   Mon, May 50, 2019  13:14:52 PM  ♡
*/

#include "fsm.h"
#include <stdio.h>

int main(void)
{
    an int Ret = 0 ;

    SM_ARG was ;
    InitStateMachine(&var);
    while(1)
    {
        printf("cs = %d, ns = %d\n",var.st.cs,var.st.ns);

        BestStateMachine ( & var );

        // Stop condition 
        IF ( var .st.cs == s_done)
        {
            ResetStateMachine(&var);
            //break;
        }
        entitled ++ ;
        if (right of> 10 )
        {
            break;
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/schips/p/10926795.html