日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 大橙子瘋嵌入式


前言

之前介紹的狀態(tài)機(jī)是有限狀態(tài)機(jī)(FSM),這篇介紹一下分層狀態(tài)機(jī)(HSM)的理解。

分層狀態(tài)機(jī)是一種用于描述系統(tǒng)行為和控制流的模型,它將系統(tǒng)劃分為多個層級,并將每個層級表示為一個狀態(tài)機(jī)。每個狀態(tài)機(jī)描述了一個特定的狀態(tài)集合以及狀態(tài)之間的轉(zhuǎn)移規(guī)則。每個狀態(tài)機(jī)都有自己的輸入和輸出,可以與其他狀態(tài)機(jī)進(jìn)行交互,從而形成整個系統(tǒng)的行為。

分層狀態(tài)機(jī)的設(shè)計有助于降低系統(tǒng)復(fù)雜度,并且能夠更好地組織系統(tǒng)的功能和行為。在分層狀態(tài)機(jī)中,每個狀態(tài)機(jī)負(fù)責(zé)處理一個特定的子任務(wù)或功能,這使得系統(tǒng)更易于理解和維護(hù)。
在分層狀態(tài)機(jī)中,高層狀態(tài)機(jī)負(fù)責(zé)協(xié)調(diào)和控制下層狀態(tài)機(jī)的行為。高層狀態(tài)機(jī)可以通過向下層狀態(tài)機(jī)發(fā)送命令或事件來觸發(fā)狀態(tài)轉(zhuǎn)換,下層狀態(tài)機(jī)可以將其處理結(jié)果返回給上層狀態(tài)機(jī),以便上層狀態(tài)機(jī)作出相應(yīng)的決策。

區(qū)別

分層狀態(tài)機(jī)(HSM)和有限狀態(tài)機(jī)(FSM)是兩種不同的模型,雖然它們都用于描述系統(tǒng)的行為和控制流,但它們之間還是存在一些區(qū)別的。

  1. 層次結(jié)構(gòu)不同:分層狀態(tài)機(jī)是將系統(tǒng)劃分為多個層級,并將每個層級表示為一個狀態(tài)機(jī),每個狀態(tài)機(jī)有自己的輸入和輸出,可以與其他狀態(tài)機(jī)進(jìn)行交互,形成整個系統(tǒng)的行為。而有限狀態(tài)機(jī)則是單層的結(jié)構(gòu),描述系統(tǒng)在特定條件下的狀態(tài)和狀態(tài)之間的轉(zhuǎn)移。

  2. 狀態(tài)數(shù)量不同:分層狀態(tài)機(jī)中的狀態(tài)數(shù)量通常比有限狀態(tài)機(jī)更多。由于分層狀態(tài)機(jī)的每個層級都有自己的狀態(tài)集合,因此整個系統(tǒng)的狀態(tài)集合是各層狀態(tài)集合的并集。而有限狀態(tài)機(jī)只有一個狀態(tài)集合,狀態(tài)數(shù)量相對較少。

  3. 狀態(tài)之間的轉(zhuǎn)移規(guī)則不同:在分層狀態(tài)機(jī)中,狀態(tài)之間的轉(zhuǎn)移規(guī)則可以根據(jù)不同的層級進(jìn)行定義,每個狀態(tài)機(jī)有自己的轉(zhuǎn)移規(guī)則。而有限狀態(tài)機(jī)的狀態(tài)之間的轉(zhuǎn)移規(guī)則通常是全局統(tǒng)一的。

  4. 功能不同:分層狀態(tài)機(jī)通常用于描述復(fù)雜系統(tǒng)的行為和控制流,其設(shè)計目的是為了降低系統(tǒng)的復(fù)雜度并更好地組織系統(tǒng)的功能和行為。而有限狀態(tài)機(jī)通常用于描述簡單的控制流程或者算法。

總之,分層狀態(tài)機(jī)和有限狀態(tài)機(jī)雖然都是描述系統(tǒng)行為和控制流的模型,但是它們的層次結(jié)構(gòu)、狀態(tài)數(shù)量、狀態(tài)之間的轉(zhuǎn)移規(guī)則和應(yīng)用場景等方面存在較大的不同

舉例說明

假設(shè)有一個自動售貨機(jī),它需要根據(jù)用戶選擇的按鈕來售出對應(yīng)的商品。我們可以使用有限狀態(tài)機(jī)和分層狀態(tài)機(jī)分別來實(shí)現(xiàn)這個自動售貨機(jī)。

首先,我們來看一下如何使用有限狀態(tài)機(jī)來實(shí)現(xiàn)自動售貨機(jī)。假設(shè)我們有三個商品可以售賣,分別是飲料、糖果和薯片,對應(yīng)的按鈕分別為A、B和C。那么,我們可以定義以下狀態(tài):

  • 初始狀態(tài):待命狀態(tài)

  • 狀態(tài)1:等待用戶選擇按鈕

  • 狀態(tài)2:出貨狀態(tài)

根據(jù)這些狀態(tài),我們可以設(shè)計狀態(tài)轉(zhuǎn)移規(guī)則如下:

  • 待命狀態(tài):如果用戶按下按鈕A、B或C,則轉(zhuǎn)移到等待用戶選擇按鈕狀態(tài)。

  • 等待用戶選擇按鈕狀態(tài):如果用戶按下按鈕A,則轉(zhuǎn)移到出貨狀態(tài)1;如果用戶按下按鈕B,則轉(zhuǎn)移到出貨狀態(tài)2;如果用戶按下按鈕C,則轉(zhuǎn)移到出貨狀態(tài)3。

  • 出貨狀態(tài)1:出售飲料,并轉(zhuǎn)移到待命狀態(tài)。

  • 出貨狀態(tài)2:出售糖果,并轉(zhuǎn)移到待命狀態(tài)。

  • 出貨狀態(tài)3:出售薯片,并轉(zhuǎn)移到待命狀態(tài)。

流程圖:

接下來,我們來看一下如何使用分層狀態(tài)機(jī)來實(shí)現(xiàn)自動售貨機(jī)。首先,我們可以將自動售貨機(jī)分解成三個層次:選擇商品層、支付層和出貨層。每個層次都有自己的狀態(tài)和狀態(tài)轉(zhuǎn)移規(guī)則,如下所示:

  • 選擇商品層:等待用戶選擇按鈕狀態(tài)

  • 支付層:等待用戶支付狀態(tài)

  • 出貨層:出貨狀態(tài)

然后,我們可以進(jìn)一步細(xì)化每個層次的狀態(tài)和狀態(tài)轉(zhuǎn)移規(guī)則,如下所示:

  • 選擇商品層:

    • 初始狀態(tài):待命狀態(tài)

    • 狀態(tài)1:等待用戶選擇按鈕

    • 轉(zhuǎn)移規(guī)則:如果用戶按下按鈕A、B或C,則轉(zhuǎn)移到等待用戶支付狀態(tài),并保存用戶選擇的商品。

  • 支付層:

    • 初始狀態(tài):待命狀態(tài)

    • 狀態(tài)1:等待用戶支付

    • 轉(zhuǎn)移規(guī)則:如果用戶完成支付,則轉(zhuǎn)移到出貨狀態(tài),并發(fā)送出貨指令。

  • 出貨層:

    • 初始狀態(tài):待命狀態(tài)

    • 狀態(tài)1:等待出貨指令

    • 狀態(tài)2:正在出貨

    • 轉(zhuǎn)移規(guī)則:如果接收到出貨指令,則轉(zhuǎn)移到正在出貨狀態(tài),并執(zhí)行出貨操作;如果出貨操作完成,則轉(zhuǎn)移到待命狀態(tài)。

流程圖:

需要注意的是,有限狀態(tài)機(jī)和分層狀態(tài)機(jī)都可以用于自動售貨機(jī)的設(shè)計,選擇哪種方法取決于具體的需求和復(fù)雜度。如果系統(tǒng)相對簡單,可以使用有限狀態(tài)機(jī)。如果需要管理多個子系統(tǒng)、處理多個事件和狀態(tài),可以考慮使用分層狀態(tài)機(jī)。

最重要的是,在實(shí)際應(yīng)用中,理解分層狀態(tài)機(jī)的關(guān)鍵是正確地設(shè)計狀態(tài)轉(zhuǎn)移邏輯和事件處理函數(shù)。如果狀態(tài)轉(zhuǎn)移邏輯不正確,可能會導(dǎo)致狀態(tài)機(jī)無法正確響應(yīng)事件;如果事件處理函數(shù)不正確,可能會導(dǎo)致狀態(tài)機(jī)無法正確處理事件。因此,在設(shè)計分層狀態(tài)機(jī)時,需要認(rèn)真考慮狀態(tài)轉(zhuǎn)移和事件處理的邏輯,并進(jìn)行充分的測試和驗(yàn)證。

代碼參考

有限狀態(tài)機(jī)

有限狀態(tài)機(jī)可以使用switch/case或if/else語句實(shí)現(xiàn)狀態(tài)轉(zhuǎn)移,并在每個狀態(tài)轉(zhuǎn)移時執(zhí)行相應(yīng)的操作。

#include  #include  enum State
{
 ST_IDLE,
 ST_WAIT_SELECT,
 ST_WAIT_PAY,
 ST_DISPENSE
}; enum Button
{
 BTN_NONE,
 BTN_A,
 BTN_B,
 BTN_C
}; enum State current_state = ST_IDLE; enum Button current_button = BTN_NONE; void update_fsm(enum Button button) { switch (current_state)
 { case ST_IDLE: if (button != BTN_NONE)
 {
 current_button = button;
 current_state = ST_WAIT_SELECT; printf("商品選擇: %c\n", button);
 } break; case ST_WAIT_SELECT: if (button == BTN_NONE)
 {
 current_state = ST_WAIT_PAY; printf("等待支付...\n");
 } break; case ST_WAIT_PAY: if (button == BTN_NONE)
 {
 current_state = ST_DISPENSE; printf("出貨中...\n");
 } break; case ST_DISPENSE: if (button == BTN_NONE)
 {
 current_state = ST_IDLE; printf("出售完成\n");
 } break;
 }
} int main() {
 update_fsm(BTN_NONE);
 update_fsm(BTN_A);
 update_fsm(BTN_NONE);
 update_fsm(BTN_NONE);
 update_fsm(BTN_NONE);
 update_fsm(BTN_NONE); return 0;
}

分層狀態(tài)機(jī)

而分層狀態(tài)機(jī)中由于更加復(fù)雜,單純地采用switch/case或if/else語句已經(jīng)不太適合不同狀態(tài)機(jī)及其子狀態(tài)的轉(zhuǎn)移,最好的方式是采用表驅(qū)動的方式去實(shí)現(xiàn),然后在數(shù)組表中定義每個狀態(tài)機(jī)及其子狀態(tài),并且有回調(diào)函數(shù)用來處理每個狀態(tài)機(jī)及其子狀態(tài)的處理等,提高系統(tǒng)的可維護(hù)性和可擴(kuò)展性。

由于實(shí)現(xiàn)較為復(fù)雜,以下代碼僅供參考,不具體實(shí)現(xiàn)

#include  #include  #include  // 狀態(tài)機(jī)狀態(tài)枚舉 typedef enum {
 STATE_IDLE,
 STATE_WAITING_FOR_COIN,
 STATE_WAITING_FOR_SELECTION,
 STATE_DISPENSING,
 STATE_COUNT
} state_t; // 事件枚舉 typedef enum {
 EVENT_INSERT_COIN,
 EVENT_MAKE_SELECTION,
 EVENT_DISPENSE,
 EVENT_COUNT
} event_t; // 狀態(tài)轉(zhuǎn)移條件函數(shù)類型定義 typedef bool (*condition_func_t)(void); // 狀態(tài)機(jī)狀態(tài)結(jié)構(gòu)體定義 typedef struct { void (*enter_func)(void); // 進(jìn)入狀態(tài)函數(shù) void (*exit_func)(void); // 退出狀態(tài)函數(shù) void (*poll_func)(void); // 事件輪詢處理函數(shù) condition_func_t (*cond_func)(void); // 轉(zhuǎn)移條件函數(shù) } state_info_t; // 狀態(tài)轉(zhuǎn)移表 static const int transition_table[STATE_COUNT][EVENT_COUNT] = { // EVENT_INSERT_COIN    EVENT_MAKE_SELECTION    EVENT_DISPENSE { STATE_WAITING_FOR_COIN, STATE_IDLE,           STATE_IDLE           }, // STATE_IDLE { STATE_WAITING_FOR_COIN, STATE_WAITING_FOR_SELECTION, STATE_IDLE }, // STATE_WAITING_FOR_COIN { STATE_WAITING_FOR_COIN, STATE_WAITING_FOR_SELECTION, STATE_DISPENSING }, // STATE_WAITING_FOR_SELECTION { STATE_WAITING_FOR_COIN, STATE_WAITING_FOR_SELECTION, STATE_IDLE } // STATE_DISPENSING }; // 狀態(tài)機(jī)狀態(tài)數(shù)組 static const state_info_t state_table[STATE_COUNT] = { // 進(jìn)入狀態(tài)函數(shù)            退出狀態(tài)函數(shù)               事件輪詢處理函數(shù)                轉(zhuǎn)移條件函數(shù) { NULL, NULL, NULL, NULL }, // STATE_IDLE { wait_for_coin_enter, wait_for_coin_exit, wait_for_coin_poll, wait_for_coin }, // STATE_WAITING_FOR_COIN { wait_for_select_enter, wait_for_select_exit, wait_for_select_poll, waiting_for_select }, // STATE_WAITING_FOR_SELECTION { dispensing_enter, dispensing_exit, dispensing_poll, dispensing } // STATE_DISPENSING }; // 當(dāng)前狀態(tài) static state_t current_state = STATE_IDLE;




本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉