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; }