基于真值表的有限状态机实现

在ECU的处理逻辑中往往摆脱不了状态机,为了使状态编程清晰可靠,可以将状态跳转条件组成真值表,将状态跳转用模型实现,一方面减少逻辑的复杂度,另一方面可以将代码变得更清晰减少出错。以下是我的思路,希望能给大家提供一些帮助,具体实现如下:

static volatile Uint32 fsm_tmr[STATE_CNT+1] = {0};

void fsm_timer_init(void)
{
    MemSet((Uint16 *)fsm_tmr, 0, sizeof(fsm_tmr));
}

void fsm_set_timer(Uint16 index, Uint32 tout)
{
    fsm_tmr[index] = tout;
}

Uint32 fsm_get_timer(Uint16 index)
{
    return fsm_tmr[index];
}


Uint16 fsm_chk_timer(Uint16 index)
{
    return (!fsm_tmr[index]);
}

void fsm_1ms_irq(void)
{
    Uint16 j;

    for(j = 0; j < STATE_CNT+1; j++)
	{
        if(fsm_tmr[j])
        {
            fsm_tmr[j]--;
        }
	}
}

typedef enum
{
    STARTUP,
    INIT,
    STANDBY,
    CHARG,
    SHUTDOWN,
    STATE_CNT
}FSM_STATE;

Uint16 jump_matrix[STARTUP][INIT];
Uint16 fsm_state_min_time[FSM_STATE] = {200, 200, 200, 200, 200};

#define MATRIX_INIT(cond,dly) (((!!(cond))<<15) | (dly))

void update_matrix(void)
{
    jump_matrix[STARTUP][INIT] = MATRIX_INIT(1,0);
    jump_matrix[INIT][STANDBY] = MATRIX_INIT(1,0);
    jump_matrix[INIT][SHUTDOWN] = MATRIX_INIT(1,0);
}

typedef struct
{
    (void)(*entry_ev)(void);
    (void)(*during_ev)(void);
    (void)(*exit_ev)(void);
    
}FSM_EV;

FSM_EV ev_list[STATE_CNT] = 
{
    .[INIT] = {},
    .[STANDBY] = {}
};

typedef struct
{
    FSM_STATE state;
    Uint16 (*matrix)[STATE_CNT][STATE_CNT];
    FSM_EV *event;
    (void)(*state_change_notification)(FSM_STATE, FSM_STATE);
}FSM_INS;

FSM_INS fsm;

void fsm_state_change_notification(FSM_STATE prev_state, FSM_STATE curr_state)
{
}

void fsm_init(void)
{
    fsm.state = STARTUP;
    fsm.matrix = jump_matrix;
    fsm.event = ev_list;
    fsm.state_change_notification = fsm_state_change_notification;
}

void fsm_run(void)
{
    Uint16 i;

    update_matrix();
    
    (fsm.event[fsm.state]->state_ev)();
    
    for(i = 0; i < STATE_CNT; i++)
    {
        //lookup table
        if(fsm.matrx[fsm.state][i] & 0x8000)
        {
            if(fsm_chk_timer(i) && fsm_chk_timer(STATE_CNT))
            {
                //(fsm.event[fsm.state]->exit_ev)();
                (fsm.event[fsm.state]->state_change_notification)(fsm.state, i);
                fsm.state = i;
                
                fsm_timer_init();

                fsm_set_timer(STATE_CNT, fsm_state_min_time[fsm.state]*MS_T);
                
                //(fsm.event_list[fsm.state]->entry_ev)();

                //(fsm.event_list[fsm.state]->during_ev)();
                break;
            }
        }
        else
        {
            fsm_set_timer(i, fsm.matrx[fsm.state][i]&0x7FFF);
        }
    } 
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值