当前位置:首页 > 嵌入式 > 嵌入式大杂烩
[导读]星标「嵌入式大杂烩」,一起进步!来源:www.cnblogs.com/autosar/archive/2012/06/22/2558604.html状态机模式是一种行为模式,在《设计模式》这本书中对其有详细的描述,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式...





状态机模式是一种行为模式,在 《设计模式》这本书中对其有详细的描述,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式环境下,有时只能写纯C代码,并且还需要考虑代码的重入和多任务请求跳转等情形,因此实现起来着实需要一番考虑。


近日在看了一个开源系统时,看到了一个状态机的实现,也学着写了一个,与大家分享。


首先,分析一下一个普通的状态机究竟要实现哪些内容。


状态机存储从开始时刻到现在的变化,并根据当前输入,决定下一个状态。这意味着,状态机要存储状态、获得输入(我们把它叫做跳转条件)、做出响应。


如上图所示,{s1, s2, s3}均为状态,箭头c1/a1表示在s1状态、输入为c1时,跳转到s2,并进行a1操作。


最下方为一组输入,状态机应做出如下反应:


当某个状态遇到不能识别的输入时,就默认进入陷阱状态,在陷阱状态中,不论遇到怎样的输入都不能跳出。


为了表达上面这个自动机,我们定义它们的状态和输入类型:


typedef int State;
typedef int Condition;

#define STATES 3   1
#define STATE_1 0
#define STATE_2 1
#define STATE_3 2
#define STATE_TRAP 3

#define CONDITIONS 2
#define CONDITION_1 0
#define CONDITION_2 1
在嵌入式环境中,由于存储空间比较小,因此把它们全部定义成宏。此外,为了降低执行时间的不确定性,我们使用O(1)的跳转表来模拟状态的跳转。


首先定义跳转类型:


typedef void (*ActionType)(State state, Condition condition);

typedef struct
{

State next;
ActionType action;
} Trasition, * pTrasition;
然后按照上图中的跳转关系,把三个跳转加一个陷阱跳转先定义出来:


// (s1, c1, s2, a1)
Trasition t1 = {
STATE_2,
action_1
};

// (s2, c2, s3, a2)
Trasition t2 = {
STATE_3,
action_2
};

// (s3, c1, s2, a3)
Trasition t3 = {
STATE_2,
action_3
};

// (s, c, trap, a1)
Trasition tt = {
STATE_TRAP,
action_trap
};
其中的动作,由用户自己完成,在这里仅定义一条输出语句。


void action_1(State state, Condition condition)
{
printf("Action 1 triggered.\n");
}
最后定义跳转表:


pTrasition transition_table[STATES][CONDITIONS] = {
/*      c1,  c2*/
/* s1 */
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读
关闭