狀態(tài)機(jī)原理及用法_圖文_第1頁(yè)
狀態(tài)機(jī)原理及用法_圖文_第2頁(yè)
狀態(tài)機(jī)原理及用法_圖文_第3頁(yè)
狀態(tài)機(jī)原理及用法_圖文_第4頁(yè)
狀態(tài)機(jī)原理及用法_圖文_第5頁(yè)
已閱讀5頁(yè),還剩40頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、狀態(tài)機(jī)模塊Yanping Huang黃燕平狀態(tài)機(jī)模塊.xml Status MachineCopyright©2006 Yanping Huang 2 / 36 Page目錄1、術(shù)語(yǔ) (31.1、參考文獻(xiàn) (32、內(nèi)容摘要 (32.1、狀態(tài)機(jī)概念 (32.2、狀態(tài)機(jī)其他 (42.2.1、狀態(tài)機(jī)類(lèi)型 (42.2.2、狀態(tài)機(jī)的描述手法 (42.2.3、狀態(tài)機(jī)特殊定義說(shuō)明 (43、狀態(tài)機(jī)實(shí)現(xiàn)方式選擇 (83.1、HSM 函數(shù)方式 (83.2、uHsm 結(jié)構(gòu)方式 (83.3、uHsm 設(shè)計(jì)事項(xiàng) (94、狀態(tài)機(jī)功能庫(kù)用法 (134.1、第一步設(shè)計(jì)狀態(tài)圖 (134.2、定義自己的狀態(tài)機(jī)需要的定制

2、數(shù)據(jù) (134.3、實(shí)現(xiàn)狀態(tài)機(jī) (144.3.1、包含狀態(tài)機(jī)頭 (144.3.2、預(yù)定義狀態(tài)函數(shù) (144.3.3、狀態(tài)機(jī)中事件定義 (144.3.4、定義狀態(tài)編號(hào) (144.3.5、定義狀態(tài)數(shù)據(jù)表 (154.3.5、定義狀態(tài)函數(shù) (154.4、使用狀態(tài)機(jī) (184.4.1、函數(shù)環(huán)境中使用 (184.4.2、中斷環(huán)境中使用 (194.4.3、使用狀態(tài)機(jī)的附加說(shuō)明 (205、可擴(kuò)充功能的模式 (206、狀態(tài)機(jī)框架 (217、基于狀態(tài)機(jī)的并發(fā)設(shè)計(jì) (227.1、并發(fā)模式的反省 (227.2、概要設(shè)計(jì) (25狀態(tài)機(jī)模塊.xml 狀態(tài)機(jī)1、術(shù)語(yǔ)狀態(tài)機(jī):有限狀態(tài)機(jī):HSM:層次化狀態(tài)機(jī)uHsm:嵌入式層

3、次化狀態(tài)機(jī)Virtual Bus:虛擬總線(xiàn)VBus1.1、參考文獻(xiàn)Practical Statecharts in C/C+:Quantum Programming for Embedded Systems中文譯名:嵌入式系統(tǒng)的微模塊化程序設(shè)計(jì)實(shí)用狀態(tài)圖C/C+實(shí)現(xiàn)作者:Miro Samek Ph.D.翻譯:敬萬(wàn)鈞陳麗容出版:北京航空航天大學(xué)出版社譯名不太準(zhǔn)確,應(yīng)該是“實(shí)用C/C+狀態(tài)圖技術(shù)嵌入式系統(tǒng)量子編程”。其中“量子”一詞在書(shū)中有特別涵義。或者簡(jiǎn)單點(diǎn)“實(shí)用嵌入式狀態(tài)圖技術(shù)”。2、內(nèi)容摘要2.1、狀態(tài)機(jī)概念狀態(tài)圖邏輯中,涉及到層次化問(wèn)題。最古老的狀態(tài)圖的代碼實(shí)現(xiàn)是用嵌套switch語(yǔ)句實(shí)現(xiàn)

4、,但是狀態(tài)圖層次超過(guò)2層后,這種試想方法代碼太過(guò)復(fù)雜,不實(shí)用。還有一種辦法用C+等面向?qū)ο蟮?、有繼承能力的技術(shù)實(shí)現(xiàn)狀態(tài)機(jī)中的狀態(tài),這非常符合狀態(tài)圖中不同層次狀態(tài)的繼承關(guān)系,但是有其他缺陷。Miro先生的HSM采用函數(shù)方式定義狀態(tài),極大優(yōu)化了狀態(tài)機(jī)的實(shí)現(xiàn),但是也有一些缺陷待改進(jìn)。描述一種新型的狀態(tài)機(jī)模塊(uHsm實(shí)現(xiàn)方法,更好地實(shí)現(xiàn)了狀態(tài)機(jī),并且從綜合折中考察,具有相當(dāng)?shù)谋容^優(yōu)勢(shì)。主要的優(yōu)勢(shì)是邏輯嚴(yán)密、性能高效、對(duì)狀態(tài)圖的運(yùn)作最接近狀態(tài)圖理論的理想概念,因而需要特別處理(因此也就特別容易產(chǎn)生偏差的邏輯點(diǎn)少,特別適合運(yùn)行穩(wěn)定性高、資源不豐富的嵌入式環(huán)境。版權(quán)所有©2006 黃燕平第3頁(yè)/

5、共36頁(yè)狀態(tài)機(jī)模塊.xml Status MachineCopyright©2006 Yanping Huang 4 / 36 Page2.2、狀態(tài)機(jī)其他2.2.1、狀態(tài)機(jī)類(lèi)型狀態(tài)機(jī)描述的狀態(tài)有兩種大類(lèi),一類(lèi)是任務(wù)運(yùn)行似的邏輯。這種狀態(tài)圖的狀態(tài)通常是任務(wù)在等待某個(gè)條件達(dá)到,也就是任務(wù)處于“等待狀態(tài)”。通常任務(wù)本身是直接推動(dòng)狀態(tài)機(jī)運(yùn)作的發(fā)動(dòng)機(jī),任務(wù)本身檢查狀態(tài)機(jī)的事件達(dá)到情況并進(jìn)行分發(fā)。任務(wù)狀態(tài)的變遷由某個(gè)事件的達(dá)成觸發(fā),可能要求任務(wù)間同步機(jī)制ITC 具有回調(diào)能力,以便在條件成立時(shí)向狀態(tài)機(jī)事件隊(duì)列中壓入事件。這種狀態(tài)機(jī)明顯有異步邏輯特征,稱(chēng)為“異步類(lèi)狀態(tài)機(jī)”。第二種類(lèi)型是算法邏輯,利用

6、狀態(tài)機(jī)邏輯清晰的特性描述復(fù)雜的算法。該狀態(tài)機(jī)通常嵌入在某個(gè)算法函數(shù)類(lèi)部,幫助該函數(shù)完成功能。函數(shù)入口后,模擬任務(wù)等具有主動(dòng)性的實(shí)體,向狀態(tài)機(jī)分發(fā)事件。這種狀態(tài)機(jī)明顯有同步函數(shù)調(diào)用特征,稱(chēng)為“同步類(lèi)狀態(tài)機(jī)”。同步狀態(tài)機(jī)的一次事件過(guò)程就是一次入口函數(shù)調(diào)用過(guò)程。入口函數(shù)調(diào)用返回時(shí),狀態(tài)機(jī)必須處于一個(gè)明確定義的狀態(tài),不能是不確定的中間狀態(tài)。無(wú)論異步還是同步,特別是對(duì)異步狀態(tài)機(jī)而言,狀態(tài)機(jī)內(nèi)部不能在某個(gè)狀態(tài)發(fā)生等待、阻塞等情況,而應(yīng)該是標(biāo)記狀態(tài)后返回,把執(zhí)行的機(jī)會(huì)讓給其他任務(wù)或邏輯體(狀態(tài)機(jī)的驅(qū)動(dòng)實(shí)體。之后在條件達(dá)到的情況下,通過(guò)事件分發(fā)機(jī)構(gòu)調(diào)動(dòng)狀態(tài)機(jī)的運(yùn)行。2.2.2、狀態(tài)機(jī)的描述手法1、 引入流程圖

7、:應(yīng)該考慮在狀態(tài)機(jī)描述工具中引入流程圖。2、 內(nèi)部流程外化表示:還應(yīng)該考慮狀態(tài)內(nèi)部過(guò)程用虛線(xiàn)引出、引入,這樣方便在圖示中說(shuō)明邏輯。3、 在狀態(tài)中放置一個(gè)表示狀態(tài)私有數(shù)據(jù)的塊,對(duì)其虛線(xiàn)引用表示讀取或操作它。歷史數(shù)據(jù)記錄也是其中的一個(gè)特例。此處的歷史數(shù)據(jù)有別于經(jīng)典的歷史偽狀態(tài),參見(jiàn)下一屆對(duì)“歷史”的描述。4、 如果狀態(tài)圖描述工具能夠自動(dòng)檢查超態(tài)已經(jīng)定義的事件處理,并避免子態(tài)重新定義,則非常有幫助。包括超態(tài)已經(jīng)定義的內(nèi)部轉(zhuǎn)換或自轉(zhuǎn)換事件處理。5、 如果狀態(tài)圖工具能夠給出狀態(tài)機(jī)實(shí)現(xiàn)的框架代碼,將會(huì)非常有利于編程設(shè)計(jì)。如果修改代碼的框架部分,能夠同步回設(shè)計(jì)方案中,則幫助更大??蚣懿糠职ň唧w狀態(tài)機(jī)定義、

8、狀態(tài)描述數(shù)據(jù)表的生成、狀態(tài)函數(shù)的基本switch 結(jié)構(gòu)、監(jiān)控條件結(jié)構(gòu)、狀態(tài)轉(zhuǎn)換語(yǔ)句等。反向工程的這部工作如果是代碼編寫(xiě)工具被替換掉,則會(huì)容易很多。也就是一個(gè)中間編寫(xiě)工具,負(fù)責(zé)銜接模型和具體代碼兩邊。完全拒絕用戶(hù)自己直接編寫(xiě)代碼。2.2.3、狀態(tài)機(jī)特殊定義說(shuō)明1、 進(jìn)入事件:“轉(zhuǎn)換到達(dá)后”狀態(tài)“收到”的第一個(gè)事件,準(zhǔn)確地說(shuō)應(yīng)該稱(chēng)為“進(jìn)入通知事件”。表示通知該狀態(tài),已經(jīng)進(jìn)來(lái)了,以便做一些“初始化處理”(注意不是初始化轉(zhuǎn)換。之后才收到“初始轉(zhuǎn)換”事件,在已經(jīng)完成初步處理基礎(chǔ)上,立即進(jìn)行進(jìn)一步的狀態(tài)機(jī)模塊.xml 狀態(tài)機(jī) 版權(quán)所有©2006 黃燕平 第5頁(yè)/共36頁(yè)2 5 67 和 1234

9、56123、頂層狀態(tài)從狀態(tài)圖邏輯上來(lái)說(shuō)是不處理事件的,但是uHsm把頂層狀態(tài)暴露給讀者,讓讀者有一個(gè)控制各如果點(diǎn)地機(jī)會(huì)。通常用其“進(jìn)入”事件處理作為整個(gè)狀態(tài)機(jī)的初始化 圖文6、可能的狀態(tài)轉(zhuǎn)換方式13、從源到目標(biāo)的路徑最多15層。并不一定意味著狀態(tài)機(jī)只能15層,但是狀態(tài)圖如果達(dá)到15層,則需要仔細(xì)檢查。為簡(jiǎn)化邏輯,規(guī)定只能有15層,包括頂層在內(nèi)。14、需要說(shuō)明的邏輯還有在流程中激發(fā)其他事件的手法問(wèn)題。實(shí)際上不是激發(fā)本狀態(tài)當(dāng)前處理,而是壓入事件隊(duì)列之后不管,等到轉(zhuǎn)換完成后交給執(zhí)行體去分發(fā)。這需要構(gòu)思狀態(tài)圖的工程師注意這個(gè)邏輯,不要認(rèn)為是激發(fā)為當(dāng)前狀態(tài)立即處理的事件。15、根據(jù)2.2.3小節(jié)的定義,

10、事件處理的寫(xiě)法一定是所有的功能寫(xiě)完之后,才調(diào)用轉(zhuǎn)換功能,以判斷和動(dòng)作在源狀態(tài)環(huán)境執(zhí)行的要求。16、內(nèi)部轉(zhuǎn)換容易造成邏輯上的漏洞。比如說(shuō),定義在超態(tài)的內(nèi)部轉(zhuǎn)換,要確保對(duì)子態(tài)來(lái)說(shuō)也是內(nèi)部轉(zhuǎn)換。如果對(duì)子態(tài)來(lái)說(shuō),期盼的是自轉(zhuǎn)換,而超態(tài)定義的又是內(nèi)部轉(zhuǎn)換,則很容易造成邏輯混淆。因此,要嚴(yán)格審核超態(tài)的內(nèi)部轉(zhuǎn)換是否對(duì)所有子態(tài)都是內(nèi)部轉(zhuǎn)換,特別是多層超態(tài)的上層內(nèi)部轉(zhuǎn)換。沒(méi)有必要的情況下,要嚴(yán)格限制內(nèi)部轉(zhuǎn)換的使用?;蛘咭獜?qiáng)調(diào)子態(tài)Entry、Exit事件處理的沒(méi)有“痕跡”記憶,這樣才能自由使用超態(tài)中的內(nèi)部處理,并在內(nèi)部處理中可以只有使用狀態(tài)轉(zhuǎn)換。17、uHsm是比較排斥執(zhí)行環(huán)境這個(gè)概念的,因此狀態(tài)處理函數(shù)應(yīng)該不依

11、賴(lài)于當(dāng)前狀態(tài)。圖3中的第4步,實(shí)際上就通過(guò)Entry的執(zhí)行,一步步把環(huán)境建立好了。最后state = target 操作僅僅是完成一個(gè)標(biāo)記性質(zhì)的操作。當(dāng)然,實(shí)際上是可以依賴(lài)環(huán)境也就是可以依賴(lài)Entry處理的執(zhí)行結(jié)果的。絕不能依賴(lài)的是狀態(tài)機(jī)當(dāng)前狀態(tài)值的具體數(shù)據(jù)這個(gè)數(shù)據(jù)成員項(xiàng)。 態(tài)退到主態(tài),只可能是投遞或橋型。從正常態(tài)進(jìn)入并存態(tài),不會(huì)是自轉(zhuǎn)、返父、返祖 mySM;如果這個(gè)頭文件完全不需要給客戶(hù)使用,上訴結(jié)構(gòu)也可以在后面的實(shí)現(xiàn)文件前部定義。4.3、實(shí)現(xiàn)狀態(tài)機(jī)實(shí)現(xiàn)狀態(tài)機(jī)的C文件按照之的要求編寫(xiě)如下:4.3.1、包含狀態(tài)機(jī)頭#include "mySM.h"4.3.2、預(yù)定義狀態(tài)函數(shù)

12、/狀態(tài)函數(shù)預(yù)定義static int _Top(SuHsm* pSM, const SuHsmEvent* pEvt;static int _S1(SuHsm* pSM, const SuHsmEvent* pEvt;static int _S2(SuHsm* pSM, const SuHsmEvent* pEvt;static int _S2_1(SuHsm* pSM, const SuHsmEvent* pEvt;static int _S2_2(SuHsm* pSM, const SuHsmEvent* pEvt;static int _EXIT(SuHsm* pSM, const Su

13、HsmEvent* pEvt; /自行設(shè)計(jì)的退出狀態(tài)函數(shù)4.3.3、狀態(tài)機(jī)中事件定義頭文件.h中定義/狀態(tài)機(jī)中事件定義#define EVT1 U_EVENT_USER + 1 /見(jiàn)uHsm.h頭文件定義#define EVT2 U_EVENT_USER + 2#define EVT3 U_EVENT_USER + 3#define EVT4 U_EVENT_USER + 4#define EVT5 U_EVENT_USER + 5#define EVT6 U_EVENT_USER + 64.3.4、定義狀態(tài)編號(hào)在c/定義狀態(tài)編號(hào)#define TOP_ 0#define S1_ 1#defi

14、ne S2_ 2#define S2_1_ 3#define S2_2_ 4#define EXIT_ 5為避免錯(cuò)誤和BUG,狀態(tài)編號(hào)的定義一定要按照0、1、2這樣的順序遞增定義。如果對(duì)狀態(tài)圖設(shè)計(jì)進(jìn)行了修改,此處的定義也要跟隨修改。并且必須保持TOP_為0,EXIT_為最后一個(gè)定義的結(jié)構(gòu)。4.3.5、定義狀態(tài)數(shù)據(jù)表C文件中定義/定義狀態(tài)數(shù)據(jù)表= /狀態(tài)數(shù)組,用const分配在代碼空間const SuState mySMTable5/如果不用const則分配在全局變量堆空間/自行根據(jù)MCU的情況決定_Top,/0:頂狀態(tài),必須有,必須在第一個(gè)位置TOP_,_S1, /1:S1狀態(tài)TOP_,_S2

15、, /2:S2狀態(tài)TOP_,/3:S2.1狀態(tài),超態(tài)為S2狀態(tài)S2_, _S2_1,S2_, _S2_2,/4:S2.2狀態(tài),超態(tài)為S2狀態(tài)/5:退出狀態(tài),必須有,任意位置TOP_,_EXIT/必須是TOP_作為其超態(tài)為避免錯(cuò)誤和BUG,此處數(shù)組的初始化定義,一定要按照4.3.4中狀態(tài)編號(hào)定義的順序。也就是說(shuō)此處數(shù)組初始化的每個(gè)子項(xiàng)的第二項(xiàng)必須保持前面同樣的定義順序。也就是此處的第二列必須保持前面一小節(jié)的順序。當(dāng)然,第一列定義的是狀態(tài)的超態(tài),也必須定義正確。TOP_狀態(tài)沒(méi)有超態(tài),用自己的編號(hào)代替。4.3.5、定義狀態(tài)函數(shù)/定義狀態(tài)函數(shù)static int _Top(SuHsm* pSM, co

16、nst SuHsmEvent* pEvtswitch(*pEvtcase U_EVENT_ENTRY:/top狀態(tài)的entry事件是初始化整個(gè)狀態(tài)機(jī)的機(jī)會(huì)/在狀態(tài)圖中設(shè)計(jì)時(shí)應(yīng)該相應(yīng)有說(shuō)明0;returncase U_EVENT_INIT:/top轉(zhuǎn)態(tài)的init事件通常執(zhí)行一些和進(jìn)入默認(rèn)轉(zhuǎn)態(tài)相關(guān)的動(dòng)作之后,轉(zhuǎn)入默認(rèn)轉(zhuǎn)態(tài) /執(zhí)行那些操作在狀態(tài)圖中應(yīng)該有說(shuō)明/注意,此處一定要return uHsmTran或者調(diào)用/uHsmTran之后return 1,否則會(huì)出現(xiàn)狀態(tài)操作錯(cuò)誤return uHsmTran(pSM, &mySMTableS_1;/轉(zhuǎn)到狀態(tài)S1 case U_EVENT_EXIT

17、:/狀態(tài)機(jī)退出、清理資源的一個(gè)機(jī)會(huì)0;returnreturn 1; /默認(rèn)處理,一個(gè)處理異常的最后機(jī)會(huì)static int _S1(SuHsm* pSM, const SuHsmEvent* pEvt(*pEvtswitchcase U_EVENT_ENTRY:/進(jìn)入初始化0;returncase U_EVENT_INIT:/葉子狀態(tài)必須返回1,表示沒(méi)有子狀態(tài)1;returncase U_EVENT_EXIT:0;returncase EVT1:/事件Evt1的各種處理&mySMTableS2_; /轉(zhuǎn)到狀態(tài)S2uHsmTran(pSM,0;/此處一定不能用return uHsmTr

18、anreturncase EVT2:/事件Evt2的各種處理&mySMTableS2_1_; /轉(zhuǎn)到狀態(tài)S2.1uHsmTran(pSM,0;returnreturn 1;static int _S2(SuHsm* pSM, const SuHsmEvent* pEvtswitch(*pEvtcase U_EVENT_ENTRY:/本狀態(tài)初始化0;returncase U_EVENT_INIT:/通常只單純處理轉(zhuǎn)換到默認(rèn)狀態(tài),/如果加了其他處理,很可能在特定情況下不能被調(diào)用到/因此,該狀態(tài)的初始化處理都應(yīng)該放到entry事件處理中/默認(rèn)轉(zhuǎn)換,每個(gè)超態(tài)都必須有默認(rèn)轉(zhuǎn)換uHsmTran(p

19、SM,&mySMTableS2_2_; /轉(zhuǎn)到狀態(tài)S2.2 returncase U_EVENT_EXIT:/退出本狀態(tài)處理0;returncase EVT3:/事件Evt3的各種處理&mySMTableS1_; /轉(zhuǎn)到狀態(tài)S1 uHsmTran(pSM,0;returncase EVT4:/事件Evt4的各種處理/轉(zhuǎn)到狀態(tài)EXIT&mySMTableEXIT_;uHsmTran(pSM,0;returnreturn 1;static int _S2_1(SuHsm* pSM, const SuHsmEvent* pEvt(*pEvtswitchcase U_EVENT

20、_ENTRY:/本狀態(tài)初始化0;returncase U_EVENT_INIT:/葉子狀態(tài)必須返回1,表示沒(méi)有子狀態(tài)1;returncase U_EVENT_EXIT:0;returncase EVT6:/事件Evt6的各種處理&mySMTableS2_2_; /轉(zhuǎn)到狀態(tài)S2.2 uHsmTran(pSM,0;returnreturn 1;static int _S2_2(SuHsm* pSM, const SuHsmEvent* pEvtswitch(*pEvtcase U_EVENT_ENTRY:/初始化本狀態(tài)return0;case U_EVENT_INIT:/葉子狀態(tài)必須返回1

21、,表示沒(méi)有子狀態(tài)1;returncase U_EVENT_EXIT:0;returncase EVT5:/事件Evt5的各種處理uHsmTran(pSM,&mySMTableS2_1_; /轉(zhuǎn)到狀態(tài)S2.10;returnreturn 1;static int _EXIT(SuHsm* pSM, const SuHsmEvent* pEvt/必須按照這個(gè)格式編寫(xiě)/退出狀態(tài)機(jī)處理,一個(gè)處理異常的機(jī)會(huì)return 1;4.4、使用狀態(tài)機(jī)狀態(tài)機(jī)實(shí)現(xiàn)之后就是如何使用的問(wèn)題,可以是在算法函數(shù)中使用也可以是在線(xiàn)程環(huán)境中使用。狀態(tài)機(jī)和可以嵌套狀態(tài)機(jī),比如說(shuō)在某個(gè)狀態(tài)的entry事件中初始化一個(gè)狀態(tài)機(jī)

22、,在其事件處理中給“子狀態(tài)機(jī)”(不是子狀態(tài)發(fā)送事件。此處按照在函數(shù)中使用和ISR方式使用進(jìn)行說(shuō)明,也就是在沒(méi)有任務(wù)的環(huán)境中的使用。后一種適合單片機(jī)、ARM處理器等不想要多任務(wù)的小型應(yīng)用環(huán)境中。函數(shù)環(huán)境中通常用一個(gè)main 函數(shù)來(lái)使用狀態(tài)機(jī),單片機(jī)、ARM如果沒(méi)有任務(wù),通常是在時(shí)鐘處理中斷ISR(或其他的特定于某應(yīng)用的經(jīng)常存在的中斷中使用狀態(tài)機(jī)。4.4.1、函數(shù)環(huán)境中使用#include "mySM.h"static myStateMach theSM; /應(yīng)用狀態(tài)機(jī)的靜態(tài)實(shí)例int main(void/應(yīng)用自身的初始化/uHsm要求的狀態(tài)機(jī)初始化,見(jiàn)4.3.5/此時(shí)狀態(tài)機(jī)已

23、經(jīng)進(jìn)入默認(rèn)的S1狀態(tài) uHsmInitSM(SuHsm*&theSM,mySMTable;while(1/通常應(yīng)用是一個(gè)大循環(huán),如果是中斷方式使用,不需要這個(gè)大循環(huán)/根據(jù)應(yīng)用發(fā)送各種事件/構(gòu)造要發(fā)送的事件EVT2;=evtSuHsmEvent&evtif(uHsmPostEvt(SuHsm*&theSM,/異?;驙顟B(tài)機(jī)按設(shè)計(jì)要求退出4.4.2、中斷環(huán)境中使用通常要事先在芯片入口初始化環(huán)境中準(zhǔn)備好狀態(tài)機(jī):#include "mySM.h"static myStateMach theSM; /應(yīng)用狀態(tài)機(jī)的靜態(tài)實(shí)例int main(void/應(yīng)用自身的初始

24、化/uHsm要求的狀態(tài)機(jī)初始化,見(jiàn)4.3.5/此時(shí)狀態(tài)機(jī)已經(jīng)進(jìn)入默認(rèn)的S1狀態(tài)mySMTable;uHsmInitSM(SuHsm*&theSM,/之后進(jìn)入死循環(huán)或休眠轉(zhuǎn)態(tài),有些處理器支持休眠狀態(tài)while(1;然后在中斷處理函數(shù)中進(jìn)行處理pinterrupter int TimerISR(int/中斷相關(guān)的初始化處理,如堆棧保護(hù)等./根據(jù)應(yīng)用發(fā)送各種事件/構(gòu)造要發(fā)送的事件SuHsmEvent evt = EVT2;if (uHsmPostEvt(SuHsm*&theSM, &evt/異常或狀態(tài)機(jī)按設(shè)計(jì)要求退出4.4.3、使用狀態(tài)機(jī)的附加說(shuō)明前面的使用說(shuō)明中,都沒(méi)有充分

25、利用“事件”,實(shí)際上事件可以客戶(hù)自行定義一個(gè)結(jié)構(gòu),只要保證第一個(gè)字段是SuHsmEvent 類(lèi)型的字段即可。(SuHsmEvent實(shí)際上就是一個(gè)整數(shù)例如:struct myEventsig;/保證是第一個(gè)字段SuHsmEventdword ndata;之后在事件處理函數(shù)(那些函數(shù)也是客戶(hù)自己編寫(xiě)的中,就可以使用自己定義的事件類(lèi)型。例如通常窗口函數(shù)帶有l(wèi)Param, wParam兩個(gè)參數(shù)等等。事件的實(shí)例動(dòng)態(tài)可以分配也可以靜態(tài)分配,完全視使用的方便而定。如果是在復(fù)雜環(huán)境中,特別是多任務(wù)、多狀態(tài)機(jī)的環(huán)境中使用,最好使用后續(xù)說(shuō)明的狀態(tài)機(jī)框架(uHsmFrame。該框架為狀態(tài)機(jī)執(zhí)行定義了事件隊(duì)列、事件訂

26、閱、事件分發(fā)等機(jī)制。使用的時(shí)候就可以更專(zhuān)注具體應(yīng)用的邏輯,而不必處理這些周邊情況。例如,一個(gè)中斷信號(hào)的產(chǎn)生要通知多個(gè)狀態(tài)機(jī)或任務(wù)等等情況下。如果是用于算法函數(shù)庫(kù)中或單片機(jī)等簡(jiǎn)單應(yīng)用環(huán)境中,目標(biāo)只是把算法、單片機(jī)設(shè)計(jì)更嚴(yán)謹(jǐn)化,這按照前面描述的方法使用即可。這種條件下,該庫(kù)僅占用920個(gè)字節(jié)的代碼空間和12字節(jié)的靜態(tài)內(nèi)存空間。如果是有特殊需要的使用方,要求特別小體積的狀態(tài)機(jī)庫(kù),有一個(gè)版本用匯編語(yǔ)言實(shí)現(xiàn)的,僅500字節(jié)左右代碼空間的庫(kù)。如果是8051等簡(jiǎn)單環(huán)境,還有一個(gè)版本的庫(kù),僅占用3個(gè)字節(jié)的靜態(tài)內(nèi)存空間。5、可擴(kuò)充功能的模式終結(jié)鉤子提示法延遲事件正交構(gòu)件轉(zhuǎn)換到歷史6 獲取數(shù)據(jù)。其中,ISR將關(guān)鍵

27、的、需要立即處理的數(shù)據(jù)或信號(hào)進(jìn)行處理或緩存,但同時(shí)要保證快速處理,避免長(zhǎng)時(shí)間屏蔽其他設(shè)備中斷(這個(gè)可能導(dǎo)致的屏蔽時(shí)間的最大值就是系統(tǒng)的實(shí)時(shí)響應(yīng)能力。ISR將次關(guān)鍵(不再需要ISR環(huán)境,不需要關(guān)閉中斷的數(shù)據(jù)或信號(hào)通過(guò)異步事件通知DEV A后交給SISR處理,DEV A控制SISR順序執(zhí)行,沒(méi)有了ISR環(huán)境中中斷可能在任何時(shí)候發(fā)生的問(wèn)題。但是這種同步中斷式處理變異步串行化處理是需要條件的。條件就是所制定的芯片方案的后級(jí)處理能力(ISR后應(yīng)能夠滿(mǎn)足所面對(duì)應(yīng)用的前級(jí)峰值壓力,并通過(guò)DEV A的事件Fifo緩沖不會(huì)丟失不允許丟失的數(shù)據(jù)(可拋棄的數(shù)據(jù)或信號(hào)除外。在ISR前后級(jí)之間關(guān)系處理好之后,SISR和

28、各種應(yīng)用,實(shí)際上都是在任務(wù)空間中運(yùn)行。SISR 和普通應(yīng)用不同的只是所有SISR在DEV A環(huán)境中執(zhí)行,DEV A相當(dāng)于一個(gè)最高優(yōu)先級(jí)的任務(wù)。以便能夠快速處理ISR中的數(shù)據(jù)要求,避免設(shè)備堵塞。之后,SISR和任務(wù)之間就有了較為從容的空間和時(shí)間來(lái)處理應(yīng)用邏輯,而這種應(yīng)用邏輯的安排是虛擬為多任務(wù)并行似的。這種邏輯構(gòu)成了當(dāng)今計(jì)算機(jī)的整個(gè)基礎(chǔ),但是實(shí)際上是否夠嚴(yán)謹(jǐn)、是否夠健壯、是否實(shí)時(shí)性夠好、是否擴(kuò)展性夠好、有沒(méi)有改進(jìn)余地?Miro Samek Ph.D.在其書(shū)Practical Statecharts in C/C+:Quantum Programming for Embedded Systems中

29、設(shè)想了一種基于狀態(tài)機(jī)的內(nèi)核系統(tǒng),具有相對(duì)于經(jīng)典內(nèi)核邏輯結(jié)構(gòu)多方面的優(yōu)勢(shì)。其中一個(gè)最大的優(yōu)勢(shì)就是狀態(tài)機(jī)的理論“成熟度”遠(yuǎn)高于基于順序邏輯的編程方式。順序邏輯思考方式初看起來(lái)是編寫(xiě)程序的第一選擇,這是一種同步式的思考方式。但是實(shí)際上真實(shí)環(huán)境中太多的異步工作方式,如果以同步方式為主干,非常難適應(yīng)與異步方式的對(duì)接,而反過(guò)來(lái),異步方式作為主干,則非常方便與同步方式的對(duì)接??纯窜浖幕A(chǔ)處理器,各種處理器,各種長(zhǎng)時(shí)間運(yùn)行的硬件設(shè)備都是按照異步方式運(yùn)作的。再看看現(xiàn)實(shí)社會(huì)中各種事務(wù)的發(fā)送,絕大多數(shù)都是異步方式的。同步方式在建立簡(jiǎn)單邏輯,用簡(jiǎn)單邏輯搭建小系統(tǒng)事非常方便快捷,而一旦開(kāi)始有復(fù)雜的要求,就開(kāi)始變得越來(lái)

30、越混亂,最后必須把體系結(jié)構(gòu)做得特別復(fù)雜,而且還要借助各種異步同步轉(zhuǎn)接手段來(lái)銜接。當(dāng)今計(jì)算機(jī)軟件系統(tǒng)的復(fù)雜性,其中很大原因可以歸結(jié)到其體系結(jié)構(gòu)基礎(chǔ)的同步性質(zhì)。因?yàn)檫@些同步性,最后必須引入信號(hào)、中斷等,并且導(dǎo)致各種競(jìng)爭(zhēng)條件的出現(xiàn),并最好導(dǎo)致系統(tǒng)的各種不穩(wěn)定現(xiàn)象。如果一開(kāi)始就以中斷、信號(hào)為基礎(chǔ)建立異步方式的基礎(chǔ)體系結(jié)構(gòu),在開(kāi)始階段不容易建立,但是越到后期復(fù)雜系統(tǒng),越能體現(xiàn)其體系結(jié)構(gòu)的優(yōu)勢(shì),并且在穩(wěn)定性上會(huì)有極大的回報(bào)。異步方式中,中斷、信號(hào)通知、基于狀態(tài)的處理邏輯,實(shí)際上是不可分割的基礎(chǔ)。在此基礎(chǔ)上還有不同異步邏輯實(shí)體之間溝通通訊的橋接設(shè)計(jì)等一些其他要素。其中虛擬總線(xiàn),就是一個(gè)主要的要素。但是Mir

31、o在他的書(shū)中只是作為一個(gè)設(shè)想,實(shí)際上并沒(méi)有真正去規(guī)劃它,包括其QFrame量子狀態(tài)機(jī)框架都還是考慮這如何與搶占式多任務(wù)環(huán)境適配。在此,按照Miro開(kāi)啟的思路,作者嘗試把它更為完整地做一個(gè)考察,并進(jìn)行真正面向?qū)崿F(xiàn)的一個(gè)規(guī)劃。首先來(lái)考慮經(jīng)典體系結(jié)構(gòu)的背景假設(shè)。實(shí)際上經(jīng)典體系結(jié)構(gòu)背后有個(gè)背景假設(shè)隱含在人們的思考習(xí)慣里,這個(gè)假設(shè)就是要模擬出并發(fā)行就需要線(xiàn)程或進(jìn)程等執(zhí)行體。實(shí)際上并不見(jiàn)得需要如此,如果沒(méi)有“執(zhí)行體”或者準(zhǔn)確的說(shuō),整個(gè)系統(tǒng)只有一個(gè)執(zhí)行體來(lái)推動(dòng)狀態(tài)機(jī)的運(yùn)行也同樣能夠?qū)崿F(xiàn)并行。因?yàn)槎鄠€(gè)同時(shí)存在的狀態(tài)機(jī)的事件各自到達(dá)的時(shí)候,都能夠通過(guò)“執(zhí)行體”推動(dòng)狀態(tài)機(jī)邏輯的運(yùn)作,這樣同樣能夠給使用者并行的假象

32、?;蛘叨嗪说奶幚砥髦幸粋€(gè)處理器核一個(gè)執(zhí)行體,其中的每一個(gè)可以安放多個(gè)狀態(tài)機(jī),這樣的體系結(jié)構(gòu)設(shè)計(jì),甚至將來(lái)可以把狀態(tài)機(jī)的執(zhí)行體做到芯片的硬邏輯中。狀態(tài)機(jī)的事件都是隨時(shí)發(fā)生的,因此并行特 征。 件通知變?yōu)橛心繕?biāo)的事件通知。4.邏輯上存在持續(xù)存在的事件,這種事件不用事件通知方式完成,而用另外的簡(jiǎn)便方法表達(dá)。因此事件通知都是瞬態(tài)性的。完成一次通知(單播或一輪通知后(多播后隨即消失。5.最高級(jí)事件隊(duì)列(0級(jí)隊(duì)列,僅用于硬件驅(qū)動(dòng)部件通知后方邏輯部件,這個(gè)隊(duì)列僅登記無(wú)目標(biāo)、單播式性質(zhì)事件。如果特定事件被搶占登記后轉(zhuǎn)發(fā),只能在1級(jí)隊(duì)列轉(zhuǎn)發(fā)專(zhuān)向事件。其他任何事件只能在0級(jí)之后(不包括0級(jí)隊(duì)列中進(jìn)行交流。這樣安排

33、,保證了在其他狀態(tài)中不必使用硬保護(hù)。因?yàn)?級(jí)隊(duì)列的事件源都是處理好了硬保護(hù)互斥問(wèn)題的,如果其他后臺(tái)狀態(tài)機(jī)要向0級(jí)隊(duì)列發(fā)送事件,會(huì)造成搶占問(wèn)題。因此,系統(tǒng)至少要配置0、1兩個(gè)級(jí)別事件隊(duì)列。6.大數(shù)據(jù)量處理任務(wù)內(nèi)部可能也是狀態(tài)機(jī),但是應(yīng)該沒(méi)有必要再具備分發(fā)機(jī)構(gòu)。只需要基本的uHsm狀態(tài)機(jī)處理即可。7.SDU設(shè)計(jì)為函數(shù)方式。這樣在前兩種有任務(wù)的環(huán)境中,只需要生成任務(wù)調(diào)用SDU函數(shù)即可。在前后臺(tái)設(shè)計(jì)中,只需要在后臺(tái)邏輯中直接調(diào)用SDU函數(shù)即可。以此保持系統(tǒng)的較高可移植性。8.內(nèi)存問(wèn)題:事件的傳遞過(guò)程中參數(shù)不應(yīng)該包含類(lèi)似單獨(dú)分配的內(nèi)存塊這樣的參數(shù),應(yīng)該只是一個(gè)通知性質(zhì)。內(nèi)存數(shù)據(jù)都應(yīng)該保存在事件源模塊中。

34、就像玩卡設(shè)備一樣,收到的數(shù)據(jù)包保存好,通知軟件。目標(biāo)軟件收到后才到事件源去取內(nèi)存數(shù)據(jù)并釋放事件源的內(nèi)存。因此,狀態(tài)機(jī)中的狀態(tài),如果涉及到此類(lèi)處理的時(shí)候,也就工作類(lèi)似一個(gè)設(shè)備一樣。如果它進(jìn)一步投遞消息出去,它需要自己緩存數(shù)據(jù)。就像TCP模塊一樣,接受到網(wǎng)卡設(shè)備數(shù)據(jù)后,要自行緩存。并投遞必要的事件到應(yīng)用程序,應(yīng)用程序再到TCP模塊取TCP處理后的數(shù)據(jù)。這樣處理事件在傳遞過(guò)程中,無(wú)論是單播的鏈?zhǔn)絺鬟f還是廣播的鏈?zhǔn)絺鬟f,才能夠穩(wěn)定。否則內(nèi)存塊的處理會(huì)在傳遞沒(méi)有目標(biāo)是導(dǎo)致系統(tǒng)內(nèi)存占用無(wú)法釋放。但是事件源和狀態(tài)機(jī)之間如果私下約定好,也可以用分配的內(nèi)存塊作為參數(shù)進(jìn)行傳遞。7.3、VBus設(shè)計(jì)7.3.1、VB

35、us基礎(chǔ)問(wèn)題的規(guī)定在此對(duì)SDU體系結(jié)構(gòu)使用的一些基礎(chǔ)問(wèn)題進(jìn)行規(guī)定。最基本的問(wèn)題就是對(duì)事件編號(hào)空間進(jìn)行規(guī)定。從下面的事件編號(hào)劃分,我們看到一個(gè)類(lèi)似內(nèi)存空間分配的形式。如果把這個(gè)劃分再細(xì)化到每個(gè)模塊,就像是微處理器中的設(shè)備寄存器地址一樣。這就是Miro先生所說(shuō)軟件總線(xiàn)的概念。在此我們稱(chēng)其為VBus(Virtual Bus。根據(jù)這個(gè)概念還可以對(duì)VBus進(jìn)行更詳細(xì)、更合理的劃分。也就是說(shuō)以事件編號(hào)作為VBus的寄存器地址,事件參數(shù)作為要表達(dá)的(寫(xiě)入或報(bào)告的寄存器值。這樣理解之后,SDU就成為了VBus空間的管理器。1.事件編號(hào)U_EVENT_USER(3開(kāi)始到262143(256K-1,為每種處理器硬

36、件相關(guān)信號(hào)。2.通常最底層的驅(qū)動(dòng)除了最基本的硬件信號(hào)接收、緊急數(shù)據(jù)緩存之外,還有信號(hào)編號(hào)翻譯轉(zhuǎn)發(fā)的功能。3.事件編號(hào)在U_EVENT_USER(3到2147483647(2G-1之間。2G(0x80000000位(第32位是單播標(biāo)記。4.事件編號(hào)262144到2097151(2M-1之間,是驅(qū)動(dòng)用事件編號(hào)。5.事件編號(hào)2097152(2M到1073741823(1G-1之間,規(guī)劃為系統(tǒng)服務(wù)用事件編號(hào)。1G到2G-1之間為應(yīng)用程序事件編號(hào)。6.模塊自身定義的發(fā)出和接收事件號(hào),都按照一個(gè)初始化基數(shù)進(jìn)行便宜疊加。就像微處理器中的設(shè)備一樣。這樣可以非常方便模塊進(jìn)行移植定制。7.模塊的數(shù)據(jù)傳遞不采用事件

37、號(hào)方式,而采用Fifo方式。這樣事件號(hào)只用于控制、配置目的,需要的事件號(hào)空間會(huì)很少。8.模塊如果工作必須依賴(lài)于接收事件(該模塊本身不發(fā)出這個(gè)事件,可以自行注冊(cè)事件。以保證事件存在,而之后不發(fā)出該事件即可。接收的事件就像微處理器中指定地址的寄存器一樣。發(fā)出的控制事件就像微處理器中用于供客戶(hù)讀出的寄存器一樣。而且這種讀出的數(shù)據(jù)的每個(gè)變化都是用事件通知發(fā)出的,不會(huì)因?yàn)楹罄m(xù)事件的到達(dá)而破壞。如果需要那種隨時(shí)變化的,可以只通知變化事件,而不附帶數(shù)據(jù)即可。9.模塊Fifo的安排:如果用fifo逐級(jí)下傳,容易導(dǎo)致數(shù)據(jù)傳遞量過(guò)大。比較好的方式是分多個(gè)Fifo。以TCP為例,進(jìn)行說(shuō)明。兩個(gè)用戶(hù)接口fifo,用于

38、和用戶(hù)接口。但是數(shù)據(jù)實(shí)際上并不由Tcp模塊讀出,而Ip模塊有一個(gè)數(shù)據(jù)下發(fā)頭Fifo供Tcp使用。這個(gè)頭對(duì)用戶(hù)接口Fifo進(jìn)行指示。同樣也為Udp添加一個(gè)頭Fifo。而以太為Ip提供一個(gè)Ip頭Fifo。如果必要為Ipx提供一個(gè)Ipx頭Fifo,為PPPoe提供一個(gè)頭Fifo。這樣,只在最后取數(shù)據(jù)傳遞到真正最終設(shè)備是,才讀出來(lái)。10.上傳則采取類(lèi)似的方式:只用一個(gè)以太一個(gè)Fifo接收數(shù)據(jù)。之后剝掉頭,通過(guò)IP頭Fifo通知IP。IP來(lái)處理這個(gè)數(shù)據(jù),剝掉頭,通過(guò)TCP或UDP頭Fifo傳遞給TCP模塊。TCP 模塊再來(lái)處理這個(gè)數(shù)據(jù),將數(shù)據(jù)全部取出推入用戶(hù)Fifo。11.上述Fifo總體上是最高效的傳遞方式,如果再加上一些4字節(jié)對(duì)齊限制等約束,效率會(huì)更高。打開(kāi)cache也能極大提高效率。另外用戶(hù)接口Fifo的數(shù)據(jù)最好不立即下推。最好是滿(mǎn)包或定時(shí)器事件到之后才下推。12.IP和TCP之間只有一對(duì)雙向頭Fifo。TCP內(nèi)部各套接字狀態(tài)機(jī)的劃分,在TCP內(nèi)部進(jìn)行處理。頭Fifo之間都是頭保存完之后,用事件進(jìn)行通知。就像數(shù)據(jù)準(zhǔn)備好之后,通過(guò)一個(gè)寄存器啟動(dòng)發(fā)送一樣。13.VBus總線(xiàn)的設(shè)計(jì)比真正的處理器總線(xiàn)更具有靈活性。例如可以接收廣播方式。另外還可以通過(guò)Fifo操作使操作更靈活。并且這種方式具有將來(lái)將軟件模塊化、硬件化的可能性。如果將軟件硬件化,為提高效率,可能Fifo都最好是4字節(jié)32

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論