色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

嵌入式軟件架構設計之狀態機

汽車電子技術 ? 來源:大橙子瘋嵌入式 ? 作者:大橙子瘋 ? 2023-02-15 15:49 ? 次閱讀

前言

功能業務代碼寫多了,回看代碼會發現用if-else if-else用的越來越多,因為有很多場景需要區分,不同場景下的功能不一樣,因此需要通過if做判斷,場景一旦多了起來起來,用if-else if-else就會越來越多。

這里的if-else if-else通常是用來區分不同場景下的功能實現,和上篇提到的表驅動編程還不太一樣。

為了避免這種情況,本編介紹一種開發方法-- 狀態機編程

為什么需要狀態機編程?相信很多人在實現if判斷的時候,偶爾會出現不小心漏掉或者寫錯一些觸發條件,導致功能出現異常的問題,特別是一些復雜的邏輯條件,一大堆的&&/||/()等眼花繚亂的復雜邏輯,寫完之后恐怕自己都得檢查好一會,擔心是不是哪個條件不能正常觸發。狀態機通常采用 switch-case實現。

那么狀態機的引入解決了哪些問題呢?

  • 當程序有多個狀態時,規范了程序的狀態轉換,避免了一些引入一些復雜的判斷邏輯。
  • 規范了程序在不同狀態下的實現和所能提供的能力。
  • 在能力上可以進行橫向擴展,提供新的狀態來完善現有邏輯
  • 邏輯清楚,實現過程會多考慮一些情況,方便定位問題所在

介紹

什么是狀態機?

狀態機是有限狀態自動機(FSM)的簡稱,是現實事物運行規則抽象而成的一個 數學模型

簡單理解就是:現實事物是有不同狀態的,比如燈,就有“亮”和“滅”兩種狀態,再復雜抽象一點,增加一個“損壞”狀態,那這屬于異常情況了。

概念

  • 現態:當前所處的狀態,一個狀態機至少要包含兩個狀態,某一時刻只能是一種狀態,比如剛才說到的燈,就有“亮”和“滅”兩種狀態
  • 條件:又稱事件,執行某個操作的觸發條件或者口令,比如燈通過開關控制,操作開關就是一個事件
  • 動作:事件發生以后要執行動作,比如開關按下開關,燈亮,松開則滅
  • 次態:條件滿足后要遷往的新狀態,比如開關按下后燈從當前滅的狀態變為亮的狀態

圖片

用過"RTOS"的朋友應該也知道任務的幾種狀態,任務的四種狀態分別是: 就緒態、運行態、阻塞態、掛起態 ,不會同時出現兩種及兩種以上的狀態存在,OS 根據當前的狀態,和任務優先級、滴答時鐘、主動睡眠等條件進行任務的狀態切換。

狀態機的動作類型

  • 進入動作:在進入狀態時進行
  • 退出動作:在退出狀態時進行
  • 輸入動作:依賴于當前狀態 和 輸入條件進行
  • 轉移動作:在進行特定轉移時進行

實現

首先,看一個簡單的例子,在不同場景下實現控制電機的功能:設備開機啟動三次電機、開關按下一次啟動一次、關機啟動三次電機。采用非狀態機的寫法,通過各種標志位去判斷設備是否需要控制電機,什么條件下退出等。

只是簡單的實現一下,可能其中也有一些狀態機的思想吧(畢竟狀態機編程思想已經在腦海里,不可避免吧),不過我還是盡量還原我初次編程期間的實現這個功能的邏輯思想吧,勿怪。

/* 控制電機函數 */
void MotorCtrlTask(void)
{
    if (ctrlCnt)
    {
        MotorCtrl(ON);
        delay(1);
        MotorCtrl(OFF);
    }
    else
    {
        MotorCtrl(OFF);
    }
}

int isPowerOn = true;
int isPowerOff = false;
int ctrlCnt = 0;

void main(void)
{   
    while (1)
    {
        if (isPowerOn)
        {
            isPowerOn = false;
            ctrlCnt = 3;
        }

        if (keyPress)
        {
            keyPress = false;
            ctrlCnt = 1;
        }

        if (...)  // 關機條件
        {
            if (ctrlCnt == 0 && !isPowerOff && !isPowerOn)
            {
                isPowerOff = true;
                ctrlCnt = 3;
            }
        }

        MotorCtrlTask();

        if (ctrlCnt > 0)
            ctrlCnt--;
        else
        {
            if (ctrlCnt == 0 && isPowerOff && !isPowerOn)
            {
                return;
            }
        }
    }
}

通過采用狀態機編程的方式,首先考慮的就是有三種狀態:開機、關機和工作狀態,先理清楚三種狀態之間轉換的條件和當前狀態需要執行的相關功能,然而在實現過程中就會意識到還需要增加一種過渡狀態:關機準備中(關機過程中需要執行的一系列操作)。

只有邏輯清晰了,才會下意識的察覺少了一些東西了,特別是一些臨界處理等。

int sysState = POWER_OFF; // 默認關機狀態
int ctrlCnt = 0;

/* 控制電機函數 */
void MotorCtrlTask(void)
{
    if (ctrlCnt)
    {
        MotorCtrl(ON);
        delay(1);
        MotorCtrl(OFF);
    }
    else
    {
        MotorCtrl(OFF);
    }
}

void main(void)
{
    while (1)
    {
        switch (sysState)
        {
            case POWER_OFF: // 關機狀態
                sysState = POWER_ON; // 自動切換成開機狀態
                ctrlCnt = 3;
                break;
            case POWER_ON:  // 開機過程狀態
                ... // 開機過程中的其他功能

                if (ctrlCnt == 0) // 控制結束自動切換工作狀態
                {
                    sysState = WORKING;
                    break;
                }
                break;
            case WORKING:  // 工作狀態
                if (...) // 關機條件
                {
                    sysState = POWER_OFF_READY;
                    ctrlCnt = 3;
                    break;
                }

                if (keyPress)
                {
                    keyPress = false;
                    ctrlCnt = 1;
                }
                break;

            case POWER_OFF_READY:  // 關機準備中
                ... // 關機準備中的其他功能

                if (ctrlCnt == 0) // 控制結束自動退出
                {
                    sysState = POWER_OFF;
                    return; // 退出程序
                }
                break;

            default:
                break;
        }

        MotorCtrlTask();

        if (ctrlCnt > 0)
            ctrlCnt--;
    }
}

總結:從上述兩份代碼看,你覺得哪一個邏輯更清晰呢?非狀態機實現方式還有一些異常處理沒有實現,比如開機過程中在啟動三次調節電機過程中按下會有什么現象呢,為了避免這種情況又需要加入多少if條件判斷呢?

適用場景

狀態機應用范圍挺廣的,不止是在C語言中,其他都能使用,準確來說這個屬于一種編程思想。特別是業務功能,狀態機是常用的。

比如常常使用的模塊也有狀態機的身影:比如按鍵的按下和松開,按下又包括按下瞬間、多次按下、持續按下、松開瞬間和持續松開等

通常狀態機和表驅動可以結合使用,狀態機的現態、條件、動作和次態作為數據,執行這些狀態切換的作為邏輯。完全可以根據實際情況靈活使用。

代碼參考:

菜單 :菜單控制,可以這樣理解:當前菜單界面為現態、菜單進入和退出為條件、菜單切換時的函數執行為動作、上下級菜單理解為次態,其中菜單選項表就靈活使用了狀態機和表驅動的方式。

https://gitee.com/const-zpc/menu.git

ESP8266 :AT指令數據表,包含指令、期望響應、時間和函數指針【后續的動作】等,可以這樣理解:數組索引當前值為現態、收到響應和超時為條件、收到響應或超時執行的函數為動作、數組索引的未來值為次態

https://gitee.com/const-zpc/esp8266
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 狀態機
    +關注

    關注

    2

    文章

    492

    瀏覽量

    27529
  • fsm
    fsm
    +關注

    關注

    0

    文章

    35

    瀏覽量

    12822
  • 數學模型
    +關注

    關注

    0

    文章

    83

    瀏覽量

    11933
收藏 人收藏

    評論

    相關推薦

    嵌入式狀態機的幾種大牛才懂的操作

    狀態機嵌入式軟件中隨處可見,可能你會說狀態機有什么難的,不就是 switch 嗎? switch僅僅是最基礎的一個點,關于狀態機的更多操作
    發表于 11-17 10:41 ?1470次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>狀態機</b>的幾種大牛才懂的操作

    嵌入式軟件開發中常用的狀態機編程實現

    嵌入式軟件開發中,狀態機編程是一個十分重要的編程思想,它也是嵌入式開發中一個常用的編程框架。掌握了狀態機編程思想,可以更加邏輯清晰的實現復
    發表于 09-06 10:25 ?2002次閱讀

    為何要進行嵌入式軟件架構設計?如何設計?

    為何要進行嵌入式軟件架構設計?如何進行嵌入式軟件架構設計?
    發表于 11-01 06:31

    嵌入式狀態機編程的概念是什么

    干貨 | 嵌入式狀態機編程干貨篇文章描述了基本的狀態機編程概念,感覺還可以。如果在搭上事件驅動框架,就可以寫一個簡單的RTOS了,這個OS可以作為一種不可剝奪型內核。...
    發表于 12-22 06:25

    嵌入式軟件架構設計資料分享

    作為程序員,我覺得如果要走的更遠必須要成為工程師,畢竟年齡和資歷都擺在那里了。所以就讓我這個老程序員淺談一下嵌入式軟件架構設計。我參考的也是一篇博文。原圖如下![在這里插入圖片描述](?x-oss-process=image/w
    發表于 12-24 07:09

    狀態機嵌入式系統中的應用

    為了便于研究和描述狀態機嵌入式前后臺軟件系統中的應用,本文將以移動2G光纖直放站近端的監控軟件案例來闡述和說明。
    發表于 05-23 10:48 ?2157次閱讀
    <b class='flag-5'>狀態機</b>在<b class='flag-5'>嵌入式</b>系統中的應用

    嵌入式軟件架構設

    嵌入式軟件架構的設計,幫助我們建立合理,有效的軟件架構
    發表于 11-09 17:34 ?19次下載

    嵌入式軟件狀態機的抽象與實現

    文中提出了 在嵌入式軟件中把狀態機作為一個獨立模塊從控制模塊中抽象出來的思想 , 描述了 抽象出來的狀態機模塊 。 并介紹了 如何將這種狀態機
    發表于 03-22 15:47 ?1次下載

    有限狀態機嵌入式系統中的實現及應用

    如何使嵌入式軟件代碼更加可靠 增強程序的可維護性 一直以來都是嵌入式程序員追 求的目標。論述了有限狀態機的原理和其實現方法;采用狀態機方法編
    發表于 03-22 15:40 ?1次下載

    有限狀態機嵌入式軟件中的應用

    有限狀態機嵌入式軟件中的應用,感興趣的小伙伴們可以看看。
    發表于 07-26 10:43 ?27次下載

    嵌入式UI架構設計漫談

    嵌入式UI架構設計漫談
    發表于 11-03 17:36 ?15次下載
    <b class='flag-5'>嵌入式</b>UI<b class='flag-5'>架構設</b>計漫談

    嵌入式狀態機的設置

    狀態機嵌入式軟件中隨處可見,可能你會說狀態機有什么難的,不就是 switch 嗎?
    的頭像 發表于 11-02 09:04 ?1086次閱讀

    嵌入式狀態機的編程優點分析

    嵌入式狀態機編程是真的好用,寫出來的程序結構非常清晰!所以平時用的也比較多。
    的頭像 發表于 02-25 16:21 ?836次閱讀

    嵌入式狀態機的設計與實現

    嵌入式狀態機是一種常用的軟件設計模式,它能夠提高代碼的可讀性和可維護性。狀態機是一個抽象的概念,它描述了一個系統或者組件的不同狀態以及在不同
    的頭像 發表于 04-14 11:55 ?1773次閱讀

    C語言實現嵌入式狀態機簡單描述與應用

    嵌入式狀態機是一種常用的軟件設計模式,它能夠提高代碼的可讀性和可維護性。
    發表于 05-20 14:52 ?1690次閱讀
    主站蜘蛛池模板: 亚洲精品国产专区91在线| 99精品欧美一区二区三区美图| 扒开小处30p| 精品人妻伦九区久久AAA片69| 日本妈妈xxxx| 99精品小视频| 久久精品国产亚洲AV久五月天| 无套内射在线观看THEPORN| chinese极品嫩模videos| 久久精品视频3| 亚洲AV噜噜88| 国产白丝精品爽爽久久蜜臀 | 国产精品JIZZ视频免费| 欧美人与动牲交XXXXBBBB免费| 野花社区视频WWW高清| 国产欧美国日产在线播放| 热久久视久久精品2015| 91福利国产在线观看网站| 精品96在线观看影院| 午夜影院一区二区三区| 岛国大片在线播放高清| 女人久久WWW免费人成看片| 真实伦 乱| 久久99热这里只有精品66| 亚洲精品嫩草研究院久久| 国产精品路线1路线2路线 | 午夜性爽视频男人的天堂在线 | 免费三级现频在线观看| 真实农村女人野外自拍照片| 精子网久久国产精品| 亚洲精品久久久久中文字幕二区| 国产高清视频在线观看97 | 99re这里只有精品视频| 两个人在线观看的视频720 | 9国产露脸精品国产麻豆| 蜜芽国产在线精品欧美| 中文字幕亚洲无线码高清不卡| 久久99精品AV99果冻| 亚洲永久精品AV在线观看| 精品久久久无码21P发布| 亚洲精品久久无码AV片WWW|