State Machines with C Callbacks

来源:互联网 发布:乐乎的图片怎么保存 编辑:程序博客网 时间:2024/05/22 04:41

State Machine with Function Pointers

转自:http://codeandlife.com/2013/10/06/tutorial-state-machines-with-c-callbacks/

Now how do we benefit from function pointers in the context of a state machine? Simple, just wrap the processing for a given state as a function, and call that:

#include <avr/io.h>
#define F_CPU 20000000UL
#include <util/delay.h>

// States
void led_on();
void led_off();

// State pointer
void (*statefunc)() = led_on;

void led_on() {
  PORTB
|= 1;
  statefunc
= led_off;
}

void led_off() {
  PORTB
&= ~1;
  statefunc
= led_on;
}

int main() {
  DDRB
|= 1;

 
while(1) {
   
(*statefunc)();
    _delay_ms
(1000); // sleep for a second
 
}

 
return 1; // should not get here
}

We can make one further addition: Instead of setting a global function pointer, let’s just have the state function to return a pointer to the next state function. This will make the code a bit cleaner with maybe a few clock cycle overhead. We’ll use a typedef and some type casting to make the code a little easier to read:

#include <avr/io.h>
#define F_CPU 20000000UL
#include <util/delay.h>

typedef void *(*StateFunc)();

// States
void *led_on();
void *led_off();

void *led_on() {
  PORTB
|= 1;
 
return led_off; // next state
}

void *led_off() {
  PORTB
&= ~1;
 
return led_on; // next state
}

int main() {
 
StateFunc statefunc = led_on;

  DDRB
|= 1;

 
while(1) {
    statefunc
= (StateFunc)(*statefunc)();
    _delay_ms
(1000); // sleep for a second
 
}

 
return 1; // should not get here
}

Anyone who can write the code below without a void pointer and a type cast, please give your solution in comments, I’d be interested to see the exact line to do it (extra points if you can typedef the StateFunc as a function pointer that returns a function pointer)!

对状态机的转换函数可以写得抽象写,利用状态机转换表的形式。比如:

/*Stat1Stat2Stat3Stat4Stat1  0       1       1      0Stat2  0       0       1      0Stat3  1       1       0      0Stat4  0       0       1      0*/bool stateTable[4][4]={false};typedef void *(*StateFunc)();// Statesvoid *S1();void *S2();void *S3();void *S4();void *S1() {if(stateTable[0][1]==true)return S2;else if (stateTable[0][2]==true)return S3;elsereturn S1;}void *S2() {if(stateTable[0][2]==true)return S3;elsereturn S2;}void *S3() {if(stateTable[0][0]==true)return S1;else if (stateTable[0][1]==true)return S2;elsereturn S3;}void *S4() {if(stateTable[0][3]==true)return S3;elsereturn S4;}int main() {  StateFunc statefunc = S1;  while(1) {modifystateTable();//modify stateTable according to situations    statefunc = (StateFunc)(*statefunc)();    _delay_ms(1000); // sleep for a second  }  return 1; // should not get here}



0 0
原创粉丝点击