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

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

狀態(tài)機(jī)要實(shí)現(xiàn)哪些內(nèi)容

科技綠洲 ? 來(lái)源:一起學(xué)嵌入式 ? 作者:一起學(xué)嵌入式 ? 2023-06-22 14:26 ? 次閱讀

狀態(tài)機(jī)模式是一種行為模式,通過(guò)多態(tài)實(shí)現(xiàn)不同狀態(tài)的調(diào)轉(zhuǎn)行為的確是一種很好的方法,只可惜在嵌入式環(huán)境下,有時(shí)只能寫(xiě)純C代碼,并且還需要考慮代碼的重入和多任務(wù)請(qǐng)求跳轉(zhuǎn)等情形,因此實(shí)現(xiàn)起來(lái)著實(shí)需要一番考慮。

近日在看到了一個(gè)狀態(tài)機(jī)的實(shí)現(xiàn),也學(xué)著寫(xiě)了一個(gè),與大家分享。

首先,分析一下一個(gè)普通的狀態(tài)機(jī)究竟要實(shí)現(xiàn)哪些內(nèi)容。

狀態(tài)機(jī)存儲(chǔ)從開(kāi)始時(shí)刻到現(xiàn)在的變化,并根據(jù)當(dāng)前輸入,決定下一個(gè)狀態(tài)。這意味著,狀態(tài)機(jī)要存儲(chǔ)狀態(tài)、獲得輸入(我們把它叫做跳轉(zhuǎn)條件)、做出響應(yīng)。

圖片

如上圖所示,{s1, s2, s3}均為狀態(tài),箭頭c1/a1表示在s1狀態(tài)、輸入為c1時(shí),跳轉(zhuǎn)到s2,并進(jìn)行a1操作。

最下方為一組輸入,狀態(tài)機(jī)應(yīng)做出如下反應(yīng):

圖片

當(dāng)某個(gè)狀態(tài)遇到不能識(shí)別的輸入時(shí),就默認(rèn)進(jìn)入陷阱狀態(tài),在陷阱狀態(tài)中,不論遇到怎樣的輸入都不能跳出。

為了表達(dá)上面這個(gè)自動(dòng)機(jī),我們定義它們的狀態(tài)和輸入類(lèi)型:

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

在嵌入式環(huán)境中,由于存儲(chǔ)空間比較小,因此把它們?nèi)慷x成宏。此外,為了降低執(zhí)行時(shí)間的不確定性,我們使用O(1)的跳轉(zhuǎn)表來(lái)模擬狀態(tài)的跳轉(zhuǎn)。

首先定義跳轉(zhuǎn)類(lèi)型:

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

然后按照上圖中的跳轉(zhuǎn)關(guān)系,把三個(gè)跳轉(zhuǎn)加一個(gè)陷阱跳轉(zhuǎn)先定義出來(lái):

// (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
};

其中的動(dòng)作,由用戶(hù)自己完成,在這里僅定義一條輸出語(yǔ)句。

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

最后定義跳轉(zhuǎn)表:

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

即可表達(dá)上文中的跳轉(zhuǎn)關(guān)系。

最后定義狀態(tài)機(jī),如果不考慮多任務(wù)請(qǐng)求,那么狀態(tài)機(jī)僅需要存儲(chǔ)當(dāng)前狀態(tài)便行了。例如:

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;
}

但是考慮到當(dāng)一個(gè)跳轉(zhuǎn)正在進(jìn)行的時(shí)候,同時(shí)又有其他任務(wù)請(qǐng)求跳轉(zhuǎn),則會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題。

舉個(gè)例子:task1(s1, c1/a1 –> s2)和task2(s2, c2/a2 –> s3)先后執(zhí)行,是可以順利到達(dá)s3狀態(tài)的,但若操作a1運(yùn)行的時(shí)候,執(zhí)行權(quán)限被task2搶占,則task2此時(shí)看到的當(dāng)前狀態(tài)還是s1,s1遇到c2就進(jìn)入陷阱狀態(tài),而不會(huì)到達(dá)s3了,也就是說(shuō),狀態(tài)的跳轉(zhuǎn)發(fā)生了不確定,這是不能容忍的。

因此要重新設(shè)計(jì)狀態(tài)機(jī),增加一個(gè)“事務(wù)中”條件和一個(gè)用于存儲(chǔ)輸入的條件隊(duì)列。修改后的代碼如下:

#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;
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4788

    瀏覽量

    68603
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    492

    瀏覽量

    27539
  • 存儲(chǔ)空間
    +關(guān)注

    關(guān)注

    0

    文章

    54

    瀏覽量

    10685
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Spring狀態(tài)機(jī)實(shí)現(xiàn)原理和使用方法

    說(shuō)起 Spring 狀態(tài)機(jī),大家很容易聯(lián)想到這個(gè)狀態(tài)機(jī)和設(shè)計(jì)模式中狀態(tài)模式的區(qū)別是啥呢?沒(méi)錯(cuò),Spring 狀態(tài)機(jī)就是狀態(tài)模式的一種
    的頭像 發(fā)表于 12-26 09:39 ?2006次閱讀
    Spring<b class='flag-5'>狀態(tài)機(jī)</b>的<b class='flag-5'>實(shí)現(xiàn)</b>原理和使用方法

    如何寫(xiě)好狀態(tài)機(jī)

    一篇經(jīng)典文獻(xiàn),詳細(xì)講解了一段、兩段、三段式狀態(tài)機(jī)實(shí)現(xiàn),效率、優(yōu)缺點(diǎn)。看完后相信會(huì)對(duì)狀態(tài)機(jī)有一個(gè)詳細(xì)的了解。 狀態(tài)機(jī)是邏輯設(shè)計(jì)的重要內(nèi)容
    發(fā)表于 10-24 11:43

    如何寫(xiě)好狀態(tài)機(jī)

    如何寫(xiě)好狀態(tài)機(jī):狀態(tài)機(jī)是邏輯設(shè)計(jì)的重要內(nèi)容狀態(tài)機(jī)的設(shè)計(jì)水平直接反應(yīng)工程師的邏輯功底,所以許多公司的硬件和邏輯工程師面試中,狀態(tài)機(jī)設(shè)計(jì)幾乎是
    發(fā)表于 06-14 19:24 ?97次下載

    狀態(tài)機(jī)原理及用法

    狀態(tài)機(jī)原理及用法狀態(tài)機(jī)原理及用法狀態(tài)機(jī)原理及用法
    發(fā)表于 03-15 15:25 ?0次下載

    利用狀態(tài)機(jī)狀態(tài)機(jī)實(shí)現(xiàn)層次結(jié)構(gòu)化設(shè)計(jì)

    練習(xí)九.利用狀態(tài)機(jī)的嵌套實(shí)現(xiàn)層次結(jié)構(gòu)化設(shè)計(jì)目的:1.運(yùn)用主狀態(tài)機(jī)與子狀態(tài)機(jī)產(chǎn)生層次化的邏輯設(shè)計(jì);
    發(fā)表于 02-11 05:52 ?3312次閱讀
    利用<b class='flag-5'>狀態(tài)機(jī)</b>的<b class='flag-5'>狀態(tài)機(jī)</b><b class='flag-5'>實(shí)現(xiàn)</b>層次結(jié)構(gòu)化設(shè)計(jì)

    狀態(tài)機(jī)概述 如何理解狀態(tài)機(jī)

    本篇文章包括狀態(tài)機(jī)的基本概述以及通過(guò)簡(jiǎn)單的實(shí)例理解狀態(tài)機(jī)
    的頭像 發(fā)表于 01-02 18:03 ?1w次閱讀
    <b class='flag-5'>狀態(tài)機(jī)</b>概述  如何理解<b class='flag-5'>狀態(tài)機(jī)</b>

    基于FPGA實(shí)現(xiàn)狀態(tài)機(jī)的設(shè)計(jì)

    狀態(tài)機(jī)有三種描述方式:一段式狀態(tài)機(jī)、兩段式狀態(tài)機(jī)、三段式狀態(tài)機(jī)。下面就用一個(gè)小例子來(lái)看看三種方式是如何實(shí)現(xiàn)的。
    的頭像 發(fā)表于 08-29 06:09 ?2853次閱讀
    基于FPGA<b class='flag-5'>實(shí)現(xiàn)狀態(tài)機(jī)</b>的設(shè)計(jì)

    如何使用狀態(tài)機(jī)實(shí)現(xiàn)對(duì)TLC549的采樣控制

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何使用狀態(tài)機(jī)實(shí)現(xiàn)對(duì)TLC549的采樣控制。
    發(fā)表于 08-07 17:39 ?9次下載
    如何使用<b class='flag-5'>狀態(tài)機(jī)</b><b class='flag-5'>實(shí)現(xiàn)</b>對(duì)TLC549的采樣控制

    使用函數(shù)指針的方法實(shí)現(xiàn)狀態(tài)機(jī)

    之前寫(xiě)過(guò)一篇狀態(tài)機(jī)的實(shí)用文章,很多朋友說(shuō)有幾個(gè)地方有點(diǎn)難度不易理解,今天給大家換種簡(jiǎn)單寫(xiě)法,使用函數(shù)指針的方法實(shí)現(xiàn)狀態(tài)機(jī)狀態(tài)機(jī)簡(jiǎn)介 有限狀態(tài)機(jī)FSM是有限個(gè)
    的頭像 發(fā)表于 10-19 09:36 ?2411次閱讀
    使用函數(shù)指針的方法<b class='flag-5'>實(shí)現(xiàn)狀態(tài)機(jī)</b>

    FPGA:狀態(tài)機(jī)簡(jiǎn)述

    本文目錄 前言 狀態(tài)機(jī)簡(jiǎn)介 狀態(tài)機(jī)分類(lèi) Mealy 型狀態(tài)機(jī) Moore 型狀態(tài)機(jī) 狀態(tài)機(jī)描述 一段式
    的頭像 發(fā)表于 11-05 17:58 ?7401次閱讀
    FPGA:<b class='flag-5'>狀態(tài)機(jī)</b>簡(jiǎn)述

    狀態(tài)模式(狀態(tài)機(jī))

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

    LABVIEW的狀態(tài)機(jī)實(shí)現(xiàn)資料合集

    LABVIEW的狀態(tài)機(jī)實(shí)現(xiàn)資料合集
    發(fā)表于 01-04 11:18 ?47次下載

    如何在FPGA中實(shí)現(xiàn)狀態(tài)機(jī)

    狀態(tài)機(jī)往往是FPGA 開(kāi)發(fā)的主力。選擇合適的架構(gòu)和實(shí)現(xiàn)方法將確保您獲得一款最佳解決方案。 FPGA 常常用于執(zhí)行基于序列和控制的行動(dòng), 比如實(shí)現(xiàn)一個(gè)簡(jiǎn)單的通信協(xié)議。對(duì)于設(shè)計(jì)人員來(lái)說(shuō),滿(mǎn)足這些行動(dòng)
    的頭像 發(fā)表于 07-18 16:05 ?1097次閱讀
    如何在FPGA中<b class='flag-5'>實(shí)現(xiàn)狀態(tài)機(jī)</b>

    什么是狀態(tài)機(jī)狀態(tài)機(jī)的種類(lèi)與實(shí)現(xiàn)

    狀態(tài)機(jī),又稱(chēng)有限狀態(tài)機(jī)(Finite State Machine,F(xiàn)SM)或米利狀態(tài)機(jī)(Mealy Machine),是一種描述系統(tǒng)狀態(tài)變化的模型。在芯片設(shè)計(jì)中,
    的頭像 發(fā)表于 10-19 10:27 ?9552次閱讀

    如何在FPGA中實(shí)現(xiàn)狀態(tài)機(jī)

    在FPGA(現(xiàn)場(chǎng)可編程門(mén)陣列)中實(shí)現(xiàn)狀態(tài)機(jī)是一種常見(jiàn)的做法,用于控制復(fù)雜的數(shù)字系統(tǒng)行為。狀態(tài)機(jī)能夠根據(jù)當(dāng)前的輸入和系統(tǒng)狀態(tài),決定下一步的動(dòng)作和新的狀態(tài)。這里,我們將詳細(xì)探討如何在FPG
    的頭像 發(fā)表于 07-18 15:57 ?601次閱讀
    主站蜘蛛池模板: www.亚洲天堂| 国内久久精品| 很黄网站| 天天色天天射综合网| 久久国产视频一区| 欧美黑人换爱交换乱理伦片| 视频一区二区在线播放| 日本高清视频色www在线观看| 热久热| 日韩一级特黄毛片在线看| 1000部啪啪未满十八勿入| 日本日本69xxxx| 四虎4hu永久在线观看| 97人人模人人揉人人捏| 91啦中文在线观看| 日本一区二区三区四区不卡 | 亚洲欧美日韩色图| 久久成人国产| www干| 色婷婷综合缴情综六月| 午夜视频福利在线观看| 日日操夜夜爽| 高h污快穿文汁水四溅| 黄色激情小说视频| 高清一级片| 综合精品| 欧美色图色就是色| 伊人网视频在线| 日本在线亚洲| 狠狠五月深爱婷婷网免费| 18性夜影院午夜寂寞影院免费| 特黄一级黄色片| 天天射天天做| 91福利视频网站| ww欧美| 92香蕉视频| 日韩1页| 久久精品国产亚洲片| 婷婷激情综合| 三级黄色免费网站| 香蕉爱爱视频|