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ī),開(kāi)發(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)入和離開(kāi)狀態(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ù)信號(hào)在32以后定義*/
enum{
FSM_NULL_SIG=0,
FSM_ENTER_SIG,
FSM_EXIT_SIG,
FSM_USER_SIG_START=32
/*用戶(hù)信號(hào)請(qǐng)?jiān)谟脩?hù)文件定義,不允許在此定義*/
};
創(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:沒(méi)設(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ù)信號(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é)果:

-
單片機(jī)
+關(guān)注
關(guān)注
6074文章
45453瀏覽量
667060 -
嵌入式
+關(guān)注
關(guān)注
5192文章
20274瀏覽量
331694 -
Switch
+關(guān)注
關(guān)注
1文章
541瀏覽量
61569 -
狀態(tài)機(jī)
+關(guān)注
關(guān)注
2文章
498瀏覽量
29001
原文標(biāo)題:?jiǎn)纹瑱C(jī)最好用的程序框架,莫過(guò)于狀態(tài)機(jī)了
文章出處:【微信號(hào):玩轉(zhuǎn)嵌入式,微信公眾號(hào):玩轉(zhuǎn)嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
嵌入式狀態(tài)機(jī)的幾種大牛才懂的操作
嵌入式軟件開(kāi)發(fā)中常用的狀態(tài)機(jī)編程實(shí)現(xiàn)
嵌入式之狀態(tài)機(jī)編程的概念是什么
狀態(tài)機(jī)在嵌入式系統(tǒng)中的應(yīng)用
嵌入式軟件中狀態(tài)機(jī)的抽象與實(shí)現(xiàn)
有限狀態(tài)機(jī)在嵌入式系統(tǒng)中的實(shí)現(xiàn)及應(yīng)用
有限狀態(tài)機(jī)在嵌入式軟件中的應(yīng)用
嵌入式應(yīng)用框架EAF詳解
關(guān)于嵌入式應(yīng)用框架(EAF)的分析
嵌入式中狀態(tài)機(jī)的設(shè)置
嵌入式狀態(tài)機(jī)的編程優(yōu)點(diǎn)分析
嵌入式狀態(tài)機(jī)的設(shè)計(jì)與實(shí)現(xiàn)
C語(yǔ)言實(shí)現(xiàn)嵌入式狀態(tài)機(jī)簡(jiǎn)單描述與應(yīng)用
如何生成狀態(tài)機(jī)框架
嵌入式框架Zorb Framework狀態(tài)機(jī)的實(shí)現(xiàn)
評(píng)論