一、狀態(tài)機(jī)實(shí)現(xiàn)的要素
首先,分析一下一個(gè)普通的狀態(tài)機(jī)究竟要實(shí)現(xiàn)哪些內(nèi)容。
狀態(tài)機(jī)存儲(chǔ)從開(kāi)始時(shí)刻到現(xiàn)在的變化,并根據(jù)當(dāng)前輸入,決定下一個(gè)狀態(tài)。這意味著,狀態(tài)機(jī)要存儲(chǔ)狀態(tài)、獲得輸入(我們把它叫做跳轉(zhuǎn)條件)、做出響應(yīng)。
托福改分 如上所示,{s1, s2, s3}均為狀態(tài),箭頭c1/a1表示在s1狀態(tài)、輸入為c1時(shí),跳轉(zhuǎn)到s2,并進(jìn)行a1操作。
托福答案 最下方為一組輸入,狀態(tài)機(jī)應(yīng)做出如下反應(yīng):
當(dāng)前狀態(tài) 輸入 下一個(gè)狀態(tài) 動(dòng)作
s1 c1 s2 a1
s2 c2 s3 a2
s3 c1 s2 a3
s2 c2 s3 a2
s3 c1 s2 a3
s2 c1 s_trap a_trap
s_trap c1 s_trap a_trap
當(dāng)某個(gè)狀態(tài)遇到不能識(shí)別的輸入時(shí),就默認(rèn)進(jìn)入陷阱狀態(tài),在陷阱狀態(tài)中,不論遇到怎樣的輸入都不能跳出。
為了表達(dá)上面這個(gè)自動(dòng)機(jī),我們定義它們的狀態(tài)和輸入類(lèi)型:
typedef 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
總結(jié)一下,我們需要定義的有狀態(tài)、輸入、行為(動(dòng)作+下一個(gè)狀態(tài)),其中,行為的個(gè)數(shù)是"狀態(tài)數(shù)*輸入數(shù)量"(其中有一些是重復(fù)的);其中動(dòng)作一般來(lái)說(shuō)可以用一個(gè)函數(shù)指針來(lái)實(shí)現(xiàn)。
二、具體設(shè)計(jì)
在嵌入式環(huán)境中,由于存儲(chǔ)空間比較小,因此把它們?nèi)慷x成宏。此外,為了降低執(zhí)行時(shí)間的不確定性,我們使用O(1)的跳轉(zhuǎn)表來(lái)模擬狀態(tài)的跳轉(zhuǎn)。
首先定義跳轉(zhuǎn)類(lèi)型:
typedef void (*actiontype)(state
mystate, condition condition);
typedef struct
{
state
next;
actiontype
action;
}
trasition, * ptrasition;
然后按照上圖中的跳轉(zhuǎn)關(guān)系,把三個(gè)跳轉(zhuǎn)加一個(gè)陷阱跳轉(zhuǎn)先定義出來(lái):
//
?。╯1, c1, s2, a1)
trasition
t1 = {
STATE2,
action1
};
//
(s2, c2, s3, a2)
trasition
t2 = {
STATE3,
action2
};
//
?。╯3, c1, s2, a3)
trasition
t3 = {
STATE2,
action3
};
//
?。╯, c, trap, a1)
trasition
tt = {
STATETRAP,
actiontrap
};
其中的動(dòng)作,由用戶(hù)自己完成,在這里僅定義一條輸出語(yǔ)句。
void action1(State
state, Condition condition)
{
printf("Action
1 triggered.\n");
}
1
最后定義跳轉(zhuǎn)表:
asition
transition_table[STATES][CONDITIONS] = {
/*
c1, c2*/
/*
s1 */&t1,
&tt,
/*
s2 */&tt,
&t2,
/*
s3 */&t3,
&tt,
/*
st */&tt,
&tt,
};
即可表達(dá)上文中的跳轉(zhuǎn)關(guān)系。
最后定義狀態(tài)機(jī),如果不考慮多任務(wù)請(qǐng)求,那么狀態(tài)機(jī)僅需要存儲(chǔ)當(dāng)前狀態(tài)便行了。例如:
typedef 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;
}
總結(jié):我們現(xiàn)在設(shè)計(jì)實(shí)現(xiàn)好了一個(gè)狀態(tài)機(jī),然后要給這個(gè)狀態(tài)機(jī)特定的輸入,看看狀態(tài)機(jī)的運(yùn)轉(zhuǎn)情況,以上面圖中的那個(gè)狀態(tài)機(jī)為例,我們輸入的序列是0和1分別代表c1和C2,然后狀態(tài)s1,s2分別對(duì)應(yīng)0,1.用程序?qū)崿F(xiàn)這個(gè)內(nèi)容如下
三、程序?qū)崿F(xiàn)
程序清單:小型狀態(tài)機(jī)的實(shí)現(xiàn)
[cpp
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
typedef int state;
typedef int condition;
#define STATENUM 4
#define STATE1 0
#define STATE2 1
#define STATE3 2
#define STATETRAP 3
#define CONDITIONS 2
#define CONDITION1 0
#define CONDITION2 1
typedef void (* actiontype)(state mystate,condition mycondition);
typedef struct{
state next;
actiontype action;
}trasition, *ptrasition;
void action1(state mystate,condition myconditon);
void action2(state mystate,condition myconditon);
void action3(state mystate,condition myconditon);
void actiontrap(state mystate,condition myconditon);
trasition t1={
STATE2,action1
};
trasition t2={
STATE3,action2
};
trasition t3={
STATE2,action3
};
trasition tt={
STATETRAP,actiontrap
};
void action1(state mystate,condition myconditon){
printf("action1 one triggered\n");
}
void action2(state mystate,condition myconditon){
printf("action2 one triggered\n");
}
void action3(state mystate,condition myconditon){
printf("action3 one triggered\n");
}
void actiontrap(state mystate,condition myconditon){
printf("actiontrap one triggered\n");
}
ptrasition transition_table[STATENUM][CONDITIONS] = {
/* c1, c2*/
/* s1 */&t1, &tt,
/* s2 */&tt, &t2,
/* s3 */&t3, &tt,
/* st */&tt, &tt,
};
typedef struct
{
state current;
} StateMachine, * pStateMachine;
state step(pStateMachine machine, condition mycondition)
{
ptrasition t = transition_table[machine->current][mycondition];
?。?(t->action))(machine->current, mycondition);
machine->current = t->next;
printf("the current state is %d\n",t->next );
return machine->current;
}
int main(int argc, char *argv[])
{
StateMachine mymachine;
mymachine.current=STATE1;
int mycon;
char ch;
while(1){
scanf("%d",&mycon);
step(&mymachine,mycon);
}
return 0;
}