我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮。

嵌入式框架Zorb Framework搭建过程

嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调试输出和建立时间系统

嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

嵌入式框架Zorb Framework搭建三:列表的实现

嵌入式框架Zorb Framework搭建四:状态机的实现

嵌入式框架Zorb Framework搭建五:事件的实现

嵌入式框架Zorb Framework搭建六:定时器的实现

嵌入式框架Zorb Framework搭建七:任务的实现

一、前言

  在这一篇中,我们将为Zorb Framework提供状态机功能。中小型嵌入式程序说白了就是由各种状态机组成,因此掌握了如何构建状态机,开发嵌入式应用程序可以说是手到拈来。简单的状态机可以用Switch-Case实现,但复杂一点的状态机再继续使用Switch-Case的话,层次会变得比较乱,不方便维护。因此我们为Zorb Framework提供了函数式状态机。

二、状态机设计

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

  初步要提供的功能如下:

  1、可以设置初始状态

  2、可以进行状态转换

  3、可以进行信号调度

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

  5、最好可以有子状态机

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

 /* 状态机结构 */
struct _Fsm
{
uint8_t Level; /* 嵌套层数,根状态机层数为1,子状态机层数自增 */
/* 注:严禁递归嵌套和环形嵌套 */
List *ChildList; /* 子状态机列表 */
Fsm *Owner; /* 父状态机 */
IFsmState OwnerTriggerState; /* 当父状态机为设定状态时,才触发当前状态机 */
/* 若不设定,则当执行完父状态机,立即运行子状态机 */
IFsmState CurrentState; /* 当前状态 */
bool IsRunning; /* 是否正在运行(默认关) */ /* 设置初始状态 */
void (*SetInitialState)(Fsm * const pFsm, IFsmState initialState); /* 运行当前状态机 */
bool (*Run)(Fsm * const pFsm); /* 运行当前状态机和子状态机 */
bool (*RunAll)(Fsm * const pFsm); /* 停止当前状态机 */
bool (*Stop)(Fsm * const pFsm); /* 停止当前状态机和子状态机 */
bool (*StopAll)(Fsm * const pFsm); /* 释放当前状态机 */
bool (*Dispose)(Fsm * const pFsm); /* 释放当前状态机和子状态机 */
bool (*DisposeAll)(Fsm * const pFsm); /* 添加子状态机 */
bool (*AddChild)(Fsm * const pFsm, Fsm * const pChildFsm); /* 移除子状态机(不释放空间) */
bool (*RemoveChild)(Fsm * const pFsm, Fsm * const pChildFsm); /* 调度状态机 */
bool (*Dispatch)(Fsm * const pFsm, FsmSignal const signal); /* 状态转移 */
void (*Transfer)(Fsm * const pFsm, IFsmState nextState); /* 状态转移(触发转出和转入事件) */
void (*TransferWithEvent)(Fsm * const pFsm, IFsmState nextState);
};

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

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

  其中,0-31为框架信号,用户信号在32之后定义。

  状态机已经设计好了,具体实现请看附件代码或在文末的github地址拉框架源码。

三、状态机结果测试

  简单的测试代码如下:

 /**
*****************************************************************************
* @file app_fsm.c
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief 状态机测试的实现
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:建立文件
*
*****************************************************************************
*/ #include "app_fsm.h"
#include "zf_includes.h" /* 定义用户信号 */
enum Signal
{
SAY_HELLO = FSM_USER_SIG_START
}; Fsm *pFsm; /* 父状态机 */
Fsm *pFsmSon; /* 子状态机 */ /* 父状态机状态1 */
static void State1(Fsm * const pFsm, FsmSignal const fsmSignal);
/* 父状态机状态2 */
static void State2(Fsm * const pFsm, FsmSignal const fsmSignal); /******************************************************************************
* 描述 :父状态机状态1
* 参数 :-pFsm 当前状态机
* -fsmSignal 当前调度信号
* 返回 :无
******************************************************************************/
static void State1(Fsm * const pFsm, FsmSignal const fsmSignal)
{
switch(fsmSignal)
{
case FSM_ENTER_SIG:
ZF_DEBUG(LOG_D, "enter state1\r\n");
break; case FSM_EXIT_SIG:
ZF_DEBUG(LOG_D, "exit state1\r\n\r\n");
break; case SAY_HELLO:
ZF_DEBUG(LOG_D, "state1 say hello, and want to be state2\r\n");
/* 切换到状态2 */
pFsm->TransferWithEvent(pFsm, State2);
break;
}
} /******************************************************************************
* 描述 :父状态机状态2
* 参数 :-pFsm 当前状态机
* -fsmSignal 当前调度信号
* 返回 :无
******************************************************************************/
static void State2(Fsm * const pFsm, FsmSignal const fsmSignal)
{
switch(fsmSignal)
{
case FSM_ENTER_SIG:
ZF_DEBUG(LOG_D, "enter state2\r\n");
break; case FSM_EXIT_SIG:
ZF_DEBUG(LOG_D, "exit state2\r\n\r\n");
break; case SAY_HELLO:
ZF_DEBUG(LOG_D, "state2 say hello, and want to be state1\r\n");
/* 切换到状态1 */
pFsm->TransferWithEvent(pFsm, State1);
break;
}
} /******************************************************************************
* 描述 :子状态机状态
* 参数 :-pFsm 当前状态机
* -fsmSignal 当前调度信号
* 返回 :无
******************************************************************************/
static void SonState(Fsm * const pFsm, FsmSignal const fsmSignal)
{
switch(fsmSignal)
{
case SAY_HELLO:
ZF_DEBUG(LOG_D, "son say hello only in state2\r\n");
break;
}
} /******************************************************************************
* 描述 :任务初始化
* 参数 :无
* 返回 :无
******************************************************************************/
void App_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);
} /******************************************************************************
* 描述 :任务程序
* 参数 :无
* 返回 :无
******************************************************************************/
void App_Fsm_process(void)
{
ZF_DELAY_MS();
/* 每1000ms调度状态机,发送SAY_HELLO信号 */
pFsm->Dispatch(pFsm, SAY_HELLO);
} /******************************** END OF FILE ********************************/

  结果:

state1 say hello, and want to be state2
exit state1 enter state2
son say hello only in state2
state2 say hello, and want to be state1
exit state2 enter state1
state1 say hello, and want to be state2
exit state1 enter state2
son say hello only in state2
state2 say hello, and want to be state1
exit state2 enter state1
state1 say hello, and want to be state2
exit state1 省略...

四、最后

  本篇为Zorb Framework提供了状态机功能,复杂的状态转换关系被分解成了一个个状态函数,然后在状态函数中仅仅需要处理本状态出现的情况,忽然感觉世界变得简单很多。后面再配上即将为框架添加的事件功能,会让状态机的功能发挥到极致。

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

  版权所有,转载请打赏哟

如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

嵌入式框架Zorb Framework搭建四:状态机的实现的更多相关文章

  1. 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调试输出和建立时间系统

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  2. 嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  3. 嵌入式框架Zorb Framework搭建三:列表的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  4. 嵌入式框架Zorb Framework搭建五:事件的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  5. 嵌入式框架Zorb Framework搭建六:定时器的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  6. 嵌入式框架Zorb Framework搭建七:任务的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  7. 实体框架(Entity Framework)快速入门--实例篇

    在上一篇 <实体框架(Entity Framework)快速入门> 中我们简单了解的EF的定义和大体的情况,我们通过一步一步的做一个简单的实际例子来让大家对EF使用有个简单印象,看操作步骤 ...

  8. iOS9全新的联系人相关框架——Contacts Framework

    iOS9全新的联系人相关框架——Contacts Framework 一.引言 在以前iOS开发中,涉及联系人相关的编程,代码都非常繁琐,并且框架的设计也不是Objective-C风格的,这使开发者用 ...

  9. 模糊系统架构和简单实现--AForge.NET框架的使用(四)

    原文:模糊系统架构和简单实现--AForge.NET框架的使用(四) 先说一下,为什么题目是简单实现,因为我实在没有弄出好的例子. 我原来用AForge.net做的项目中的模糊系统融入了神经网络和向量 ...

随机推荐

  1. checkpoint(sqlserver数据库检查点)

    关于检查点的解释:   出于性能方面的考虑,数据库引擎对内存(缓冲区缓存)中的数据库页进行修改,但在每次更改后不将这些页写入磁盘.相反,数据库引擎定期发出对每个数据库的检查点命令.“检查点”将当前内存 ...

  2. 7 - py面向对象一条龙服务

    Python从设计之初就已经是一门面向对象的语言,在python里所有东西皆是对象. 下面通过一个实例来说明什么是面向对象. 引子 你是一家公司的员工,公司现在要开发一款“人狗战争”的游戏,人狗战争肯 ...

  3. Django:Django的路由系统

    一,URLconf配置 1,基本格式 from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图函数,参数,别名), ] 2 ...

  4. NodeJS学习日记--环境配置及项目初始化

    在node.js官网下载nodejs安装包 安装完成后打开控制台,输入 npm -version 如果正确显示npm版本则安装成功. 创建项目之前先要安装以下全局扩展模块 npm install -g ...

  5. 【洛谷T37388】P哥破解密码

    原题图: 看到这个题,首先想到的当然是暴力打表找规律了 表: 1 2 2 4 3 7 4 13 5 24 6 44 7 81 8 149 9 274 10 504 11 927 12 1705 13 ...

  6. 【luogu P3378 堆】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3378 是堆的模板...我懒,STL da fa is good #include <iostream& ...

  7. HDU 1099 Lottery (求数学期望)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1099 Lottery Time Limit: 2000/1000 MS (Java/Others)   ...

  8. Spring知识点总结(三)之Spring DI

    1. IOC(DI) - 控制反转(依赖注入) 所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和 ...

  9. 解决问题的思路(如故事版里面有东西,却不见了)(swift里面开发比较多)

    解决问题的思路(如故事版里面有东西,却不见了) 正确效果图: 真机效果图: 内容:不见了 解决步骤:(重点讲解方法1) 1.把背景图隐藏了,如果能出现内容,说明背景图把内容遮住了.那怎么办呢,背景图是 ...

  10. CPU运行的流程