State machines are commonly used to implement decision making algorithms. State machines are used in applications where distinguishable states exist. A finite state machine (FSM) is based on the idea that a given system has a finite number of states.
Dependencies: mbed
Fork of FRDM-K64F_FSM by
main.cpp
- Committer:
- mnikolaos
- Date:
- 2014-08-07
- Revision:
- 0:17539d6d4289
File content as of revision 0:17539d6d4289:
#include "mbed.h" Serial pc(USBTX, USBRX); DigitalOut gpo1(D1); DigitalOut gpo2(D2); DigitalOut gpo3(D3); DigitalOut ledB(LED_BLUE); DigitalOut ledG(LED_GREEN); DigitalOut ledR(LED_RED); Ticker tick; typedef struct EventTag { uint16_t sig; /* signal of the event */ } Event; struct StateTableTag; /* forward declaration */ typedef void (*Tran)(struct StateTableTag *me, Event const *e); typedef struct StateTableTag { uint8_t state; /* the current active state */ uint8_t *st_desc; /* the current active state Name Descriprion */ Tran const *state_table; /* the State-Table */ uint8_t n_states; /* number of states */ uint8_t n_signals; /* number of signals */ Tran initial; /* the initial transition */ } StateTable; void StTbl_ctor(StateTable *me, Tran const *table, uint8_t n_states, uint8_t n_signals, Tran initial); void StTbl_init(StateTable *me); void StTbl_dispatch(StateTable *me, Event const *e); void StTbl_empty(StateTable *me, Event const *e); /* macro for taking a state transition inside a transition function */ #define TRAN(target_) (((StateTable *)me)->state = (uint8_t)(target_)) void StTbl_ctor(StateTable *me, Tran const *table, uint8_t n_states, uint8_t n_signals, Tran initial) { me->state_table = table; me->n_states = n_states; me->n_signals = n_signals; me->initial = initial; } void StTbl_init(StateTable *me) { me->state = me->n_states; (*me->initial)(me, (Event *)0); } void StTbl_dispatch(StateTable *me, Event const *e) { Tran t; t = me->state_table[me->state*me->n_signals + e->sig]; (*t)(me, e); } void StTbl_empty(StateTable *me, Event const *e) { (void)me; (void)e; } typedef struct Tag { /* FSM */ StateTable super; /* derive from the StateTable structure */ uint8_t timeout; /* number of seconds till exp */ uint8_t defuse; /* secret defuse code to disarm */ uint8_t code; /* currently entered code to disarm */ } FSM1; enum FSMSignals { /* all signals for the Bomb FSM */ GO_SIG, OUT_SIG, TICK_SIG, ERR_SIG, CONF_SIG, TRANADM_SIG, MAX_SIG /* the number of signals */ }; enum FSMStates { SETTING_FSM_STATE, /* Setting for FSM */ READY_FSM_STATE, /* Unassigned and Ready to be configured from PC */ ASSIGNED_FSM_STATE, /* Assigned to a user. None could use it apart from him.*/ LOCKED_FSM_STATE, /* Locked by user*/ ERROR_STATE, /* Error state. Only logging communication*/ MAX_STATE }; typedef struct TickEvtTag { Event super; /* derive from the Event structure */ uint8_t fine_time; /* the fine 1/10 s counter */ } TickEvt; static void FSM_initial (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Initial\n"); TRAN(SETTING_FSM_STATE); } static void FSM_setting_GO (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Setting - GO Event was caught\n"); TRAN(READY_FSM_STATE); } static void FSM_setting_OUT (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Setting - OUT Event was caught\n"); } static void FSM_setting_ERR (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Setting - ERR Event was caught\n"); TRAN(ERROR_STATE); } static void FSM_setting_TRAN (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Setting - TRAN ADMIN Event was caught\n"); } static void FSM_ready_GO (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Ready - GO Event was caught\n"); TRAN(ASSIGNED_FSM_STATE); } static void FSM_ready_OUT (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Ready - OUT Event was caught\n"); } static void FSM_ready_TICK (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Ready - TICK Event was caught\n"); } static void FSM_ready_ERR (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Ready - ERR Event was caught\n"); TRAN(ERROR_STATE); } static void FSM_ready_CONF (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Ready - CONF Event was caught\n"); TRAN(SETTING_FSM_STATE); } static void FSM_ready_TRAN (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Ready - TRAN ADMIN Event was caught\n"); } static void FSM_assigned_GO (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Assigned - GO Event was caught\n"); TRAN(LOCKED_FSM_STATE); } static void FSM_assigned_OUT (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Assigned - OUT Event was caught\n"); TRAN(READY_FSM_STATE); } static void FSM_assigned_TICK (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Assigned - TICK Event was caught\n"); } static void FSM_assigned_ERR (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Assigned - ERR Event was caught\n"); TRAN(ERROR_STATE); } static void FSM_assigned_CONF (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Assigned - CONF Event was caught\n"); TRAN(SETTING_FSM_STATE); } static void FSM_assigned_TRAN (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Assigned - TRAN ADMIN Event was caught\n"); } static void FSM_locked_GO (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Locked - GO Event was caught\n"); } static void FSM_locked_OUT (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Locked - OUT Event was caught\n"); TRAN(ASSIGNED_FSM_STATE); } static void FSM_locked_TICK (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Locked - TICK Event was caught\n"); } static void FSM_locked_ERR (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Locked - ERR Event was caught\n"); TRAN(ERROR_STATE); } static void FSM_locked_CONF (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Locked - CONF Event was caught\n"); TRAN(SETTING_FSM_STATE); } static void FSM_locked_TRAN (FSM1 *me, Event const *e) { (void)e; pc.printf("State --> Locked - TRAN ADMIN Event was caught\n"); } void FSM_ctor(FSM1 *me, uint8_t defuse) { static const Tran fsm_state_table[MAX_STATE][MAX_SIG] = { {(Tran)&FSM_setting_GO, (Tran)&FSM_setting_OUT, &StTbl_empty, (Tran)&FSM_setting_ERR, &StTbl_empty, (Tran)&FSM_setting_TRAN }, {(Tran)&FSM_ready_GO, (Tran)&FSM_ready_OUT, (Tran)&FSM_ready_TICK, (Tran)&FSM_ready_ERR, (Tran)&FSM_ready_CONF, (Tran)&FSM_ready_TRAN }, {(Tran)&FSM_assigned_GO, (Tran)&FSM_assigned_OUT, (Tran)&FSM_assigned_TICK, (Tran)&FSM_assigned_ERR, (Tran)&FSM_assigned_CONF, (Tran)&FSM_assigned_TRAN }, {(Tran)&FSM_locked_GO, (Tran)&FSM_locked_OUT, (Tran)&FSM_locked_TICK, (Tran)&FSM_locked_ERR, (Tran)&FSM_locked_CONF, (Tran)&FSM_locked_TRAN } }; StTbl_ctor(&me->super, &fsm_state_table[0][0], MAX_STATE, MAX_SIG, (Tran)&FSM_initial); me->defuse = defuse; } bool _t1_OVRFL = false; // ISR Timer per 1sec void ISR(void) { _t1_OVRFL = true; } char cmd; bool _pc_GTCMD = false; // ISR when Gets command void Serial_ISR(void) { _pc_GTCMD = true; cmd = pc.getc(); //Gets the command } int main() { pc.baud(9600); pc.attach(&Serial_ISR); tick.attach(&ISR, 1.0); static FSM1 _frdm_fsm; static Event const go_evt = { GO_SIG }; static Event const out_evt = { OUT_SIG }; static Event const err_evt = { ERR_SIG }; static Event const conf_evt = { CONF_SIG }; static TickEvt tick_evt = { TICK_SIG, 0}; FSM_ctor(&_frdm_fsm, 0xFF); StTbl_init((StateTable *)&_frdm_fsm); pc.printf("Frdm K64F FSM App\r\n"); Event const *e = (Event *)0; while (true) { pc.printf("Running\r\n\n"); gpo1 = !gpo1; // toggle pin ledB = !ledB; // toggle led wait(0.2f); if(_t1_OVRFL) { _t1_OVRFL = false; StTbl_dispatch((StateTable *)&_frdm_fsm, (Event *)&tick_evt); } switch (cmd) { case 'G': { pc.printf(" Go received \n"); e = &go_evt; break; } case 'O': { pc.printf(" Out Received \n"); e = &out_evt; break; } case 'E': { pc.printf(" Error Received \n"); e = &err_evt; break; } case 'C': { pc.printf(" Config Received \n"); e = &conf_evt; break; } } if(_pc_GTCMD) { _pc_GTCMD = false; if (e != (Event *)0) { StTbl_dispatch((StateTable *)&_frdm_fsm, e); } } } }