sm005 state machine in C

  • Based on array with addresses of function states

  • simple state variable

  • the one I would use

raw

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>



// msg block between or to from states
#define NRPARM 4

typedef struct stateMsg {
	int parm[NRPARM];
} stateMsg;

typedef enum {INIT,LEDON,LEDOFF} stateTp;

stateTp init(stateMsg * msg);
stateTp ledOn(stateMsg * msg);
stateTp ledOff(stateMsg * msg);

// NB same order as in stateTp enum !
const stateTp (*stateFunc[])(struct stateMsg *ss) = {init, ledOn, ledOff};
//                             state         INIT  LEDON  LEDOFFs    ...


stateTp init(stateMsg * msg)
{
	printf("\ninit\n");
	msg->parm[0]++;

	sleep(1);

	return LEDON;
}

stateTp ledOn(stateMsg * msg)
{
	printf("\nledOn\n");
	msg->parm[1]++;

	sleep(1);

 	return LEDOFF;
}

stateTp ledOff(stateMsg * msg)
{
	printf("\nledOff\n");
	msg->parm[2]++;

	sleep(1);

	return LEDON;
}

void dumpVars(stateMsg * msg)
{
	printf("\ndumpVars in state variable: ");
	for (int i = 0; i < NRPARM; i++) {
		printf("%i ", msg->parm[i]);
	}
}

int main()
{
	stateMsg m;
	stateTp s;
	for (int i = 0 ; i < NRPARM; i++) {
		m.parm[i] = 0;
	}

	s = INIT;

	printf("\nstarting state machine\n");

	while (1) {
		printf("\nback in scheduler");
		dumpVars(&m); // debug :-)

		s = (*stateFunc[s])(&m);  // ce state switch
	}
}