0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心
发布

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式框架Zorb Framework状态机的实现

玩转嵌入式 来源:github.com 2023-11-29 09:33 次阅读

Zorb Framework是一个基于面向对象的思想来搭建一个轻量级的嵌入式框架。

本次分享的是Zorb Framework的状态机的实现。

中小型嵌入式程序说白了就是由各种状态机组成,因此掌握了如何构建状态机,开发嵌入式应用程序可以说是手到拈来。

简单的状态机可以用Switch-Case实现,但复杂一点的状态机再继续使用Switch-Case的话,层次会变得比较乱,不方便维护。因此我们为Zorb Framework提供了函数式状态机。

状态机的功能

我们先来看看要实现的状态机提供什么功能:

初步要提供的功能如下:

1、可以设置初始状态

2、可以进行状态转换

3、可以进行信号调度

4、最好可以在进入和离开状态的时候可以做一些自定义的事情

5、最好可以有子状态机

因此,初步设计的数据结构如下:

/*状态机结构*/ struct_Fsm { uint8_tLevel;/*嵌套层数,根状态机层数为1,子状态机层数自增*/ /*注:严禁递归嵌套和环形嵌套*/ List*ChildList;/*子状态机列表*/ Fsm*Owner;/*父状态机*/ IFsmStateOwnerTriggerState;/*当父状态机为设定状态时,才触发当前状态机*/ /*若不设定,则当执行完父状态机,立即运行子状态机*/ IFsmStateCurrentState;/*当前状态*/ boolIsRunning;/*是否正在运行(默认关)*/ /*设置初始状态*/ void(*SetInitialState)(Fsm*constpFsm,IFsmStateinitialState); /*运行当前状态机*/ bool(*Run)(Fsm*constpFsm); /*运行当前状态机和子状态机*/ bool(*RunAll)(Fsm*constpFsm); /*停止当前状态机*/ bool(*Stop)(Fsm*constpFsm); /*停止当前状态机和子状态机*/ bool(*StopAll)(Fsm*constpFsm); /*释放当前状态机*/ bool(*Dispose)(Fsm*constpFsm); /*释放当前状态机和子状态机*/ bool(*DisposeAll)(Fsm*constpFsm); /*添加子状态机*/ bool(*AddChild)(Fsm*constpFsm,Fsm*constpChildFsm); /*移除子状态机(不释放空间)*/ bool(*RemoveChild)(Fsm*constpFsm,Fsm*constpChildFsm); /*调度状态机*/ bool(*Dispatch)(Fsm*constpFsm,FsmSignalconstsignal); /*状态转移*/ void(*Transfer)(Fsm*constpFsm,IFsmStatenextState); /*状态转移(触发转出和转入事件)*/ void(*TransferWithEvent)(Fsm*constpFsm,IFsmStatenextState); };

关于信号,Zorb Framework做了以下定义:

/*状态机信号0-31保留,用户信号在32以后定义*/ enum{ FSM_NULL_SIG=0, FSM_ENTER_SIG, FSM_EXIT_SIG, FSM_USER_SIG_START=32 /*用户信号请在用户文件定义,不允许在此定义*/ };

创建状态机:

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

调度状态机:

/****************************************************************************** *描述:调度状态机 *参数:(in)-pFsm 状态机指针 *(in)-signal调度信号 *返回:-true 成功 *-false失败 ******************************************************************************/ boolFsm_dispatch(Fsm*constpFsm,FsmSignalconstsignal) { /*返回结果*/ 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;i< pFsm->ChildList->Count;i++) { pChildFsm=(Fsm*)pFsm->ChildList ->GetElementDataAt(pFsm->ChildList,i); if(pChildFsm!=NULL) { Fsm_dispatch(pChildFsm,signal); } } } if(pFsm->CurrentState!=NULL) { /*1:根状态机时调度 2:没设置触发状态时调度 3:正在触发状态时调度 */ if(pFsm->Owner==NULL||pFsm->OwnerTriggerState==NULL ||pFsm->OwnerTriggerState==pFsm->Owner->CurrentState) { pFsm->CurrentState(pFsm,signal); res=true; } } } returnres; }

篇幅有限,其它接口实现可阅读:

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

状态机测试

/** ***************************************************************************** *@fileapp_fsm.c *@authorZorb *@versionV1.0.0 *@date2018-06-28 *@brief状态机测试的实现 ***************************************************************************** *@history * *1.Date:2018-06-28 *Author:Zorb *Modification:建立文件 * ***************************************************************************** */ #include"app_fsm.h" #include"zf_includes.h" /*定义用户信号*/ enumSignal { SAY_HELLO=FSM_USER_SIG_START }; Fsm*pFsm;/*父状态机*/ Fsm*pFsmSon;/*子状态机*/ /*父状态机状态1*/ staticvoidState1(Fsm*constpFsm,FsmSignalconstfsmSignal); /*父状态机状态2*/ staticvoidState2(Fsm*constpFsm,FsmSignalconstfsmSignal); /****************************************************************************** *描述:父状态机状态1 *参数:-pFsm 当前状态机 *-fsmSignal当前调度信号 *返回:无 ******************************************************************************/ 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 "); /*切换到状态2*/ pFsm->TransferWithEvent(pFsm,State2); break; } } /****************************************************************************** *描述:父状态机状态2 *参数:-pFsm 当前状态机 *-fsmSignal当前调度信号 *返回:无 ******************************************************************************/ 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 "); /*切换到状态1*/ pFsm->TransferWithEvent(pFsm,State1); break; } } /****************************************************************************** *描述:子状态机状态 *参数:-pFsm 当前状态机 *-fsmSignal当前调度信号 *返回:无 ******************************************************************************/ staticvoidSonState(Fsm*constpFsm,FsmSignalconstfsmSignal) { switch(fsmSignal) { caseSAY_HELLO: ZF_DEBUG(LOG_D,"sonsayhelloonlyinstate2 "); break; } } /****************************************************************************** *描述:任务初始化 *参数:无 *返回:无 ******************************************************************************/ voidApp_Fsm_init(void) { /*创建父状态机,并设初始状态*/ Fsm_create(&pFsm); pFsm->SetInitialState(pFsm,State1); /*创建子状态机,并设初始状态*/ Fsm_create(&pFsmSon); pFsmSon->SetInitialState(pFsmSon,SonState); /*设置子状态机仅在父状态State2触发*/ pFsmSon->OwnerTriggerState=State2; /*把子状态机添加到父状态机*/ pFsm->AddChild(pFsm,pFsmSon); /*运行状态机*/ pFsm->RunAll(pFsm); } /****************************************************************************** *描述:任务程序 *参数:无 *返回:无 ******************************************************************************/ voidApp_Fsm_process(void) { ZF_DELAY_MS(1000); /*每1000ms调度状态机,发送SAY_HELLO信号*/ pFsm->Dispatch(pFsm,SAY_HELLO); } /********************************ENDOFFILE********************************/

结果:

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

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6017

    文章

    44269

    浏览量

    626901
  • 嵌入式
    +关注

    关注

    5031

    文章

    18685

    浏览量

    296390
  • Switch
    +关注

    关注

    1

    文章

    532

    浏览量

    57849
  • 状态机
    +关注

    关注

    2

    文章

    489

    浏览量

    27339

原文标题:单片机最好用的程序框架,莫过于状态机了

文章出处:【微信号:玩转嵌入式,微信公众号:玩转嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式状态机的几种大牛才懂的操作

    状态机嵌入式软件中随处可见,可能你会说 状态机有什么难的,不就是 switch 吗? switch仅仅是最基础的一个点,关于 状态机的更多操作,或许你都没有见过,下面分享几种
    发表于11-17 10:41 1323次阅读
    <b class='flag-5'>嵌入式</b><b class='flag-5'>状态机</b>的几种大牛才懂的操作

    嵌入式软件开发中常用的状态机编程实现

    嵌入式软件开发中, 状态机编程是一个十分重要的编程思想,它也是 嵌入式开发中一个常用的编程 框架。掌握了 状态机编程思想,可以更加逻辑清晰的
    发表于09-06 10:25 1673次阅读

    嵌入式框架ZorbFramework搭建方案

    Zorb Framework是一个基于面向对象的思想来搭建一个轻量级的 嵌入式 框架
    的头像 发表于11-05 17:08 1276次阅读
    <b class='flag-5'>嵌入式</b><b class='flag-5'>框架</b><b class='flag-5'>Zorb</b> <b class='flag-5'>Framework</b>搭建方案

    嵌入式状态机编程的概念是什么

    干货 | 嵌入式状态机编程干货篇文章描述了基本的 状态机编程概念,感觉还可以。如果在搭上事件驱动 框架,就可以写一个简单的RTOS了,这个OS可以作为一种不可剥夺型内核。...
    发表于12-22 06:25

    状态机嵌入式系统中的应用

    为了便于研究和描述 状态机嵌入式前后台软件系统中的应用,本文将以移动2G光纤直放站近端 的监控软件案例来阐述和说明。
    发表于05-23 10:48 2071次阅读
    <b class='flag-5'>状态机</b>在<b class='flag-5'>嵌入式</b>系统中的应用

    嵌入式软件中状态机的抽象与实现

    文中提出了 在 嵌入式软件中把 状态机作为一个独立模块从控制模块中抽象出来的思想 , 描述了 抽象出来的 状态机模块 。 并介绍了 如何将这种 状态机抽象模块应用到实际项目中 。
    发表于03-22 15:47 1次下载

    有限状态机嵌入式系统中的实现及应用

    如何使 嵌入式软件代码更加可靠 增强程序的可维护性 一直以来都是 嵌入式程序员追 求的目标。论述了有限 状态机的原理和其 实现方法;采用 状态机方法编
    发表于03-22 15:40 1次下载

    有限状态机嵌入式软件中的应用

    有限 状态机嵌入式软件中的应用,感兴趣的小伙伴们可以看看。
    发表于07-26 10:43 27次下载

    嵌入式应用框架EAF详解

    EAF是Embedded Application Framework的缩写,即 嵌入式应用 框架嵌入式应用 框架是 Application
    发表于12-02 11:30 2667次阅读

    关于嵌入式应用框架(EAF)的分析

    EAF是Embedded Application Framework的缩写,即 嵌入式应用 框架嵌入式应用 框架是 Application
    发表于01-01 09:50 1360次阅读

    嵌入式状态机的设置

    状态机嵌入式软件中随处可见,可能你会说 状态机有什么难的,不就是 switch 吗?
    的头像 发表于11-02 09:04 974次阅读

    嵌入式状态机的编程优点分析

    嵌入式状态机编程是真的好用,写出来的程序结构非常清晰!所以平时用的也比较多。
    的头像 发表于02-25 16:21 735次阅读

    嵌入式状态机的设计与实现

    嵌入式 状态机是一种常用的软件设计模式,它能够提高代码的可读性和可维护性。 状态机是一个抽象的概念,它描述了一个系统或者组件的不同 状态以及在不同 状态
    的头像 发表于04-14 11:55 1441次阅读

    C语言实现嵌入式状态机简单描述与应用

    嵌入式 状态机是一种常用的软件设计模式,它能够提高代码的可读性和可维护性。
    发表于05-20 14:52 1491次阅读

    如何生成状态机框架

    生成 状态机 框架使用FSME不仅能够进行可视化的 状态机建模,更重要的是它还可以根据得到的模型自动生成用C++或者Python 实现状态机
    的头像 发表于09-13 16:54 792次阅读
    如何生成<b class='flag-5'>状态机</b><b class='flag-5'>框架</b>