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
00001 #include "mbed.h" 00002 00003 Serial pc(USBTX, USBRX); 00004 00005 DigitalOut gpo1(D1); 00006 DigitalOut gpo2(D2); 00007 DigitalOut gpo3(D3); 00008 DigitalOut ledB(LED_BLUE); 00009 DigitalOut ledG(LED_GREEN); 00010 DigitalOut ledR(LED_RED); 00011 00012 Ticker tick; 00013 00014 typedef struct EventTag { 00015 uint16_t sig; /* signal of the event */ 00016 } Event; 00017 00018 struct StateTableTag; /* forward declaration */ 00019 00020 typedef void (*Tran)(struct StateTableTag *me, Event const *e); 00021 00022 typedef struct StateTableTag { 00023 uint8_t state; /* the current active state */ 00024 uint8_t *st_desc; /* the current active state Name Descriprion */ 00025 Tran const *state_table; /* the State-Table */ 00026 uint8_t n_states; /* number of states */ 00027 uint8_t n_signals; /* number of signals */ 00028 Tran initial; /* the initial transition */ 00029 } StateTable; 00030 00031 void StTbl_ctor(StateTable *me, 00032 Tran const *table, 00033 uint8_t n_states, 00034 uint8_t n_signals, 00035 Tran initial); 00036 00037 void StTbl_init(StateTable *me); 00038 void StTbl_dispatch(StateTable *me, Event const *e); 00039 void StTbl_empty(StateTable *me, Event const *e); 00040 00041 /* macro for taking a state transition inside a transition function */ 00042 #define TRAN(target_) (((StateTable *)me)->state = (uint8_t)(target_)) 00043 00044 void StTbl_ctor(StateTable *me, 00045 Tran const *table, uint8_t n_states, uint8_t n_signals, 00046 Tran initial) 00047 { 00048 me->state_table = table; 00049 me->n_states = n_states; 00050 me->n_signals = n_signals; 00051 me->initial = initial; 00052 } 00053 00054 void StTbl_init(StateTable *me) { 00055 me->state = me->n_states; 00056 (*me->initial)(me, (Event *)0); 00057 } 00058 00059 void StTbl_dispatch(StateTable *me, Event const *e) { 00060 Tran t; 00061 00062 t = me->state_table[me->state*me->n_signals + e->sig]; 00063 (*t)(me, e); 00064 } 00065 00066 void StTbl_empty(StateTable *me, Event const *e) { 00067 (void)me; 00068 (void)e; 00069 } 00070 00071 typedef struct Tag { /* FSM */ 00072 StateTable super; /* derive from the StateTable structure */ 00073 uint8_t timeout; /* number of seconds till exp */ 00074 uint8_t defuse; /* secret defuse code to disarm */ 00075 uint8_t code; /* currently entered code to disarm */ 00076 } FSM1; 00077 00078 00079 enum FSMSignals { /* all signals for the Bomb FSM */ 00080 GO_SIG, 00081 OUT_SIG, 00082 TICK_SIG, 00083 ERR_SIG, 00084 CONF_SIG, 00085 TRANADM_SIG, 00086 00087 MAX_SIG /* the number of signals */ 00088 }; 00089 00090 enum FSMStates { 00091 SETTING_FSM_STATE, /* Setting for FSM */ 00092 READY_FSM_STATE, /* Unassigned and Ready to be configured from PC */ 00093 ASSIGNED_FSM_STATE, /* Assigned to a user. None could use it apart from him.*/ 00094 LOCKED_FSM_STATE, /* Locked by user*/ 00095 ERROR_STATE, /* Error state. Only logging communication*/ 00096 00097 MAX_STATE 00098 }; 00099 00100 typedef struct TickEvtTag { 00101 Event super; /* derive from the Event structure */ 00102 uint8_t fine_time; /* the fine 1/10 s counter */ 00103 } TickEvt; 00104 00105 00106 static void FSM_initial (FSM1 *me, Event const *e) 00107 { 00108 (void)e; 00109 00110 pc.printf("State --> Initial\n"); 00111 TRAN(SETTING_FSM_STATE); 00112 } 00113 00114 static void FSM_setting_GO (FSM1 *me, Event const *e) 00115 { 00116 (void)e; 00117 pc.printf("State --> Setting - GO Event was caught\n"); 00118 TRAN(READY_FSM_STATE); 00119 } 00120 00121 static void FSM_setting_OUT (FSM1 *me, Event const *e) 00122 { 00123 (void)e; 00124 pc.printf("State --> Setting - OUT Event was caught\n"); 00125 } 00126 00127 static void FSM_setting_ERR (FSM1 *me, Event const *e) 00128 { 00129 (void)e; 00130 pc.printf("State --> Setting - ERR Event was caught\n"); 00131 TRAN(ERROR_STATE); 00132 } 00133 00134 static void FSM_setting_TRAN (FSM1 *me, Event const *e) 00135 { 00136 (void)e; 00137 pc.printf("State --> Setting - TRAN ADMIN Event was caught\n"); 00138 } 00139 00140 static void FSM_ready_GO (FSM1 *me, Event const *e) 00141 { 00142 (void)e; 00143 pc.printf("State --> Ready - GO Event was caught\n"); 00144 TRAN(ASSIGNED_FSM_STATE); 00145 } 00146 00147 static void FSM_ready_OUT (FSM1 *me, Event const *e) 00148 { 00149 (void)e; 00150 pc.printf("State --> Ready - OUT Event was caught\n"); 00151 } 00152 00153 static void FSM_ready_TICK (FSM1 *me, Event const *e) 00154 { 00155 (void)e; 00156 pc.printf("State --> Ready - TICK Event was caught\n"); 00157 } 00158 00159 static void FSM_ready_ERR (FSM1 *me, Event const *e) 00160 { 00161 (void)e; 00162 pc.printf("State --> Ready - ERR Event was caught\n"); 00163 TRAN(ERROR_STATE); 00164 00165 } 00166 00167 static void FSM_ready_CONF (FSM1 *me, Event const *e) 00168 { 00169 (void)e; 00170 pc.printf("State --> Ready - CONF Event was caught\n"); 00171 TRAN(SETTING_FSM_STATE); 00172 00173 } 00174 00175 static void FSM_ready_TRAN (FSM1 *me, Event const *e) 00176 { 00177 (void)e; 00178 pc.printf("State --> Ready - TRAN ADMIN Event was caught\n"); 00179 } 00180 00181 static void FSM_assigned_GO (FSM1 *me, Event const *e) 00182 { 00183 (void)e; 00184 pc.printf("State --> Assigned - GO Event was caught\n"); 00185 TRAN(LOCKED_FSM_STATE); 00186 } 00187 00188 static void FSM_assigned_OUT (FSM1 *me, Event const *e) 00189 { 00190 (void)e; 00191 pc.printf("State --> Assigned - OUT Event was caught\n"); 00192 TRAN(READY_FSM_STATE); 00193 } 00194 00195 static void FSM_assigned_TICK (FSM1 *me, Event const *e) 00196 { 00197 (void)e; 00198 pc.printf("State --> Assigned - TICK Event was caught\n"); 00199 00200 } 00201 00202 static void FSM_assigned_ERR (FSM1 *me, Event const *e) 00203 { 00204 (void)e; 00205 pc.printf("State --> Assigned - ERR Event was caught\n"); 00206 TRAN(ERROR_STATE); 00207 00208 } 00209 00210 static void FSM_assigned_CONF (FSM1 *me, Event const *e) 00211 { 00212 (void)e; 00213 pc.printf("State --> Assigned - CONF Event was caught\n"); 00214 TRAN(SETTING_FSM_STATE); 00215 00216 } 00217 00218 static void FSM_assigned_TRAN (FSM1 *me, Event const *e) 00219 { 00220 (void)e; 00221 pc.printf("State --> Assigned - TRAN ADMIN Event was caught\n"); 00222 00223 } 00224 00225 static void FSM_locked_GO (FSM1 *me, Event const *e) 00226 { 00227 (void)e; 00228 pc.printf("State --> Locked - GO Event was caught\n"); 00229 00230 } 00231 00232 static void FSM_locked_OUT (FSM1 *me, Event const *e) 00233 { 00234 (void)e; 00235 pc.printf("State --> Locked - OUT Event was caught\n"); 00236 TRAN(ASSIGNED_FSM_STATE); 00237 00238 } 00239 00240 static void FSM_locked_TICK (FSM1 *me, Event const *e) 00241 { 00242 (void)e; 00243 pc.printf("State --> Locked - TICK Event was caught\n"); 00244 00245 } 00246 00247 static void FSM_locked_ERR (FSM1 *me, Event const *e) 00248 { 00249 (void)e; 00250 pc.printf("State --> Locked - ERR Event was caught\n"); 00251 TRAN(ERROR_STATE); 00252 00253 } 00254 00255 static void FSM_locked_CONF (FSM1 *me, Event const *e) 00256 { 00257 (void)e; 00258 pc.printf("State --> Locked - CONF Event was caught\n"); 00259 TRAN(SETTING_FSM_STATE); 00260 00261 } 00262 00263 static void FSM_locked_TRAN (FSM1 *me, Event const *e) 00264 { 00265 (void)e; 00266 pc.printf("State --> Locked - TRAN ADMIN Event was caught\n"); 00267 00268 } 00269 00270 00271 void FSM_ctor(FSM1 *me, uint8_t defuse) { 00272 00273 static const Tran fsm_state_table[MAX_STATE][MAX_SIG] = 00274 { 00275 {(Tran)&FSM_setting_GO, (Tran)&FSM_setting_OUT, &StTbl_empty, (Tran)&FSM_setting_ERR, &StTbl_empty, (Tran)&FSM_setting_TRAN }, 00276 {(Tran)&FSM_ready_GO, (Tran)&FSM_ready_OUT, (Tran)&FSM_ready_TICK, (Tran)&FSM_ready_ERR, (Tran)&FSM_ready_CONF, (Tran)&FSM_ready_TRAN }, 00277 {(Tran)&FSM_assigned_GO, (Tran)&FSM_assigned_OUT, (Tran)&FSM_assigned_TICK, (Tran)&FSM_assigned_ERR, (Tran)&FSM_assigned_CONF, (Tran)&FSM_assigned_TRAN }, 00278 {(Tran)&FSM_locked_GO, (Tran)&FSM_locked_OUT, (Tran)&FSM_locked_TICK, (Tran)&FSM_locked_ERR, (Tran)&FSM_locked_CONF, (Tran)&FSM_locked_TRAN } 00279 }; 00280 00281 StTbl_ctor(&me->super, &fsm_state_table[0][0], MAX_STATE, MAX_SIG, (Tran)&FSM_initial); 00282 00283 me->defuse = defuse; 00284 } 00285 00286 bool _t1_OVRFL = false; 00287 // ISR Timer per 1sec 00288 void ISR(void) { 00289 _t1_OVRFL = true; 00290 } 00291 00292 char cmd; 00293 bool _pc_GTCMD = false; 00294 // ISR when Gets command 00295 void Serial_ISR(void) { 00296 _pc_GTCMD = true; 00297 cmd = pc.getc(); //Gets the command 00298 } 00299 00300 int main() 00301 { 00302 00303 pc.baud(9600); 00304 pc.attach(&Serial_ISR); 00305 tick.attach(&ISR, 1.0); 00306 00307 static FSM1 _frdm_fsm; 00308 static Event const go_evt = { GO_SIG }; 00309 static Event const out_evt = { OUT_SIG }; 00310 static Event const err_evt = { ERR_SIG }; 00311 static Event const conf_evt = { CONF_SIG }; 00312 static TickEvt tick_evt = { TICK_SIG, 0}; 00313 00314 FSM_ctor(&_frdm_fsm, 0xFF); 00315 00316 StTbl_init((StateTable *)&_frdm_fsm); 00317 00318 pc.printf("Frdm K64F FSM App\r\n"); 00319 Event const *e = (Event *)0; 00320 00321 while (true) { 00322 00323 pc.printf("Running\r\n\n"); 00324 gpo1 = !gpo1; // toggle pin 00325 ledB = !ledB; // toggle led 00326 wait(0.2f); 00327 00328 if(_t1_OVRFL) 00329 { 00330 _t1_OVRFL = false; 00331 StTbl_dispatch((StateTable *)&_frdm_fsm, (Event *)&tick_evt); 00332 } 00333 00334 switch (cmd) 00335 { 00336 case 'G': { 00337 pc.printf(" Go received \n"); 00338 e = &go_evt; 00339 break; 00340 } 00341 case 'O': { 00342 pc.printf(" Out Received \n"); 00343 e = &out_evt; 00344 break; 00345 } 00346 case 'E': { 00347 pc.printf(" Error Received \n"); 00348 e = &err_evt; 00349 break; 00350 } 00351 case 'C': { 00352 pc.printf(" Config Received \n"); 00353 e = &conf_evt; 00354 break; 00355 } 00356 } 00357 if(_pc_GTCMD) 00358 { 00359 _pc_GTCMD = false; 00360 if (e != (Event *)0) 00361 { 00362 StTbl_dispatch((StateTable *)&_frdm_fsm, e); 00363 } 00364 } 00365 00366 } 00367 } 00368
Generated on Thu Jul 28 2022 10:57:56 by 1.7.2