HI.. I want an example of how to implement FSM using function pointers in C.
-
I'm assuming FSM means Finite State Machine? What would you need function pointers for? A little more info on what the goal is would help to get a helpful example. – rubenvb Aug 19 '10 at 09:38
-
2(1) Quite demanding you are. (2) What does FSM stand for? (3) Have you already got any code you could show us, along with a pointer where you're currently stuck? (4) Is this homework? (If so, please edit your question and add the tag `homework`.) – stakx - no longer contributing Aug 19 '10 at 09:39
-
@stakx: You sure like making unclaimed assumptions... – leppie Aug 19 '10 at 09:44
-
@leppie, from the way archana asked, i agree with stakx... – YeenFei Aug 19 '10 at 09:50
-
_@leppie_: Are you referring to (1)? That was due to the _"I want..."_, and is my personal opinion concerning this very question, not an assumption about the OP's general character. It's only that I think questions on SO can be asked in a slightly less demanding manner. (I didn't mean to give offense or be hostile, sorry if I did just that.) – stakx - no longer contributing Aug 19 '10 at 09:55
-
have you tried yourself? have you searched? what were your findings? – Jens Gustedt Aug 19 '10 at 09:56
-
http://stackoverflow.com/questions/1371460/state-machines-tutorials/1371654#1371654 – qrdl Aug 19 '10 at 11:17
-
2You can't implement the FSM using function pointers. You need meatballs, Bolognese sauce and spaghetti. – JeremyP Aug 19 '10 at 11:18
-
@JeremyP: You're brilliant! :-D – stakx - no longer contributing Aug 19 '10 at 12:52
5 Answers
See this simple example on how to implement a finite state machine in C.

- 18,571
- 25
- 126
- 193
Here is a little demo of using function pointers in ARDUINO. This example does not allow for concurrency. It perfectly transferable to normal C if make write the setup and loop inside main()
Each state is a void() function. Each state function is responsible for reading input and setting output. When this is done the function should return immediately. It will be called again directly. The function is also responsible for state-transition by calling the leave function immediately before returning. Each state function should have a static long variable for timekeeping.
A global variable state is set to point to the initial state in the setup routine.
I wanted timekeeping in the different states so i implemented the state transitions by 2 functions:
void enter(long *stateTime), this should be called the very first thing when entering the state functions. It activates the state if inactive end keeps time.
void leave(void (*next)(), long *statetime), this changes the global state pointer and deactivates the current state.
void (*state)();//function pointer for state machine
long prevMillis = 0;//timekeeper
const int LEDPIN = 13;
int counter1 = 0;
void enter(long *statetime){
if(*statetime==-1){//check for passive state
prevMillis = millis();//set timemark when entering state
}//if(statetime==0)
*statetime = millis()-prevMillis;//keep time
}//enter()
void leave(void (*next)(), long *statetime){
*statetime=-1;//set state to passive
state=next;//point to next state
}//leave()
void off500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>499){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off500ms()
void off2s(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>1999){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off2s()
void on500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, HIGH);
if(stateMillis >499){//time is up
if(++counter1==6){//number of blinks
leave(off2s, &stateMillis);
counter1=0;//reset counter
}else{//if(++counter1==6)
leave(off500ms, &stateMillis);
}//if(++counter1==6)
}//if(stateMills>499)
}//on500ms
void setup(){
pinMode(LEDPIN, OUTPUT);
state = on500ms;//set initial state
}/setup()
void loop(){
state();//start FSM
}//loop

- 11
- 1
An example is too big to write as an answer here.
Here's an existing example, which I found by Googling for state machine c "function pointer"
: Implementing Efficient State Machines

- 54,973
- 13
- 116
- 224
I would say initialize a array of pointers to event handlers. So each element of a array is a function pointer to a particular event which is part of an enum.
if foo
is your array of function pointers which is initialized to event then call foo[event]()
when any event occurs.
Try coding for calling a function pointer first, next you can move to array and come back to SO if there are more doubts.
For a start you can read about function pointers here.

- 10,355
- 2
- 43
- 69
State transtion code can be utilize either by array or switch case. Written under if else directive.
#include <stdio.h>
#include <stdlib.h>
int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);
enum state_codes lookup_transitions(enum state_codes, enum ret_codes);
/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};
enum ret_codes { ok, fail, repeat};
struct transition {
enum state_codes src_state;
enum ret_codes ret_code;
enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
{entry, ok, foo},
{entry, fail, end},
{foo, ok, bar},
{foo, fail, end},
{foo, repeat, foo},
{bar, ok, end},
{bar, fail, end},
{bar, repeat, foo}};
int main(int argc, char *argv[]) {
enum state_codes cur_state = entry;
enum ret_codes rc;
int (* state_fun)(void);
for (;;) {
state_fun = state[cur_state];
rc = state_fun();
if (end == cur_state)
break;
cur_state = lookup_transitions(cur_state, rc);
}
return EXIT_SUCCESS;
}
/*
* lookup_transition() function has time complexity of class O(n).
* We can optimize it.
* */
enum state_codes
lookup_transitions(enum state_codes cur_state, enum ret_codes rc)
{
#if 0
switch (cur_state) {
case entry:
cur_state = ((rc == ok) ? (foo) : (end));
break;
case foo:
cur_state = ((rc == ok) ? (bar) : ((rc == fail) ? (end) : (foo)));
break;
default:
cur_state = ((rc == ok) ? (end) : ((rc == fail) ? (end) : (foo)));
break;
}
return cur_state;
#else
char arr_size = (sizeof(state_transitions) / sizeof(state_transitions[0])); /* This can be shifted to main function to avoid redundant job. */
char count;
for (count = 0; count < arr_size; count++) {
if ((state_transitions[count].src_state == cur_state) && (state_transitions[count].ret_code == rc)) {
return (state_transitions[count].dst_state);
}
}
#endif
}
int entry_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN ENTRY STATE.\nEnter 0/1: ");
scanf("%d", &st);
rc = ((st == 1) ? (fail) : (ok));
return rc;
}
int foo_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN FOO STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int bar_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN BAR STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int exit_state(void)
{
printf("YOU ARE IN EXIT STATE.\n");
exit(EXIT_SUCCESS);
}

- 75
- 1
- 4
-
no it is copied from github website.. and i wrote for lookup_transtion code. Almost all know that it is copied from github. that is the first search result in google. https://gist.github.com/nmandery/1717405 and keep in mind that copied from git hub. that stackoverflow answer also copied from there. look at lookup_transition functiom... i pasted here for that.. – Ashutosh Tiwari May 28 '17 at 22:29
-
Along with loopup_transtion function, I have written small UT code for testing also.and dont conclude so quickly.. "just copied" at least understand the difference. and you arite your own and feel like toper.. needed for student... – Ashutosh Tiwari May 28 '17 at 22:34
-
I dont know shino, why you are not able to see the difference. It is copied. that's open. but please find the missing lookup function and UT code... – Ashutosh Tiwari May 28 '17 at 22:36
-
okay. fine. i am not going to discuss here who wrote first. But that is sure I wrote in last.. and my concern is not about that code.. it's about the lookup_transtion function and test UT code..just once compare the code..wil come to know what was missing in that.(github code)/.. – Ashutosh Tiwari May 28 '17 at 22:40