用C语言实现有限状态自动机FSM
摘要:状态机模式是一种行为模式,在《设计模式》这本书中对其有详细的描述,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式环境下,有时只能写纯C代码,并且还需要考虑代码的重入和多任务请求跳转等情形,因此实现起来着实需要一番考虑。本文主要为你实现一个简单的有限状态机,没有考虑代码的重入和多任务跳转,为以后复杂的状态机实现,打下基础。
本文来源:用C语言实现有限状态自动机FSM
首先,分析一下一个普通的状态机究竟要实现哪些内容。
状态机存储从开始时刻到现在的变化,并根据当前输入,决定下一个状态。这意味着,状态机要存储状态、获得输入(我们把它叫做跳转条件)、做出响应。

如上图所示,{s1, s2, s3}均为状态,箭头c1/a1表示在s1状态、输入为c1时,跳转到s2,并进行a1操作。
最下方为一组输入,状态机应做出如下反应:
当前状态输入下一个状态动作s1c1s2a1s2c2s3a2s3c1s2a3s2c2s3a2s3c1s2a3s2c1s_trapa_traps_trapc1s_trapa_trap
当某个状态遇到不能识别的输入时,就默认进入陷阱状态,在陷阱状态中,不论遇到怎样的输入都不能跳出。
为了表达上面这个自动机,我们定义它们的状态和输入类型:
123456789101112typedef int state;typedef int condition; #define STATES 4#define STATE1 0#define STATE2 1#define STATE3 2#define STATETRAP 3 #define CONDITIONS 2#define CONDITION1 0#define CONDITION2 1总结一下,我们需要定义的有状态、输入、行为(动作+下一个状态),其中,行为的个数是“状态数*输入数量”(其中有一些是重复的);其中动作一般来说可以用一个函数指针来实现。
在嵌入式环境中,由于存储空间比较小,因此把它们全部定义成宏。此外,为了降低执行时间的不确定性,我们使用O(1)的跳转表来模拟状态的跳转。
首先定义跳转类型:
1234567typedef void (*actiontype)(state mystate, condition condition); typedef struct{ state next; actiontype action;} trasition, * ptrasition;
然后按照上图中的跳转关系,把三个跳转加一个陷阱跳转先定义出来:
1234567891011121314151617181920212223// (s1, c1, s2, a1)trasition t1 = { STATE2, action1}; // (s2, c2, s3, a2)trasition t2 = { STATE3, action2}; // (s3, c1, s2, a3)trasition t3 = { STATE2, action3}; // (s, c, trap, a1)trasition tt = { STATETRAP, actiontrap};
其中的动作,由用户自己完成,在这里仅定义一条输出语句。
1234void action1(State state, Condition condition){ printf("Action 1 triggered.\n");}1最后定义跳转表:1234567ptrasition transition_table[STATES][CONDITIONS] = {/* c1, c2*//* s1 */&t1, &tt,/* s2 */&tt, &t2,/* s3 */&t3, &tt,/* st */&tt, &tt,};
即可表达上文中的跳转关系。
最后定义状态机,如果不考虑多任务请求,那么状态机仅需要存储当前状态便行了。例如:
123456789101112typedef struct{ State current;} StateMachine, * pStateMachine; State step(pStateMachine machine, Condition condition){ pTrasition t = transition_table[machine->current][condition]; (*(t->action))(machine->current, condition); machine->current = t->next; return machine->current;}
四、外部参考【1】嵌入式设计模式:有限状态自动机的C语言实现 http://www.cnblogs.com/autosar/archive/2012/06/22/2558604.html