<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      版權(quán)聲明:本文為博主原創(chuàng)文章,遵循?CC 4.0 BY-SA?
      <http://creativecommons.org/licenses/by-sa/4.0/>版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。

      本文鏈接:https://www.cnblogs.com/lihuidashen/p/11510532.html
      <https://www.cnblogs.com/lihuidashen/p/11510532.html>

      https://mp.weixin.qq.com/s/xDAfaEFY4INHzr7MFnR5dg
      <https://mp.weixin.qq.com/s/xDAfaEFY4INHzr7MFnR5dg>

      ?


      ????關(guān)于狀態(tài)機(jī),基礎(chǔ)的知識點可以自行理解,講解的很多,這里主要是想寫一個有限狀態(tài)機(jī)FSM通用的寫法,目的在于更好理解,移植,節(jié)省代碼閱讀與調(diào)試時間,體現(xiàn)出編程之美。

      ?

      傳統(tǒng)的實現(xiàn)方案

      *
      if...else : 搞一大堆if else, 一個函數(shù)寫很長很長......

      *
      swich...case : 也搞一大堆一個函數(shù)寫很長很長......

      ?

      ????先來看看最近做的一個項目,無線通信協(xié)議實現(xiàn)的狀態(tài)機(jī)是什么樣子的:

      ?

      ?


      ????有三種類型的事件:上層下達(dá)的命令事件;下層到達(dá)的標(biāo)志和數(shù)據(jù)傳輸事件;超時定時器超時事件。有10種狀態(tài),關(guān)聯(lián)性很大,復(fù)雜了吧,這要是各種if/else的要寫到什么時候呢。

      ?

      ? ? 偷偷放一張討論的圖,亂七八糟形容很恰當(dāng)。



      ?

      ????在事件中判斷狀態(tài),在狀態(tài)中判斷事件,橫豎兩種寫法的代碼都比較冗長,看起來呢也不大好,一旦增減,就又要動腦子重新梳理一遍,很累的。

      ?

      ????怎么去寫呢?其狀態(tài)機(jī)原理:在根據(jù)當(dāng)前狀態(tài)(cur_state)
      下,發(fā)生事件(event)后,轉(zhuǎn)移到下一個狀態(tài)號(nxt_state),決定執(zhí)行的動作(action)。盜用一個圖吧

      ?



      ?

      ????這里我們首先定義一個結(jié)構(gòu)體如下:
      typedef struct { State curState;//當(dāng)前狀態(tài) EventID eventId;//事件ID State nextState;
      //下個狀態(tài) Action action;//具體表現(xiàn)} StateTransform;
      ?

      ?

      ????我們假設(shè)有3種狀態(tài),這里可以隨意增加,狀態(tài)枚舉如下:
      typedef enum { state_1=1, state_2, state_3} State;
      ?

      ????我們假設(shè)有5個事件,也可以隨意增加,事件ID枚舉如下:
      typedef enum{ event_1=1, event_2, event_3, event_4, event_5}EventID;
      ?

      ????將其封裝起來在StateMachine中:
      typedef struct{ State state; int transNum; StateTransform* transform;
      }StateMachine;
      ?

      ?

      ????具體流程:當(dāng)前狀態(tài)-有事件觸發(fā)-跳到下個狀態(tài)-具體表現(xiàn),重構(gòu)代碼
      StateTransform* findTranss(StateMachine* pSM, const EventID evt){ int i; for
      (i =0; i < pSM->transNum; i++) { if ((pSM->transform[i].curState == pSM->state)
      && (pSM->transform[i].eventId == evt)) { return &pSM->transform[i]; } } return
      NULL; }
      ?

      ????狀態(tài)機(jī)實現(xiàn)如下:
      StateTransformm* pTrans; pTrans = findTrans(pSM, evt); if (pTrans == NULL) {
      xil_printf("CurState= %s Do not process enent: %s\r\n", pSM->state,evt); return
      ; } pSM->state = pTrans->nextState; Action act = pTrans->action; if (act ==
      NULL) { xil_printf("change state to %s. No action\r\n",pSM->state); return; }
      act(&evt);
      ?

      ????最后我模擬一些隨機(jī)事件,我們只需要弄清楚事件ID,狀態(tài)切換,具體表現(xiàn)就可以了,在代碼中就是填寫 stateTran[] 這個表
      ,一旦有增減事件,狀態(tài)等等,也不需要再去使用switch/case,特費(fèi)腦,其代碼如下:
      int run() { StateMachine stateMachine; stateMachine.state = state_1;
      stateMachine.transNum= 7; StateTransform stateTran[] = {
      {state_1,event_3,state_2,f121}, {state_1,event_4,state_2,NULL},
      {state_2,event_1,state_3,f231}, {state_2,event_4,state_2,f221},
      {state_3,event_2,state_1,f311}, {state_3,event_3,state_2,f321},
      {state_3,event_5,state_3,f331} }; stateMachine.transform= stateTran; EventID
      inputEvent[15] = { event_1, event_2, event_3, event_4, event_5, event_1,
      event_2, event_3, event_4, event_5, event_1, event_2, event_3, event_4, event_5
      };int i; for (i = 0; i < 15; i++) { runStateMachine(&stateMachine,
      inputEvent[i]); }return 0; }
      ?

      ????最后運(yùn)行結(jié)果如下



      ?

      ?

      總結(jié):

      ?? ?狀態(tài)機(jī)應(yīng)用很廣泛,也可以鍛煉我們寫代碼的邏輯思維,看清問題的本質(zhì),寫的代碼才能賞心悅目,希望大家能夠多多指點,找到編程的樂趣,欣賞到編程之美。

      ?

      推薦閱讀

      FPGA 高手養(yǎng)成記-Verliog語法基礎(chǔ)
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247484062&idx=1&sn=8a871531f31a7513236654d1bda3d1e3&chksm=97584a6ca02fc37a1db431685d689241f6a89bb5f0549a300ab7bd1fcb7d659fe1f62a19ec5a&scene=21#wechat_redirect>

      FPGA 高手養(yǎng)成記-淺談狀態(tài)機(jī)
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247484095&idx=1&sn=5e82fbb0648da16e079488ec646c6ac8&chksm=97584a4da02fc35b803c9289a872f67950bc53f53854f3dad3e9a15b227c97e402bc6800aa32&scene=21#wechat_redirect>

      FPGA 高手養(yǎng)成記-Test bench文件結(jié)構(gòu)一覽無余
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247484150&idx=1&sn=f8c079d12898a541991c930c1ed29e4a&chksm=97584a04a02fc31201604dea5fbfcdf01f23fa6986d3e1f8e4549ece1acee33c3813d8943e31&scene=21#wechat_redirect>

      FPGA 高手養(yǎng)成記-【很重要】Testbenth前仿真全過程
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247484168&idx=1&sn=0f250add9f1dec4d33ad48c78a8c81f4&chksm=97584bfaa02fc2ecbef31ccacd57c58401e9e414ca0a70ae133ae8fe13777d77ad9f995668f5&scene=21#wechat_redirect>

      const 指針與指向const的指針
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247484016&idx=1&sn=f3f723a30dbb50811d4ac48afd028ac6&chksm=97584a82a02fc39463e536310a061a1cfcf8adc21b1d1de34c7c5d4a9cd1cfeb0dc164afbe47&scene=21#wechat_redirect>

      蛻變成蝶~Linux設(shè)備驅(qū)動之字符設(shè)備驅(qū)動
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247483912&idx=1&sn=4ac95f580a2fc7d51157a4fb651354f4&chksm=97584afaa02fc3eca1b6d4218e8399a6d2c42857558630001d8de3660b9502e0023d2e44759b&scene=21#wechat_redirect>

      24小時學(xué)通Linux內(nèi)核--內(nèi)核探索工具類
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247483834&idx=1&sn=2bb49a10cbbc10d146a2da2705a774b7&chksm=97584948a02fc05ef8b385c9f8b61888c23aa7fc101e655af0d9f2bdad892712e330b0f785c2&scene=21#wechat_redirect>

      機(jī)器學(xué)習(xí)理論提升方法AdaBoost算法第一卷
      <http://mp.weixin.qq.com/s?__biz=MzIxMTE5ODM2NQ==&mid=2247483973&idx=1&sn=6ad3c88e18b74bdc7be711b8effdfdf2&chksm=97584ab7a02fc3a1ee423ba6aa4d1e3c1cb5fa1b8dcc5cfc28673e1023941af3bad45cbb03ca&scene=21#wechat_redirect>

      ?


      關(guān)注公眾號【技術(shù)讓夢想更偉大】,獲取更多Linux/C/C++/Python/FPGA等原創(chuàng)技術(shù)文章。后臺免費(fèi)獲取經(jīng)典電子書籍和視頻資源,實時更新,原創(chuàng)不易,請多支持,謝謝!



      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          国产丰满精东videossex | 一边摸上边一边摸下边的app | 无套内谢少妇毛片免费 | 女生扒开腿让男生捅 | 福利视频网站 | 国产乱xxxxx987国语对白 | 日日夜夜精 | 夜夜夜夜猛噜噜噜噜噜噜燥 | 成人视频免费观看做爱 | 午夜福利视频日本 |