- 首先定义一个自己的状态机管理对象
typedef struct FSM_s {
int curState;//当前状态
FsmTable_t *pFsmTable;//状态表
int size;//表的项数
} FSM_t;
- 初始化该对象,即指定当前状态,状态表和size
- 处理各种event时,遵循原则
event == 状态表中某项的event && 状态表中该项的状态 == 当前状态 - 符合条件后,则可执行action以及下一个状态切换。
//
// Created by wyy on 2024/7/7.
//
/*state.c*/
#include <stdio.h>
enum year_state {
SPRING = 1,
SUMMER,
AUTUMN,
WINTER
};
enum year_event {
EVENT1 = 1,
EVENT2,
EVENT3,
EVENT4,
};
typedef struct FsmTable_s {
int event; //事件
int CurState; //当前状态
void (*eventActFun)(); //函数指针
int NextState; //下一个状态
} FsmTable_t;
void spring_thing() {
printf("this is spring\n");
}
void summer_thing() {
printf("this is summer\n");
}
void autumn_thing() {
printf("this is autumn\n");
}
void winter_thing() {
printf("this is winter\n");
}
FsmTable_t year_table[] =
{
//{到来的事件,当前的状态,将要要执行的函数,下一个状态}
{EVENT1, SPRING, summer_thing, SUMMER},
{EVENT2, SUMMER, autumn_thing, AUTUMN},
{EVENT3, AUTUMN, winter_thing, WINTER},
{EVENT4, WINTER, spring_thing, SPRING},
//add your codes here
};
typedef struct FSM_s {
int curState;//当前状态
FsmTable_t *pFsmTable;//状态表
int size;//表的项数
} FSM_t;
/*状态机注册,给它一个状态表*/
void FSM_Regist(FSM_t *pFsm, FsmTable_t *pTable) {
pFsm->pFsmTable = pTable;
}
/*状态迁移*/
void FSM_StateTransfer(FSM_t *pFsm, int state) {
pFsm->curState = state;
}
/*事件处理*/
void FSM_EventHandle(FSM_t *pFsm, int event) {
FsmTable_t *pActTable = pFsm->pFsmTable;
void (*eventActFun)() = NULL; //函数指针初始化为空
int NextState;
int CurState = pFsm->curState;
int g_max_num = pFsm->size;
int flag = 0; //标识是否满足条件
int i;
/*获取当前动作函数*/
for (i = 0; i < g_max_num; i++) {
//当且仅当当前状态下来个指定的事件,我才执行它
if (event == pActTable[i].event && CurState == pActTable[i].CurState) {
flag = 1;
eventActFun = pActTable[i].eventActFun;
NextState = pActTable[i].NextState;
break;
}
}
if (flag) //如果满足条件了
{
/*动作执行*/
if (eventActFun) {
eventActFun();
}
//跳转到下一个状态
FSM_StateTransfer(pFsm, NextState);
} else {
printf("there is no match\n");
}
}
int main() {
FSM_t year_fsm;
FSM_Regist(&year_fsm, year_table);
year_fsm.curState = SPRING;
year_fsm.size = sizeof(year_table) / sizeof(FsmTable_t);
printf("\n-------1--init spring------\n");
printf("state:%d\n", year_fsm.curState);
printf("\n-------2--spring->summer------\n");
FSM_EventHandle(&year_fsm, EVENT1);
printf("state:%d\n", year_fsm.curState);
printf("\n-------3--summer->autumn------\n");
FSM_EventHandle(&year_fsm, EVENT2);
printf("state:%d\n", year_fsm.curState);
printf("\n-------4--autumn->winter------\n");
FSM_EventHandle(&year_fsm, EVENT3);
printf("state:%d\n", year_fsm.curState);
printf("\n-------5--winter->spring------\n");
FSM_EventHandle(&year_fsm, EVENT4);
printf("state:%d\n", year_fsm.curState);
printf("\n-------6--receive EVENT2 not EVENT1------\n");
FSM_EventHandle(&year_fsm, EVENT2);
printf("state:%d\n", year_fsm.curState);
return 0;
}
更复杂状态机2
//
// Created by wyy on 2024/7/7.
//
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#define EVENT1 0
#define EVENT2 1
#define EVENT3 2
#define EVENT4 3
#define EVENT5 4
typedef void (*STATE_ACTION)(void);
typedef struct ACTION_MAP
{
uint8_t stStateID;
STATE_ACTION EnterAct;
STATE_ACTION RunningAct;
STATE_ACTION ExitAct;
}ACTION_MAP_t; /* 动作action表描述 */
typedef struct EVENT_MAP
{
uint8_t stEventID;
uint8_t stCurState;
uint8_t stNextState;
}EVENT_MAP_t; /* 事件event表描述 */
typedef struct FSM
{
uint8_t u8Flag; /* 状态切换标志位,1表示要进行状态切换 */
uint8_t u8EventSum; /* 事件event总数 */
uint8_t u8ActSum; /* 动作action总数 */
uint8_t stCurState;
uint8_t stNextState;
ACTION_MAP_t *pActionMap;
EVENT_MAP_t *pEventMap;
}FSM_t; /* 状态机控制结构 */
void fsm_init(FSM_t* pFsm,EVENT_MAP_t* pEventMap,ACTION_MAP_t *pActionMap,
uint8_t u8EventSum,uint8_t u8ActSum,uint8_t curState)
{
pFsm->u8Flag = 0;
pFsm->stNextState = 0;
pFsm->u8EventSum = u8EventSum;
pFsm->u8ActSum = u8ActSum;
pFsm->stCurState = curState;
pFsm->pEventMap = pEventMap;
pFsm->pActionMap = pActionMap;
}
uint8_t get_action_sum(FSM_t* pFsm,uint8_t u8ID)
{
int i = 0;
for(i=0; i<pFsm->u8ActSum; i++)
{
if(u8ID == pFsm->pActionMap[i].stStateID)
return i;
}
return -1;
}
void action_perfrom(FSM_t* pFsm)
{
uint8_t u8CurID = -1, u8NextID = -1;
if(0 != pFsm->u8Flag) /* 标志位不为0表示要进行状态切换 */
{
u8CurID = get_action_sum(pFsm,pFsm->stCurState);
u8NextID = get_action_sum(pFsm,pFsm->stNextState);
if((-1 != u8CurID) && (-1 != u8NextID))
{
pFsm->pActionMap[u8CurID].ExitAct(); /* 执行当前状态的退出动作 */
pFsm->pActionMap[u8NextID].EnterAct(); /* 执行下一个状态的进入动作 */
}
else
{
pFsm->u8Flag = 0; /* 清标志位 */
printf("State transition failed! curState = %d, nextState = %d\n",pFsm->stCurState,pFsm->stNextState);
return;
}
pFsm->stCurState = pFsm->stNextState; /* 当前状态切换 */
pFsm->stNextState = -1;
pFsm->u8Flag = 0; /* 清标志位 */
}
else
{
u8CurID = get_action_sum(pFsm,pFsm->stCurState);
if(-1 != u8CurID)
pFsm->pActionMap[u8CurID].RunningAct();/* 标志位为0不进行状态切换,执行当前状态的do动作 */
}
}
void fsm_state_transfer(FSM_t* pFsm, uint8_t stEventID)
{
uint8_t i = 0;
for(i=0; i<pFsm->u8EventSum; i++)
{
if((stEventID == pFsm->pEventMap[i].stEventID)
&& (pFsm->stCurState == pFsm->pEventMap[i].stCurState))
{
pFsm->stNextState = pFsm->pEventMap[i].stNextState;
pFsm->u8Flag = 1;
return;
}
}
}
void state1_entry(void)
{
printf("state1_entry\n");
}
void state1_do(void)
{
printf("state1_do\n");
}
void state1_exit(void)
{
printf("state1_exit\n");
}
void state2_entry(void)
{
printf("state2_entry\n");
}
void state2_do(void)
{
printf("state2_do\n");
}
void state2_exit(void)
{
printf("state2_exit\n");
}
void state3_entry(void)
{
printf("state3_entry\n");
}
void state3_do(void)
{
printf("state3_do\n");
}
void state3_exit(void)
{
printf("state3_exit\n");
}
void state4_entry(void)
{
printf("state4_entry\n");
}
void state4_do(void)
{
printf("state4_do\n");
}
void state4_exit(void)
{
printf("state4_exit\n");
}
#define STATE1 0
#define STATE2 1
#define STATE3 2
#define STATE4 3
ACTION_MAP_t actionMap[] =
{
{STATE1, state1_entry, state1_do, state1_exit},
{STATE2, state2_entry, state2_do, state2_exit},
{STATE3, state3_entry, state3_do, state3_exit},
{STATE4, state4_entry, state4_do, state4_exit},
};
EVENT_MAP_t eventMap[] =
{
{EVENT1, STATE1, STATE2},
{EVENT2, STATE2, STATE3},
{EVENT3, STATE3, STATE4},
{EVENT4, STATE4, STATE1},
{EVENT5, STATE1, STATE4},
};
/* 获取动作表 */
ACTION_MAP_t* get_action_map(uint8_t *total)
{
*total = sizeof(actionMap)/sizeof(ACTION_MAP_t);
return actionMap;
}
/* 获取事件表 */
EVENT_MAP_t* get_event_map(uint8_t *total)
{
*total = sizeof(eventMap)/sizeof(EVENT_MAP_t);
return eventMap;
}
int main(void)
{
int i = 0;
uint8_t u8ActNum = 0, u8EventNum = 0;
FSM_t stFsm; /* 定义状态机 */
ACTION_MAP_t* stActMap;
EVENT_MAP_t* stEventMap;
stActMap = get_action_map(&u8ActNum);
stEventMap = get_event_map(&u8EventNum);
fsm_init(&stFsm,stEventMap,stActMap,u8EventNum,u8ActNum,STATE1);
while(1)
{
sleep(1);
printf("i = %d\n",i++);
action_perfrom(&stFsm);
/* 利用i产生EVENT1~EVENT5 */
if(1 == (i%10))
{
fsm_state_transfer(&stFsm,EVENT1);
}
if(3 == (i%10))
{
fsm_state_transfer(&stFsm,EVENT2);
}
if(5 == (i%10))
{
fsm_state_transfer(&stFsm,EVENT3);
}
if(7 == (i%10))
{
fsm_state_transfer(&stFsm,EVENT4);
}
if(9 == (i%10))
{
fsm_state_transfer(&stFsm,EVENT5);
}
}
return 0;
}