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

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

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

嵌入式框架Zorb Framework狀態(tài)機(jī)的實(shí)現(xiàn)

玩轉(zhuǎn)嵌入式 ? 來(lái)源:github.com ? 2023-11-29 09:33 ? 次閱讀

Zorb Framework是一個(gè)基于面向?qū)ο蟮乃枷雭?lái)搭建一個(gè)輕量級(jí)的嵌入式框架。

本次分享的是Zorb Framework的狀態(tài)機(jī)的實(shí)現(xiàn)。

中小型嵌入式程序說(shuō)白了就是由各種狀態(tài)機(jī)組成,因此掌握了如何構(gòu)建狀態(tài)機(jī),開發(fā)嵌入式應(yīng)用程序可以說(shuō)是手到拈來(lái)。

簡(jiǎn)單的狀態(tài)機(jī)可以用Switch-Case實(shí)現(xiàn),但復(fù)雜一點(diǎn)的狀態(tài)機(jī)再繼續(xù)使用Switch-Case的話,層次會(huì)變得比較亂,不方便維護(hù)。因此我們?yōu)閆orb Framework提供了函數(shù)式狀態(tài)機(jī)。

狀態(tài)機(jī)的功能

我們先來(lái)看看要實(shí)現(xiàn)的狀態(tài)機(jī)提供什么功能:

初步要提供的功能如下:

1、可以設(shè)置初始狀態(tài)

2、可以進(jìn)行狀態(tài)轉(zhuǎn)換

3、可以進(jìn)行信號(hào)調(diào)度

4、最好可以在進(jìn)入和離開狀態(tài)的時(shí)候可以做一些自定義的事情

5、最好可以有子狀態(tài)機(jī)

因此,初步設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)如下:

/*狀態(tài)機(jī)結(jié)構(gòu)*/
struct_Fsm
{
uint8_tLevel;/*嵌套層數(shù),根狀態(tài)機(jī)層數(shù)為1,子狀態(tài)機(jī)層數(shù)自增*/
/*注:嚴(yán)禁遞歸嵌套和環(huán)形嵌套*/
List*ChildList;/*子狀態(tài)機(jī)列表*/
Fsm*Owner;/*父狀態(tài)機(jī)*/
IFsmStateOwnerTriggerState;/*當(dāng)父狀態(tài)機(jī)為設(shè)定狀態(tài)時(shí),才觸發(fā)當(dāng)前狀態(tài)機(jī)*/
/*若不設(shè)定,則當(dāng)執(zhí)行完父狀態(tài)機(jī),立即運(yùn)行子狀態(tài)機(jī)*/
IFsmStateCurrentState;/*當(dāng)前狀態(tài)*/
boolIsRunning;/*是否正在運(yùn)行(默認(rèn)關(guān))*/

/*設(shè)置初始狀態(tài)*/
void(*SetInitialState)(Fsm*constpFsm,IFsmStateinitialState);

/*運(yùn)行當(dāng)前狀態(tài)機(jī)*/
bool(*Run)(Fsm*constpFsm);

/*運(yùn)行當(dāng)前狀態(tài)機(jī)和子狀態(tài)機(jī)*/
bool(*RunAll)(Fsm*constpFsm);

/*停止當(dāng)前狀態(tài)機(jī)*/
bool(*Stop)(Fsm*constpFsm);

/*停止當(dāng)前狀態(tài)機(jī)和子狀態(tài)機(jī)*/
bool(*StopAll)(Fsm*constpFsm);

/*釋放當(dāng)前狀態(tài)機(jī)*/
bool(*Dispose)(Fsm*constpFsm);

/*釋放當(dāng)前狀態(tài)機(jī)和子狀態(tài)機(jī)*/
bool(*DisposeAll)(Fsm*constpFsm);

/*添加子狀態(tài)機(jī)*/
bool(*AddChild)(Fsm*constpFsm,Fsm*constpChildFsm);

/*移除子狀態(tài)機(jī)(不釋放空間)*/
bool(*RemoveChild)(Fsm*constpFsm,Fsm*constpChildFsm);

/*調(diào)度狀態(tài)機(jī)*/
bool(*Dispatch)(Fsm*constpFsm,FsmSignalconstsignal);

/*狀態(tài)轉(zhuǎn)移*/
void(*Transfer)(Fsm*constpFsm,IFsmStatenextState);

/*狀態(tài)轉(zhuǎn)移(觸發(fā)轉(zhuǎn)出和轉(zhuǎn)入事件)*/
void(*TransferWithEvent)(Fsm*constpFsm,IFsmStatenextState);
};

關(guān)于信號(hào),Zorb Framework做了以下定義:

/*狀態(tài)機(jī)信號(hào)0-31保留,用戶信號(hào)在32以后定義*/
enum{
FSM_NULL_SIG=0,
FSM_ENTER_SIG,
FSM_EXIT_SIG,
FSM_USER_SIG_START=32
/*用戶信號(hào)請(qǐng)?jiān)谟脩粑募x,不允許在此定義*/
};

創(chuàng)建狀態(tài)機(jī):

boolFsm_create(Fsm**ppFsm)
{
Fsm*pFsm;

ZF_ASSERT(ppFsm!=(Fsm**)0)

/*分配空間*/
pFsm=ZF_MALLOC(sizeof(Fsm));
if(pFsm==NULL)
{
ZF_DEBUG(LOG_E,"mallocfsmspaceerror
");
returnfalse;
}

/*初始化成員*/
pFsm->Level=1;
pFsm->ChildList=NULL;
pFsm->Owner=NULL;
pFsm->OwnerTriggerState=NULL;
pFsm->CurrentState=NULL;
pFsm->IsRunning=false;

/*初始化方法*/
pFsm->SetInitialState=Fsm_setInitialState;
pFsm->Run=Fsm_run;
pFsm->RunAll=Fsm_runAll;
pFsm->Stop=Fsm_stop;
pFsm->StopAll=Fsm_stopAll;
pFsm->Dispose=Fsm_dispose;
pFsm->DisposeAll=Fsm_disposeAll;
pFsm->AddChild=Fsm_addChild;
pFsm->RemoveChild=Fsm_removeChild;
pFsm->Dispatch=Fsm_dispatch;
pFsm->Transfer=Fsm_transfer;
pFsm->TransferWithEvent=Fsm_transferWithEvent;

/*輸出*/
*ppFsm=pFsm;

returntrue;
}

調(diào)度狀態(tài)機(jī):

/******************************************************************************
*描述:調(diào)度狀態(tài)機(jī)
*參數(shù):(in)-pFsm 狀態(tài)機(jī)指針
*(in)-signal調(diào)度信號(hào)
*返回:-true 成功
*-false失敗
******************************************************************************/
boolFsm_dispatch(Fsm*constpFsm,FsmSignalconstsignal)
{
/*返回結(jié)果*/
boolres=false;

ZF_ASSERT(pFsm!=(Fsm*)0)

if(pFsm->IsRunning)
{
if(pFsm->ChildList!=NULL&&pFsm->ChildList->Count>0)
{
uint32_ti;
Fsm*pChildFsm;

for(i=0;iChildList->Count;i++)
{
pChildFsm=(Fsm*)pFsm->ChildList
->GetElementDataAt(pFsm->ChildList,i);

if(pChildFsm!=NULL)
{
Fsm_dispatch(pChildFsm,signal);
}
}
}

if(pFsm->CurrentState!=NULL)
{
/*1:根狀態(tài)機(jī)時(shí)調(diào)度
2:沒設(shè)置觸發(fā)狀態(tài)時(shí)調(diào)度
3:正在觸發(fā)狀態(tài)時(shí)調(diào)度
*/
if(pFsm->Owner==NULL||pFsm->OwnerTriggerState==NULL
||pFsm->OwnerTriggerState==pFsm->Owner->CurrentState)
{
pFsm->CurrentState(pFsm,signal);

res=true;
}
}
}

returnres;
}

篇幅有限,其它接口實(shí)現(xiàn)可閱讀:

https://github.com/54zorb/Zorb-Framework

狀態(tài)機(jī)測(cè)試

/**
*****************************************************************************
*@fileapp_fsm.c
*@authorZorb
*@versionV1.0.0
*@date2018-06-28
*@brief狀態(tài)機(jī)測(cè)試的實(shí)現(xiàn)
*****************************************************************************
*@history
*
*1.Date:2018-06-28
*Author:Zorb
*Modification:建立文件
*
*****************************************************************************
*/

#include"app_fsm.h"
#include"zf_includes.h"

/*定義用戶信號(hào)*/
enumSignal
{
SAY_HELLO=FSM_USER_SIG_START
};

Fsm*pFsm;/*父狀態(tài)機(jī)*/
Fsm*pFsmSon;/*子狀態(tài)機(jī)*/

/*父狀態(tài)機(jī)狀態(tài)1*/
staticvoidState1(Fsm*constpFsm,FsmSignalconstfsmSignal);
/*父狀態(tài)機(jī)狀態(tài)2*/
staticvoidState2(Fsm*constpFsm,FsmSignalconstfsmSignal);

/******************************************************************************
*描述:父狀態(tài)機(jī)狀態(tài)1
*參數(shù):-pFsm 當(dāng)前狀態(tài)機(jī)
*-fsmSignal當(dāng)前調(diào)度信號(hào)
*返回:無(wú)
******************************************************************************/
staticvoidState1(Fsm*constpFsm,FsmSignalconstfsmSignal)
{
switch(fsmSignal)
{
caseFSM_ENTER_SIG:
ZF_DEBUG(LOG_D,"enterstate1
");
break;

caseFSM_EXIT_SIG:
ZF_DEBUG(LOG_D,"exitstate1

");
break;

caseSAY_HELLO:
ZF_DEBUG(LOG_D,"state1sayhello,andwanttobestate2
");
/*切換到狀態(tài)2*/
pFsm->TransferWithEvent(pFsm,State2);
break;
}
}

/******************************************************************************
*描述:父狀態(tài)機(jī)狀態(tài)2
*參數(shù):-pFsm 當(dāng)前狀態(tài)機(jī)
*-fsmSignal當(dāng)前調(diào)度信號(hào)
*返回:無(wú)
******************************************************************************/
staticvoidState2(Fsm*constpFsm,FsmSignalconstfsmSignal)
{
switch(fsmSignal)
{
caseFSM_ENTER_SIG:
ZF_DEBUG(LOG_D,"enterstate2
");
break;

caseFSM_EXIT_SIG:
ZF_DEBUG(LOG_D,"exitstate2

");
break;

caseSAY_HELLO:
ZF_DEBUG(LOG_D,"state2sayhello,andwanttobestate1
");
/*切換到狀態(tài)1*/
pFsm->TransferWithEvent(pFsm,State1);
break;
}
}

/******************************************************************************
*描述:子狀態(tài)機(jī)狀態(tài)
*參數(shù):-pFsm 當(dāng)前狀態(tài)機(jī)
*-fsmSignal當(dāng)前調(diào)度信號(hào)
*返回:無(wú)
******************************************************************************/
staticvoidSonState(Fsm*constpFsm,FsmSignalconstfsmSignal)
{
switch(fsmSignal)
{
caseSAY_HELLO:
ZF_DEBUG(LOG_D,"sonsayhelloonlyinstate2
");
break;
}
}

/******************************************************************************
*描述:任務(wù)初始化
*參數(shù):無(wú)
*返回:無(wú)
******************************************************************************/
voidApp_Fsm_init(void)
{
/*創(chuàng)建父狀態(tài)機(jī),并設(shè)初始狀態(tài)*/
Fsm_create(&pFsm);
pFsm->SetInitialState(pFsm,State1);

/*創(chuàng)建子狀態(tài)機(jī),并設(shè)初始狀態(tài)*/
Fsm_create(&pFsmSon);
pFsmSon->SetInitialState(pFsmSon,SonState);

/*設(shè)置子狀態(tài)機(jī)僅在父狀態(tài)State2觸發(fā)*/
pFsmSon->OwnerTriggerState=State2;

/*把子狀態(tài)機(jī)添加到父狀態(tài)機(jī)*/
pFsm->AddChild(pFsm,pFsmSon);

/*運(yùn)行狀態(tài)機(jī)*/
pFsm->RunAll(pFsm);
}

/******************************************************************************
*描述:任務(wù)程序
*參數(shù):無(wú)
*返回:無(wú)
******************************************************************************/
voidApp_Fsm_process(void)
{
ZF_DELAY_MS(1000);
/*每1000ms調(diào)度狀態(tài)機(jī),發(fā)送SAY_HELLO信號(hào)*/
pFsm->Dispatch(pFsm,SAY_HELLO);
}

/********************************ENDOFFILE********************************/

結(jié)果:

6f904bd2-8e45-11ee-939d-92fbcf53809c.png

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(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)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6037

    文章

    44558

    瀏覽量

    635214
  • 嵌入式
    +關(guān)注

    關(guān)注

    5082

    文章

    19123

    瀏覽量

    305147
  • Switch
    +關(guān)注

    關(guān)注

    1

    文章

    533

    瀏覽量

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

    關(guān)注

    2

    文章

    492

    瀏覽量

    27539

原文標(biāo)題:?jiǎn)纹瑱C(jī)最好用的程序框架,莫過(guò)于狀態(tài)機(jī)了

文章出處:【微信號(hào):玩轉(zhuǎn)嵌入式,微信公眾號(hào):玩轉(zhuǎn)嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    嵌入式狀態(tài)機(jī)的幾種大牛才懂的操作

    狀態(tài)機(jī)嵌入式軟件中隨處可見,可能你會(huì)說(shuō)狀態(tài)機(jī)有什么難的,不就是 switch 嗎? switch僅僅是最基礎(chǔ)的一個(gè)點(diǎn),關(guān)于狀態(tài)機(jī)的更多操作,或許你都沒有見過(guò),下面分享幾種
    發(fā)表于 11-17 10:41 ?1484次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>狀態(tài)機(jī)</b>的幾種大牛才懂的操作

    嵌入式軟件開發(fā)中常用的狀態(tài)機(jī)編程實(shí)現(xiàn)

    嵌入式軟件開發(fā)中,狀態(tài)機(jī)編程是一個(gè)十分重要的編程思想,它也是嵌入式開發(fā)中一個(gè)常用的編程框架。掌握了狀態(tài)機(jī)編程思想,可以更加邏輯清晰的
    發(fā)表于 09-06 10:25 ?2020次閱讀

    嵌入式框架Zorb Framework搭建方案

    Zorb Framework是一個(gè)基于面向?qū)ο蟮乃枷雭?lái)搭建一個(gè)輕量級(jí)的嵌入式框架。
    的頭像 發(fā)表于 11-05 17:08 ?1462次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>框架</b><b class='flag-5'>Zorb</b> <b class='flag-5'>Framework</b>搭建方案

    嵌入式狀態(tài)機(jī)編程的概念是什么

    干貨 | 嵌入式狀態(tài)機(jī)編程干貨篇文章描述了基本的狀態(tài)機(jī)編程概念,感覺還可以。如果在搭上事件驅(qū)動(dòng)框架,就可以寫一個(gè)簡(jiǎn)單的RTOS了,這個(gè)OS可以作為一種不可剝奪型內(nèi)核。...
    發(fā)表于 12-22 06:25

    狀態(tài)機(jī)嵌入式系統(tǒng)中的應(yīng)用

    為了便于研究和描述狀態(tài)機(jī)嵌入式前后臺(tái)軟件系統(tǒng)中的應(yīng)用,本文將以移動(dòng)2G光纖直放站近端機(jī)的監(jiān)控軟件案例來(lái)闡述和說(shuō)明。
    發(fā)表于 05-23 10:48 ?2159次閱讀
    <b class='flag-5'>狀態(tài)機(jī)</b>在<b class='flag-5'>嵌入式</b>系統(tǒng)中的應(yīng)用

    嵌入式軟件中狀態(tài)機(jī)的抽象與實(shí)現(xiàn)

    文中提出了 在嵌入式軟件中把狀態(tài)機(jī)作為一個(gè)獨(dú)立模塊從控制模塊中抽象出來(lái)的思想 , 描述了 抽象出來(lái)的狀態(tài)機(jī)模塊 。 并介紹了 如何將這種狀態(tài)機(jī)抽象模塊應(yīng)用到實(shí)際項(xiàng)目中 。
    發(fā)表于 03-22 15:47 ?1次下載

    有限狀態(tài)機(jī)嵌入式系統(tǒng)中的實(shí)現(xiàn)及應(yīng)用

    如何使嵌入式軟件代碼更加可靠 增強(qiáng)程序的可維護(hù)性 一直以來(lái)都是嵌入式程序員追 求的目標(biāo)。論述了有限狀態(tài)機(jī)的原理和其實(shí)現(xiàn)方法;采用狀態(tài)機(jī)方法編
    發(fā)表于 03-22 15:40 ?1次下載

    有限狀態(tài)機(jī)嵌入式軟件中的應(yīng)用

    有限狀態(tài)機(jī)嵌入式軟件中的應(yīng)用,感興趣的小伙伴們可以看看。
    發(fā)表于 07-26 10:43 ?27次下載

    嵌入式應(yīng)用框架EAF詳解

    EAF是Embedded Application Framework 的縮寫,即嵌入式應(yīng)用框架。嵌入式應(yīng)用框架是 Application
    發(fā)表于 12-02 11:30 ?2848次閱讀

    關(guān)于嵌入式應(yīng)用框架(EAF)的分析

    EAF是Embedded Application Framework 的縮寫,即嵌入式應(yīng)用框架嵌入式應(yīng)用框架是 Application
    發(fā)表于 01-01 09:50 ?1529次閱讀

    嵌入式狀態(tài)機(jī)的設(shè)置

    狀態(tài)機(jī)嵌入式軟件中隨處可見,可能你會(huì)說(shuō)狀態(tài)機(jī)有什么難的,不就是 switch 嗎?
    的頭像 發(fā)表于 11-02 09:04 ?1091次閱讀

    嵌入式狀態(tài)機(jī)的編程優(yōu)點(diǎn)分析

    嵌入式狀態(tài)機(jī)編程是真的好用,寫出來(lái)的程序結(jié)構(gòu)非常清晰!所以平時(shí)用的也比較多。
    的頭像 發(fā)表于 02-25 16:21 ?839次閱讀

    嵌入式狀態(tài)機(jī)的設(shè)計(jì)與實(shí)現(xiàn)

    嵌入式狀態(tài)機(jī)是一種常用的軟件設(shè)計(jì)模式,它能夠提高代碼的可讀性和可維護(hù)性。狀態(tài)機(jī)是一個(gè)抽象的概念,它描述了一個(gè)系統(tǒng)或者組件的不同狀態(tài)以及在不同狀態(tài)
    的頭像 發(fā)表于 04-14 11:55 ?1791次閱讀

    C語(yǔ)言實(shí)現(xiàn)嵌入式狀態(tài)機(jī)簡(jiǎn)單描述與應(yīng)用

    嵌入式狀態(tài)機(jī)是一種常用的軟件設(shè)計(jì)模式,它能夠提高代碼的可讀性和可維護(hù)性。
    發(fā)表于 05-20 14:52 ?1693次閱讀

    如何生成狀態(tài)機(jī)框架

    生成狀態(tài)機(jī)框架 使用FSME不僅能夠進(jìn)行可視化的狀態(tài)機(jī)建模,更重要的是它還可以根據(jù)得到的模型自動(dòng)生成用C++或者Python實(shí)現(xiàn)狀態(tài)機(jī)
    的頭像 發(fā)表于 09-13 16:54 ?990次閱讀
    如何生成<b class='flag-5'>狀態(tài)機(jī)</b><b class='flag-5'>框架</b>