Reputation: 35
Let's say I have a finite-state-machine which looks like this:
while(1){
swtich(case){
case ONE:
do_thingone();
if(parameter1 == 0)
case = TWO;
break;
case TWO:
do_thingtwo();
do_thingthree();
if(parameter1 == 1)
case = ONE;
if(parameter0 == 0)
case = THREE;
break;
//and so on
}
}
With a boolean paramter p_master I want to change between two finite-state-machines with similar, yet different content.
while(1){
switch(state){
state STATE_0:
switch(case){
case ONE:
do_onething();
if(parameter1 == 0)
case = TWO;
break;
//case TWO:
}
break;
case STATE_1:
switch(case){
case ONE:
do_anotherthing();
if(parameter1 == 0)
case = TWO;
break;
//case TWO:
}
break;
}
}
I don't want to check and switch case via an
if(p_master == 0)
or vice versa every iteration, as I think this will create too much overhead (p_master only changes every 100th or 1000th iteration, it even is perfectly ok for it to never change at all!). Is there a more elegant way to change between a case and another than conditions ins the finite-state-machine loop?
Note: p_master can be triggered as an interrupt at CPU level!
Upvotes: 0
Views: 65
Reputation: 94409
Move the switch
statement into a function and adjust a function pointer. Having a dedicated "handler" function for each state (and each handler can define what handler is next) is pretty common when implementing finite state machines in C. It also nicely maps to the state machine diagrams you might look at (one handler function per state).
See this question for some inspiration.
Upvotes: 3
Reputation: 30011
If you only have a few such states and you can change the flags, why not roll them into one switch:
switch(state | case){
case STATE_0 | ONE:
do_onething();
if(parameter1 == 0)
case = TWO;
break;
case STATE_0 | TWO:
break;
case STATE_1 | ONE:
do_onething();
if(parameter1 == 0)
case = TWO;
break;
case STATE_1 | TWO:
break;
}
Upvotes: 0
Reputation: 16049
Function pointers.
typedef void (*State_T) (void);
void state_1(void);
void state_2(void);
void doStuff(void) {
State_T currentState = state_1;
while(...) {
currentState();
}
}
Upvotes: 0