<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 狀態(tài)機編程

狀態(tài)機編程

作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò ) 收藏
小程序無(wú)所謂,工程稍微一大,情況一多,這種方法就比較實(shí)用
轉載正文1有限狀態(tài)機FSM思想廣泛應用于硬件控制電路設計,也是軟件上常用的一種處理方法(軟件上稱(chēng)為FMM--有限消息機)。它把復雜的控制邏輯分解成有限個(gè)穩定狀態(tài),在每個(gè)狀態(tài)上判斷事件,變連續處理為離散數字處理,符合計算機的工作特點(diǎn)。同時(shí),因為有限狀態(tài)機具有有限個(gè)狀態(tài),所以可以在實(shí)際的工程上實(shí)現。但這并不意味著(zhù)其只能進(jìn)行有限次的處理,相反,有限狀態(tài)機是閉環(huán)系統,有限無(wú)窮,可以用有限的狀態(tài),處理無(wú)窮的事務(wù)。有限狀態(tài)機的工作原理如圖1所示,發(fā)生事件(event)后,根據當前狀態(tài)(cur_state),決定執行的動(dòng)作(action),并設置下一個(gè)狀態(tài)號(nxt_state)。-------------||-------->執行動(dòng)作action發(fā)生事件event ----->| cur_state |||-------->設置下一狀態(tài)號nxt_state-------------當前狀態(tài)圖1 有限狀態(tài)機工作原理e0/a0--->--||-------->----------e0/a0 ||S0|-----|-<------------| e1/a1|| e2/a2V--------------------|S2|-----<-----|S1|----------e2/a2----------圖2 一個(gè)有限狀態(tài)機實(shí)例--------------------------------------------當前狀態(tài)s0s1s2| 事件--------------------------------------------a0/s0--a0/s0|e0--------------------------------------------a1/s1----|e1--------------------------------------------a2/s2a2/s2--|e2--------------------------------------------表1 圖2狀態(tài)機實(shí)例的二維表格表示(動(dòng)作/下一狀態(tài))圖2為一個(gè)狀態(tài)機實(shí)例的狀態(tài)轉移圖,它的含義是:在s0狀態(tài),如果發(fā)生e0事件,那么就執行a0動(dòng)作,并保持狀態(tài)不變;如果發(fā)生e1事件,那么就執行a1動(dòng)作,并將狀態(tài)轉移到s1態(tài);如果發(fā)生e2事件,那么就執行a2動(dòng)作,并將狀態(tài)轉移到s2態(tài);在s1狀態(tài),如果發(fā)生e2事件,那么就執行a2動(dòng)作,并將狀態(tài)轉移到s2態(tài);在s2狀態(tài),如果發(fā)生e0事件,那么就執行a0動(dòng)作,并將狀態(tài)轉移到s0態(tài);有限狀態(tài)機不僅能夠用狀態(tài)轉移圖表示,還可以用二維的表格代表。一般將當前狀態(tài)號寫(xiě)在橫行上,將事件寫(xiě)在縱列上,如表1所示。其中“--”表示空 (不執行動(dòng)作,也不進(jìn)行狀態(tài)轉移),“an/sn”表示執行動(dòng)作an,同時(shí)將下一狀態(tài)設置為sn。表1和圖2表示的含義是完全相同的。觀(guān)察表1可知,狀態(tài)機可以用兩種方法實(shí)現:豎著(zhù)寫(xiě)(在狀態(tài)中判斷事件)和橫著(zhù)寫(xiě)(在事件中判斷狀態(tài))。這兩種實(shí)現在本質(zhì)上是完全等效的,但在實(shí)際操作中,效果卻截然不同。==================================豎著(zhù)寫(xiě)(在狀態(tài)中判斷事件)C代碼片段==================================cur_state = nxt_state;switch(cur_state){//在當前狀態(tài)中判斷事件case s0://在s0狀態(tài)if(e0_event){//如果發(fā)生e0事件,那么就執行a0動(dòng)作,并保持狀態(tài)不變;執行a0動(dòng)作;//nxt_state = s0;//因為狀態(tài)號是自身,所以可以刪除此句,以提高運行速度。}else if(e1_event){//如果發(fā)生e1事件,那么就執行a1動(dòng)作,并將狀態(tài)轉移到s1態(tài);執行a1動(dòng)作;nxt_state = s1;}else if(e2_event){//如果發(fā)生e2事件,那么就執行a2動(dòng)作,并將狀態(tài)轉移到s2態(tài);執行a2動(dòng)作;nxt_state = s2;}break;case s1://在s1狀態(tài)if(e2_event){//如果發(fā)生e2事件,那么就執行a2動(dòng)作,并將狀態(tài)轉移到s2態(tài);執行a2動(dòng)作;nxt_state = s2;}break;case s2://在s2狀態(tài)if(e0_event){//如果發(fā)生e0事件,那么就執行a0動(dòng)作,并將狀態(tài)轉移到s0態(tài);執行a0動(dòng)作;nxt_state = s0;}}==================================橫著(zhù)寫(xiě)(在事件中判斷狀態(tài))C代碼片段==================================//e0事件發(fā)生時(shí),執行的函數void e0_event_function(int * nxt_state){int cur_state;cur_state = *nxt_state;switch(cur_state){case s0://觀(guān)察表1,在e0事件發(fā)生時(shí),s1處為空case s2:執行a0動(dòng)作;*nxt_state = s0;}}//e1事件發(fā)生時(shí),執行的函數void e1_event_function(int * nxt_state){int cur_state;cur_state = *nxt_state;switch(cur_state){case s0://觀(guān)察表1,在e1事件發(fā)生時(shí),s1和s2處為空執行a1動(dòng)作;*nxt_state = s1;}}//e2事件發(fā)生時(shí),執行的函數void e2_event_function(int * nxt_state){int cur_state;cur_state = *nxt_state;switch(cur_state){case s0://觀(guān)察表1,在e2事件發(fā)生時(shí),s2處為空case s1:執行a2動(dòng)作;*nxt_state = s2;}}上面橫豎兩種寫(xiě)法的代碼片段,實(shí)現的功能完全相同,但是,橫著(zhù)寫(xiě)的效果明顯好于豎著(zhù)寫(xiě)的效果。理由如下:1、豎著(zhù)寫(xiě)隱含了優(yōu)先級排序(其實(shí)各個(gè)事件是同優(yōu)先級的),排在前面的事件判斷將毫無(wú)疑問(wèn)地優(yōu)先于排在后面的事件判斷。這種if/else if寫(xiě)法上的限制將破壞事件間原有的關(guān)系。而橫著(zhù)寫(xiě)不存在此問(wèn)題。2、由于處在每個(gè)狀態(tài)時(shí)的事件數目不一致,而且事件發(fā)生的時(shí)間是隨機的,無(wú)法預先確定,導致豎著(zhù)寫(xiě)淪落為順序查詢(xún)方式,結構上的缺陷使得大量時(shí)間被浪費。對于橫著(zhù)寫(xiě),在某個(gè)時(shí)間點(diǎn),狀態(tài)是唯一確定的,在事件里查找狀態(tài)只要使用switch語(yǔ)句,就能一步定位到相應的狀態(tài),延遲時(shí)間可以預先準確估算。而且在事件發(fā)生時(shí),調用事件函數,在函數里查找唯一確定的狀態(tài),并根據其執行動(dòng)作和狀態(tài)轉移的思路清晰簡(jiǎn)潔,效率高,富有美感。總之,我個(gè)人認為,在軟件里寫(xiě)狀態(tài)機,使用橫著(zhù)寫(xiě)的方法比較妥帖。豎著(zhù)寫(xiě)的方法也不是完全不能使用,在一些小項目里,邏輯不太復雜,功能精簡(jiǎn),同時(shí)為了節約內存耗費,豎著(zhù)寫(xiě)的方法也不失為一種合適的選擇。在FPGA類(lèi)硬件設計中,以狀態(tài)為中心實(shí)現控制電路狀態(tài)機(豎著(zhù)寫(xiě))似乎是唯一的選擇,因為硬件不太可能靠事件驅動(dòng)(橫著(zhù)寫(xiě))。不過(guò),在FPGA 里有一個(gè)全局時(shí)鐘,在每次上升沿時(shí)進(jìn)行狀態(tài)切換,使得豎著(zhù)寫(xiě)的效率并不低。雖然在硬件里豎著(zhù)寫(xiě)也要使用IF/ELSIF這類(lèi)查詢(xún)語(yǔ)句(用VHDL開(kāi)發(fā)),但他們映射到硬件上是組合邏輯,查詢(xún)只會(huì )引起門(mén)級延遲(ns量級),而且硬件是真正并行工作的,這樣豎著(zhù)寫(xiě)在硬件里就沒(méi)有負面影響。因此,在硬件設計里,使用豎著(zhù)寫(xiě)的方式成為必然的選擇。這也是為什么很多搞硬件的工程師在設計軟件狀態(tài)機時(shí)下意識地只使用豎著(zhù)寫(xiě)方式的原因,蓋思維定勢使然也。TCP和PPP框架協(xié)議里都使用了有限狀態(tài)機,這類(lèi)軟件狀態(tài)機最好使用橫著(zhù)寫(xiě)的方式實(shí)現。以某TCP協(xié)議為例,見(jiàn)圖3,有三種類(lèi)型的事件:上層下達的命令事件;下層到達的標志和數據的收包事件;超時(shí)定時(shí)器超時(shí)事件。上層命令(open,close)事件-------------------------------------------------------|TCP|<----------超時(shí)事件timeout-------------------------------------------------------RST/SYN/FIN/ACK/DATA等收包事件圖3 三大類(lèi)TCP狀態(tài)機事件由圖3可知,此TCP協(xié)議棧采用橫著(zhù)寫(xiě)方式實(shí)現,有3種事件處理函數,上層命令處理函數(如tcp_close);超時(shí)事件處理函數 (tmr_slow);下層收包事件處理函數(tcp_process)。值得一提的是,在收包事件函數里,在各個(gè)狀態(tài)里判斷RST/SYN/FIN/ACK/DATA等標志(這些標志類(lèi)似于事件),看起來(lái)象豎著(zhù)寫(xiě)方式,其實(shí),如果把包頭和數據看成一個(gè)整體,那么,RST/SYN/FIN/ACK/DATA等標志就不必被看成獨立的事件,而是屬于同一個(gè)收包事件里的細節,這樣,就不會(huì )認為在狀態(tài)里查找事件,而是總體上看,是在收包事件里查找狀態(tài)(橫著(zhù)寫(xiě))。在PPP里更是到處都能見(jiàn)到橫著(zhù)寫(xiě)的現象,有時(shí)間的話(huà)再細說(shuō)。我個(gè)人感覺(jué)在實(shí)現PPP框架協(xié)議前必須了解橫豎兩種寫(xiě)法,而且只有使用橫著(zhù)寫(xiě)的方式才能比較完美地實(shí)現PPP。

				
            
                
			
							
上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: 狀態(tài)機編

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>