有限狀態自動機的C語言實現

2021-08-21 12:41:25 字數 4089 閱讀 2648

嵌入式設計模式:有限狀態自動機的c語言實現

狀態機模式是一種行為模式,在《設計模式》這本書中對其有詳細的描述,通過多型實現不同狀態的調轉行為的確是一種很好的方法,只可惜在嵌入式環境下,有時只能寫純c**,並且還需要考慮**的重入和多工請求跳轉等情形,因此實現起來著實需要一番考慮。

近日在看了乙個開源系統時,看到了乙個狀態機的實現,也學著寫了乙個,與大家分享。

首先,分析一下乙個普通的狀態機究竟要實現哪些內容。

狀態機儲存從開始時刻到現在的變化,並根據當前輸入,決定下乙個狀態。這意味著,狀態機要儲存狀態、獲得輸入(我們把它叫做跳轉條件)、做出響應。

如上圖所示,均為狀態,箭頭c1/a1表示在s1狀態、輸入為c1時,跳轉到s2,並進行a1操作。

最下方為一組輸入,狀態機應做出如下反應:

當前狀態

輸入下乙個狀態

動作s1

c1s2

a1s2

c2s3

a2s3

c1s2

a3s2

c2s3

a2s3

c1s2

a3s2

c1s_trap

a_trap

s_trap

c1s_trap

a_trap

當某個狀態遇到不能識別的輸入時,就預設進入陷阱狀態,在陷阱狀態中,不論遇到怎樣的輸入都不能跳出。

為了表達上面這個自動機,我們定義它們的狀態和輸入型別:

typedefintstate;

typedefintcondition;

#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)的跳轉表來模擬狀態的跳轉。

首先定義跳轉型別:

typedefvoid(*actiontype)(state state, condition condition);

typedefstruct

trasition, * ptrasition;

然後按照上圖中的跳轉關係,把三個跳轉加乙個陷阱跳轉先定義出來:

// (s1, c1, s2, a1)

trasition t1 = ;

// (s2, c2, s3, a2)

trasition t2 = ;

// (s3, c1, s2, a3)

trasition t3 = ;

// (s, c, trap, a1)

trasition tt = ;

其中的動作,由使用者自己完成,在這裡僅定義一條輸出語句。

voidaction_1(state state, condition condition)

最後定義跳轉表:

ptrasition transition_table[states][conditions] = ;

即可表達上文中的跳轉關係。

最後定義狀態機,如果不考慮多工請求,那麼狀態機僅需要儲存當前狀態便行了。例如:

typedefstruct

statemachine, * pstatemachine;

state step(pstatemachine machine, condition condition)

但是考慮到當乙個跳轉正在進行的時候,同時又有其他任務請求跳轉,則會出現資料不一致的問題。

舉個例子:task1(s1, c1/a1 –> s2)和task2(s2, c2/a2 –> s3)先後執行,是可以順利到達s3狀態的,但若操作a1執行的時候,執行許可權被task2搶占,則task2此時看到的當前狀態還是s1,s1遇到c2就進入陷阱狀態,而不會到達s3了,也就是說,狀態的跳**生了不確定,這是不能容忍的。

因此要重新設計狀態機,增加乙個「事務中」條件和乙個用於儲存輸入的條件佇列。修改後的**如下:

#define e_ok        0

#define e_no_data   1

#define e_overflow  2

typedefstruct

conditionqueue, * pconditionqueue;

intpush(conditionqueue * queue, condition c)

else

returne_ok;

}

intpoll(conditionqueue * queue, condition * c)

else

returne_ok;

}

typedefstruct

statemachine, * pstatemachine;

staticstate __step(pstatemachine machine, condition condition)

state step(pstatemachine machine, condition condition)

else

machine->intransaction =false;

returncurrent;

}

}

voidinitialize(pstatemachine machine, state s)

**

有限狀態自動機

有限自動機是更一般化的狀態轉化圖。分為確定有限自動機 dfa 和不確定有限自動機 nfa m s,f,so,z 其中 下圖為乙個確定的有限狀態自動機 m s,f,so,z 其中 下圖為乙個不確定的有限狀態自動機 說了半天其實它們的本質區別就在於s0,確定的有限狀態自動機的s0是唯一確定的。而不確定的...

有限狀態自動機

有限自動機是更一般化的狀態轉化圖。分為確定有限自動機 dfa 和不確定有限自動機 nfa m s,f,so,z 其中 下圖為乙個確定的有限狀態自動機 m s,f,so,z 其中 下圖為乙個不確定的有限狀態自動機 說了半天其實它們的本質區別就在於s0,確定的有限狀態自動機的s0是唯一確定的。而不確定的...

有限狀態自動機

背景提要 星期三的時候,xw交給我乙個點燈的任務 大意是乙個玩意單擊的時候如何如何,長按又如何如何,雙擊又如何如何,幾種狀態分別執行不同的操作。這就導致了一種情況 在機器第一次檢測到按鈕被按下時,我們無法做出論斷 我們不知道這是一次雙擊還是長按還是單擊,我們只能靜觀其變,見機行事。但是按鈕被按下時,...