/* ************************************************************************************************************************ * exceute the finit state machine * * Description: This function is used to exceute the finit state machine. * * Arguments :me is the state machine * --------- * e is the trig event * * Returns * * Note(s) * * ************************************************************************************************************************ */ void fsm_exceute(STM_STRUCT *me, STATE_EVENT *e) { RAW_U16 ret; /*State must be stable here*/ if (me->state != me->temp) { RAW_ASSERT(0); } /*exceute the state function with new event*/ ret = (*me->state)(me, e); if (ret == STM_RET_TRAN) { /*exit the original state */ STM_EXIT(me->state); /*enter the new state*/ STM_ENTER(me->temp); /*change to new state*/ me->state = me->temp; } }
/* * This function is used to exceute the finit state machine. * @me is the meta state machine * @e is the trig event * * Note(s) */ void fsm_execute (TMsm *me, TEvt *e) { uint8_t ret; if (me->state != me->temp) /* State must be stable here */ { PORT_ASSERT (0); } ret = (*me->state) (me, e); /* exceute the state function with new event */ if (ret == STM_RET_TRAN) { STM_EXIT (me->state); /* exit the original state */ STM_ENTER (me->temp); /* enter the new state */ me->state = me->temp; /* change to new state */ } }
/* ************************************************************************************************************************ * Exceute the hsm state machine * * Description: This function is used to exceute the hsm state machine. * * Arguments :me is the state machine * --------- * e is the trig event * * Returns * * Note(s) * * ************************************************************************************************************************ */ void hsm_exceute(STM_STRUCT *me, STATE_EVENT *e) { stm_state_handler s; RAW_U16 r; RAW_S8 ip; RAW_S8 iq; stm_state_handler path[STM_MAX_NEST_DEPTH]; stm_state_handler t = me->state; /*state must be stable here*/ if (t != me->temp) { RAW_ASSERT(0); } do { s = me->temp; /*exceute the state function with new event*/ r = (*s)(me, e); if (r == STM_RET_UNHANDLED) { /*Move up to father state*/ r = STM_TRIG(s, STM_EMPTY_SIG); } /*move up to the father state to find suitable state to handle the sig*/ } while (r == STM_RET_FATHER); /*if state transition happened then process it*/ if (r == STM_RET_TRAN) { ip = -1; /*save the transitioned state*/ path[0] = me->temp; path[1] = t; /*t is the source state, and s is the state which cause new state change*/ /*for example s is the father state of t*/ while (t != s) { /*if STM_EXIT_SIG is handled, trig STM_EMPTY_SIG to find the father state*/ /*if STM_EXIT_SIG not handled , then me->temp hold the father state*/ if (STM_TRIG(t, STM_EXIT_SIG) == STM_RET_HANDLED) { STM_TRIG(t, STM_EMPTY_SIG); } /*move t to one father state up*/ t = me->temp; } /*t is the target transition state*/ t = path[0]; /*all the following code is try to find the LCA and exit from the source state to LCA state*/ /*Be careful LCA state is either not entered not exited.*/ /*all the father state of the target transition state is stored to path from hight to low etc, path[0] is the target transition state*/ if (s == t) { STM_EXIT(s); ip = 0; } else { STM_TRIG(t, STM_EMPTY_SIG); t = me->temp; if (s == t) { ip = 0; } else { STM_TRIG(s, STM_EMPTY_SIG); if (me->temp == t) { STM_EXIT(s); ip = 0; } else { if (me->temp == path[0]) { STM_EXIT(s); } else { iq = 0; ip = 1; path[1] = t; t = me->temp; r = STM_TRIG(path[1], STM_EMPTY_SIG); while (r == STM_RET_FATHER) { ++ip; path[ip] = me->temp; if (me->temp == s) { iq = 1; if (ip >= STM_MAX_NEST_DEPTH) { RAW_ASSERT(0); } --ip; r = STM_RET_HANDLED; } else { r = STM_TRIG(me->temp, STM_EMPTY_SIG); } } if (iq == 0) { if (ip >= STM_MAX_NEST_DEPTH) { RAW_ASSERT(0); } STM_EXIT(s); iq = ip; r = STM_RET_IGNORED; do { if (t == path[iq]) { r = STM_RET_HANDLED; ip = iq - 1; iq = -1; } else { --iq; } } while (iq >= 0); if (r != STM_RET_HANDLED) { r = STM_RET_IGNORED; do { if (STM_TRIG(t, STM_EXIT_SIG) == STM_RET_HANDLED) { STM_TRIG(t, STM_EMPTY_SIG); } t = me->temp; iq = ip; do { if (t == path[iq]) { ip = iq - 1; iq = -1; r = STM_RET_HANDLED; } else { --iq; } } while (iq >= 0); } while (r != STM_RET_HANDLED); } } } } } } /*trig STM_ENTRY_SIG from LCA to transioned state*/ for (; ip >= 0; --ip) { STM_ENTER(path[ip]); } t = path[0]; me->temp = t; /*trig the STM_INIT_SIG to the new transitioned state, if new transion happened again, then we need do it again*/ /*Becareful STM_INIT_SIG must trig t state to the nested children state, otherwise hsm crash*/ while (STM_TRIG(t, STM_INIT_SIG) == STM_RET_TRAN) { ip = 0; path[0] = me->temp; /*Find all the father state until to source t state */ STM_TRIG(me->temp, STM_EMPTY_SIG); while (me->temp != t) { ++ip; path[ip] = me->temp; STM_TRIG(me->temp, STM_EMPTY_SIG); } me->temp = path[0]; if (ip >= STM_MAX_NEST_DEPTH) { RAW_ASSERT(0); } /*trig STM_ENTRY_SIG from father source state to nested transition children state*/ do { STM_ENTER(path[ip]); --ip; } while (ip >= 0); /*remember the target transitoned state*/ t = path[0]; } } /*change to new state*/ me->state = t; me->temp = t; }