在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

3天內不再提示

狀態機要實現哪些內容

科技綠洲 ? 來源:一起學嵌入式 ? 作者:一起學嵌入式 ? 2023-06-22 14:26 ? 次閱讀

狀態機模式是一種行為模式,通過多態實現不同狀態的調轉行為的確是一種很好的方法,只可惜在嵌入式環境下,有時只能寫純C代碼,并且還需要考慮代碼的重入和多任務請求跳轉等情形,因此實現起來著實需要一番考慮。

近日在看到了一個狀態機的實現,也學著寫了一個,與大家分享。

首先,分析一下一個普通的狀態機究竟要實現哪些內容。

狀態機存儲從開始時刻到現在的變化,并根據當前輸入,決定下一個狀態。這意味著,狀態機要存儲狀態、獲得輸入(我們把它叫做跳轉條件)、做出響應。

圖片

如上圖所示,{s1, s2, s3}均為狀態,箭頭c1/a1表示在s1狀態、輸入為c1時,跳轉到s2,并進行a1操作。

最下方為一組輸入,狀態機應做出如下反應:

圖片

當某個狀態遇到不能識別的輸入時,就默認進入陷阱狀態,在陷阱狀態中,不論遇到怎樣的輸入都不能跳出。

為了表達上面這個自動機,我們定義它們的狀態和輸入類型:

typedef int State;
typedef int Condition;
 
#define STATES 3 + 1
#define STATE_1 0
#define STATE_2 1
#define STATE_3 2
#define STATE_TRAP 3
 
#define CONDITIONS 2
#define CONDITION_1 0
#define CONDITION_2 1

在嵌入式環境中,由于存儲空間比較小,因此把它們全部定義成宏。此外,為了降低執行時間的不確定性,我們使用O(1)的跳轉表來模擬狀態的跳轉。

首先定義跳轉類型:

typedef void (*ActionType)(State state, Condition condition);
 
typedef struct
{
    State next;
    ActionType action;
} Trasition, * pTrasition;

然后按照上圖中的跳轉關系,把三個跳轉加一個陷阱跳轉先定義出來:

// (s1, c1, s2, a1)
Trasition t1 = {
    STATE_2,
    action_1
};
 
// (s2, c2, s3, a2)
Trasition t2 = {
    STATE_3,
    action_2
};
 
// (s3, c1, s2, a3)
Trasition t3 = {
    STATE_2,
    action_3
};
 
// (s, c, trap, a1)
Trasition tt = {
    STATE_TRAP,
    action_trap
};

其中的動作,由用戶自己完成,在這里僅定義一條輸出語句。

void action_1(State state, Condition condition)
{
    printf("Action 1 triggered.\\n");
}

最后定義跳轉表:

pTrasition transition_table[STATES][CONDITIONS] = {
/*      c1,  c2*/
/* s1 */&t1, &tt,
/* s2 */&tt, &t2,
/* s3 */&t3, &tt,
/* st */&tt, &tt,
};

即可表達上文中的跳轉關系。

最后定義狀態機,如果不考慮多任務請求,那么狀態機僅需要存儲當前狀態便行了。例如:

typedef struct
{
    State current;
} StateMachine, * pStateMachine;
 
State step(pStateMachine machine, Condition condition)
{
    pTrasition t = transition_table[machine- >current][condition];
    (*(t- >action))(machine- >current, condition);
    machine- >current = t- >next;
    return machine- >current;
}

但是考慮到當一個跳轉正在進行的時候,同時又有其他任務請求跳轉,則會出現數據不一致的問題。

舉個例子:task1(s1, c1/a1 –> s2)和task2(s2, c2/a2 –> s3)先后執行,是可以順利到達s3狀態的,但若操作a1運行的時候,執行權限被task2搶占,則task2此時看到的當前狀態還是s1,s1遇到c2就進入陷阱狀態,而不會到達s3了,也就是說,狀態的跳轉發生了不確定,這是不能容忍的。

因此要重新設計狀態機,增加一個“事務中”條件和一個用于存儲輸入的條件隊列。修改后的代碼如下:

#define E_OK        0
#define E_NO_DATA   1
#define E_OVERFLOW  2
 
typedef struct
{
    Condition queue[QMAX];
    int head;
    int tail;
    bool overflow;
} ConditionQueue, * pConditionQueue;
 
 
int push(ConditionQueue * queue, Condition c)
{   
    unsigned int flags;
    Irq_Save(flags);
    if ((queue- >head == queue- >tail + 1) || ((queue- >head == 0) && (queue- >tail == 0)))
    {
        queue- >overflow = true;
        Irq_Restore(flags);
        return E_OVERFLOW;
    }
    else
    {
        queue- >queue[queue- >tail] = c;
        queue- >tail = (queue- >tail + 1) % QMAX;
        Irq_Restore(flags);
    }
    return E_OK;
}
 
int poll(ConditionQueue * queue, Condition * c)
{
    unsigned int flags;
    Irq_Save(flags);
    if (queue- >head == queue- >tail)
    {
        Irq_Restore(flags);
        return E_NO_DATA;
    }
    else
    {
        *c = queue- >queue[queue- >head];
        queue- >overflow = false;
        queue- >head = (queue- >head + 1) % QMAX;
        Irq_Restore(flags);
    }
    return E_OK;
}
 
typedef struct
{
    State current;
    bool inTransaction;
    ConditionQueue queue;
} StateMachine, * pStateMachine;
 
static State __step(pStateMachine machine, Condition condition)
{
    State current = machine - > current;
    pTrasition t = transition_table[current][condition];
    (*(t- >action))(current, condition);
    current = t- >next;
    machine- >current = current;
    return current;
}
 
State step(pStateMachine machine, Condition condition)
{
    Condition next_condition;
    int status;
    State current;
    if (machine- >inTransaction)
    {
        push(&(machine- >queue), condition);
        return STATE_INTRANSACTION;
    }
    else
    {
        machine- >inTransaction = true;
        current = __step(machine, condition);
        status = poll(&(machine- >queue), &next_condition);
        while(status == E_OK)
        {
            __step(machine, next_condition);
            status = poll(&(machine- >queue), &next_condition);
        }
        machine- >inTransaction = false;
        return current;
    }
}
 
void initialize(pStateMachine machine, State s)
{
    machine- >current = s;
    machine- >inTransaction = false;
    machine- >queue.head = 0;
    machine- >queue.tail = 0;
    machine- >queue.overflow = false;
}
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4883

    瀏覽量

    70100
  • 狀態機
    +關注

    關注

    2

    文章

    493

    瀏覽量

    28000
  • 存儲空間
    +關注

    關注

    0

    文章

    55

    瀏覽量

    10850
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    Spring狀態機實現原理和使用方法

    說起 Spring 狀態機,大家很容易聯想到這個狀態機和設計模式中狀態模式的區別是啥呢?沒錯,Spring 狀態機就是狀態模式的一種
    的頭像 發表于 12-26 09:39 ?2467次閱讀
    Spring<b class='flag-5'>狀態機</b>的<b class='flag-5'>實現</b>原理和使用方法

    如何寫好狀態機

    如何寫好狀態機:狀態機是邏輯設計的重要內容,狀態機的設計水平直接反應工程師的邏輯功底,所以許多公司的硬件和邏輯工程師面試中,狀態機設計幾乎是
    發表于 06-14 19:24 ?97次下載

    狀態機舉例

    狀態機舉例 你可以指定狀態寄存器和狀態機狀態。以下是一個有四種狀態的普通狀態機。 // Th
    發表于 03-28 15:18 ?1062次閱讀

    狀態機原理及用法

    狀態機原理及用法狀態機原理及用法狀態機原理及用法
    發表于 03-15 15:25 ?0次下載

    利用狀態機狀態機實現層次結構化設計

    練習九.利用狀態機的嵌套實現層次結構化設計目的:1.運用主狀態機與子狀態機產生層次化的邏輯設計;
    發表于 02-11 05:52 ?3424次閱讀
    利用<b class='flag-5'>狀態機</b>的<b class='flag-5'>狀態機</b><b class='flag-5'>實現</b>層次結構化設計

    狀態機概述 如何理解狀態機

    本篇文章包括狀態機的基本概述以及通過簡單的實例理解狀態機
    的頭像 發表于 01-02 18:03 ?1.1w次閱讀
    <b class='flag-5'>狀態機</b>概述  如何理解<b class='flag-5'>狀態機</b>

    基于FPGA實現狀態機的設計

    狀態機有三種描述方式:一段式狀態機、兩段式狀態機、三段式狀態機。下面就用一個小例子來看看三種方式是如何實現的。
    的頭像 發表于 08-29 06:09 ?3020次閱讀
    基于FPGA<b class='flag-5'>實現狀態機</b>的設計

    如何使用狀態機實現對TLC549的采樣控制

    本文檔的主要內容詳細介紹的是如何使用狀態機實現對TLC549的采樣控制。
    發表于 08-07 17:39 ?9次下載
    如何使用<b class='flag-5'>狀態機</b><b class='flag-5'>實現</b>對TLC549的采樣控制

    使用函數指針的方法實現狀態機

    之前寫過一篇狀態機的實用文章,很多朋友說有幾個地方有點難度不易理解,今天給大家換種簡單寫法,使用函數指針的方法實現狀態機。 狀態機簡介 有限狀態機FSM是有限個
    的頭像 發表于 10-19 09:36 ?2555次閱讀
    使用函數指針的方法<b class='flag-5'>實現狀態機</b>

    FPGA:狀態機簡述

    本文目錄 前言 狀態機簡介 狀態機分類 Mealy 型狀態機 Moore 型狀態機 狀態機描述 一段式
    的頭像 發表于 11-05 17:58 ?7839次閱讀
    FPGA:<b class='flag-5'>狀態機</b>簡述

    狀態模式(狀態機)

    share,作者:亞索老哥)),原來狀態機還可以這么簡單地玩~~亞索老哥提出的狀態機六步法(1)、定義狀態接口(2)、定義系統當前狀態指針(3)、定義具體
    發表于 12-16 16:53 ?9次下載
    <b class='flag-5'>狀態</b>模式(<b class='flag-5'>狀態機</b>)

    LABVIEW的狀態機實現資料合集

    LABVIEW的狀態機實現資料合集
    發表于 01-04 11:18 ?49次下載

    如何在FPGA中實現狀態機

    狀態機往往是FPGA 開發的主力。選擇合適的架構和實現方法將確保您獲得一款最佳解決方案。 FPGA 常常用于執行基于序列和控制的行動, 比如實現一個簡單的通信協議。對于設計人員來說,滿足這些行動
    的頭像 發表于 07-18 16:05 ?1371次閱讀
    如何在FPGA中<b class='flag-5'>實現狀態機</b>

    什么是狀態機?狀態機的種類與實現

    狀態機,又稱有限狀態機(Finite State Machine,FSM)或米利狀態機(Mealy Machine),是一種描述系統狀態變化的模型。在芯片設計中,
    的頭像 發表于 10-19 10:27 ?1.1w次閱讀

    如何在FPGA中實現狀態機

    在FPGA(現場可編程門陣列)中實現狀態機是一種常見的做法,用于控制復雜的數字系統行為。狀態機能夠根據當前的輸入和系統狀態,決定下一步的動作和新的狀態。這里,我們將詳細探討如何在FPG
    的頭像 發表于 07-18 15:57 ?1016次閱讀
    主站蜘蛛池模板: 在线观看的黄网 | 免费黄色网址网站 | 黄色视屏免费在线观看 | 国产三级在线看 | 丁香婷婷啪啪 | 伦理片日本韩国电影三级在线观看 | 未满十八18周岁禁止免费国产 | 五月丁香六月综合缴清无码 | 男同小黄文 | 欧美色淫网站免费观看 | 日韩三级久久 | 中文字幕一区2区 | 李老汉的性生生活1全部 | a一级黄 | 天天做夜夜爱 | 日本www网站 | 一本在线免费视频 | 2018天天操天天干 | 色在线观看视频 | 婷婷九月色 | 成年人网站免费观看 | 亚洲色图综合图区 | 91黄视频在线观看 | 国产好深好硬好爽我还要视频 | 九九涩| 日韩欧美中文字幕在线视频 | 小屁孩cao大人免费网站 | 在线看片你懂得 | 久久这里只有精品1 | 亚洲综合黄色 | 人人做人人爽 | 日韩欧美中文字幕在线播放 | 一区二区三区四区免费视频 | 可以免费看黄的网站 | 日日操夜夜操免费视频 | 国产午夜精品片一区二区三区 | 亚洲国产高清精品线久久 | 国产亚洲精品aa在线看 | 天天躁狠狠躁夜夜躁 | www射| 男人的j桶女人的j视频 |