<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      嵌入式狀態機軟件實現方式

      回想剛開始工作的時候,寫代碼感覺都會很凌亂,不知道從哪里開始入手,而且寫完老是漏掉各種情況處理。只能靠測試來發現缺陷,著實苦惱。直到某天聽到辦公室某個大佬指導另一個同事:“你搞個狀態機去管理啊......你知道什么是狀態機不?”于是便抱著好奇的心態去搜索了一下,從此打開了新的大門哈哈哈!發現尤其適合于嵌入式編程,所以十分推薦新手都了解一下。

      狀態機,這是在嵌入式系統中大量使用的軟件模式,簡單點說,就是會基于當前的狀態去做不同的動作,切換到下一個狀態。
      下面以交通信號燈控制器作為狀態機范例演示一下:(該圖來自《嵌入式系統設計與實踐》作者:Elecia White)
      功能需求很簡單:紅燈停,綠燈行,黃燈等。
      image

      狀態機一共有三個組成部分:狀態事件動作
      以上范例中,可如下拆解:
      狀態:紅燈狀態RedState、綠燈狀態GreenState、黃燈狀態YellowState
      事件:停止命令StopCmd、前進命令GoCmd、超時TimeOut
      動作:切換到紅燈RedLedOn、切換到綠燈GreenLedOn、切換到黃燈YellowLedOn

      在實際編程中,以不同的部分為中心,可以有不同的軟件實現方法:

      以狀態為中心的狀態機

      我是誰->發生了什么事->我要干什么

      每個狀態負責自己的行為和遷移邏輯。基本上一個case對應一個狀態,可讀性比較強,是最常用的風格。
      但可擴展性一般,如果狀態事件太多,那處理函數很容易膨脹,所以不太適用于事件多的場景。

      void TrafficLightSystemStateMachine(event_e event)
      {
          static state_e current_state = RedState;
          switch (current_state) {
              case RedState:
                  if (event == GoCmd) {
                      GreenLedOn();
                      current_state = GreenState;
                  }
                  break;
              case GreenState:
                  if (event == TimeOut) {
                      YellowLedOn();
                      current_state = YellowState;
                  }
                  break;
              case YellowState:
                  if (event == TimeOut) {
                      RedLedOn();
                      current_state = RedState;
                  }
                  break;
              default:
                  break;
          }
      }
      

      以隱式狀態為中心的狀態機

      同樣是以狀態為中心,不過上面那種是顯式的。區別就在于把遷移邏輯隱藏到狀態函數內部里。
      隱藏之后的好處是可以做到模塊化處理,每個狀態函數獨立封裝,易于單元測試。
      (獨立的好處是可以不用太管他人,那壞處就是無法太管得了他人。)

      state_e red_state(void)
      {
          if (received_event == GoCmd) {
              GreenLedOn();
              return GreenState;
          }
          return RedState;
      }
      
      state_e green_state(void)
      {
          if (received_event == TimeOut) {
              YellowLedOn();
              return YellowState;
          } else if (received_event == StopCmd) {
              RedLedOn();
              return RedState;
          }
          return GreenState;
      }
      
      state_e yellow_state(void)
      {
          if (received_event == TimeOut) {
              RedLedOn();
              return RedState;
          }
          return YellowState;
      }
      
      state_e (*state_functions[])(void) = {
          red_state, green_state, yellow_state
      };
      
      void TrafficLightSystemStateMachine(void)
      {
          while (1) {
              current_state = state_functions[current_state]();
          }
      }
      

      以事件為中心的狀態機

      發生了什么事->我是誰->我要干什么

      比較適用于事件驅動場景,尤其是事件頻繁,來源復雜的情況。

      void TrafficLightSystemStateMachine(event_e event)
      {
          static state_e current_state = RedState;
          switch (event) {
              case StopCmd:
                  if (current_state != RedState) {
                      RedLedOn();
                      current_state = RedState;
                  }
                  break;
              case GoCmd:
                  if (current_state == RedState) {
                      GreenLedOn();
                      current_state = GreenState;
                  }
                  break;
              case TimeOut:
                  if (current_state == GreenState) {
                      YellowLedOn();
                      current_state = YellowState;
                  } else if (current_state == YellowState) {
                      RedLedOn();
                      current_state = RedState;
                  }
                  break;
              default:
                  break;
          }
      }
      

      以動作為中心的狀態機

      現在是什么情況->我要干什么

      以狀態+事件判斷來決定動作和下一個狀態。
      把遷移邏輯集中在表里,抽象程度高,可擴展性和可移植性強。
      很適合狀態 + 事件組合很多的場景

      typedef struct {
          state_e  current;
          event_e  event;
          state_e  next;
          void (*action)(void);
      } fsm_entry_t;
      
      fsm_entry_t fsm_table[] = {
          { RedState,   GoCmd,     GreenState,  GreenLedOn },
          { GreenState, TimeOut,   YellowState, YellowLedOn },
          { YellowState, TimeOut,  RedState,    RedLedOn },
          { GreenState, StopCmd,   RedState,    RedLedOn },
      };
      
      void TrafficLightSystemStateMachine(event_e event)
      {
          for (int i = 0; i < sizeof(fsm_table)/sizeof(fsm_table[0]); i++) {
              if (fsm_table[i].current == current_state && fsm_table[i].event == event) {
                  current_state = fsm_table[i].next;
                  fsm_table[i].action();
                  break;
              }
          }
      }
      

      總結:

      哪個部分多就適合以哪個部分作為中心。狀態多適合以狀態為中心,事件多適合以事件為中心,狀態和事件都多適合以動作為中心。在實踐過程中,其實重要的不是實現方式,而是狀態機的設計思想。但是狀態機代碼往往不利于維護和評審,所以提供狀態機圖等文檔是十分必要的。

      練習:
      大家可以以電子表作為練習,寫在評論區里交流一下,功能需求如下:
      1.有液晶顯示屏顯示年月日時分秒;
      2.有4個按鍵:
      a.LIGH鍵:夜光功能,按下后表燈會亮起,提供夜晚或昏暗環境下的時間顯示。
      b.MODE鍵:功能鍵,用于選擇需要調節的鬧鐘時間等。
      c.START鍵/加鍵:秒表鍵,用于開始、停止和繼續計時/數字加。
      d.RESET鍵/減鍵:用于歸零計時功能/數字減。
      3.可以實現顯示時間、調節時間、秒表、設置鬧鐘、倒計時功能。

      posted @ 2025-08-07 19:51  HughWu  閱讀(83)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 中文午夜乱理片无码| 日本久久高清一区二区三区毛片 | 日本不卡不二三区在线看| 18禁亚洲一区二区三区| 午夜一区二区三区视频| 最新精品国偷自产在线美女足| 亚洲色大成网站WWW国产| 沈丘县| 自拍偷亚洲产在线观看| av深夜免费在线观看| 欧美人与性动交α欧美精品| 国产蜜臀视频一区二区三区| 亚洲精品色哟哟一区二区| 国产AV大陆精品一区二区三区 | 中文熟妇人妻av在线| 亚洲色大成网站WWW久久| 于田县| 亚洲男人第一无码av网站| 欧美成本人视频免费播放| 来宾市| 欧洲性开放老太大| 国产在线亚州精品内射| 锡林郭勒盟| 成人嫩草研究院久久久精品| 国内精品伊人久久久久影院对白| 东港市| 蜜臀av久久国产午夜福利软件| 麻豆人妻| 在线免费成人亚洲av| 午夜福利影院不卡影院| 东方av四虎在线观看| 男女扒开双腿猛进入爽爽免费看| 老色鬼在线精品视频在线观看| 婷婷精品国产亚洲av在线观看| 久久婷婷五月综合97色直播| 下面一进一出好爽视频| 亚洲国产韩国欧美在线| 国产日韩av免费无码一区二区三区| 蜜臀精品视频一区二区三区| 亚洲狠狠婷婷综合久久久| 一二三四中文字幕日韩乱码|