FSM状态机实现

  1. 首先定义一个自己的状态机管理对象
typedef struct FSM_s {
    int curState;//当前状态
    FsmTable_t *pFsmTable;//状态表
    int size;//表的项数
} FSM_t;
  1. 初始化该对象,即指定当前状态,状态表和size
  2. 处理各种event时,遵循原则
    event == 状态表中某项的event && 状态表中该项的状态 == 当前状态
  3. 符合条件后,则可执行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;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值