事件驱动型状态机EFSM介绍及C语言实现

2023-11-16

一、什么是状态机?

有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。

有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在计算机科学中,有限状态机被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。
 

二、状态机的老的写法

按照状态机的理解,其写法一般有两种:竖着写和横着写。

2.1 竖着写(在状态中判断事件)

C代码片段:

cur_state = nxt_state;   
switch(cur_state) //在当前状态中判断事件
{            
    case s0: //在s0状态   
        if(e0_event) //如果发生e0事件,那么就执行a0动作,并保持状态不变;
        {   
        //执行a0动作;               
        //nxt_state = s0;  //因为状态号是自身,所以可以删除此句,以提高运行速度。
        } 
        else if(e1_event) //如果发生e1事件,那么就执行a1动作,并将状态转移到s1态;
        {   
            //执行a1动作;
            nxt_state = s1;
        }           
        else if(e2_event) //如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;
        {  
            //执行a2动作;
            nxt_state = s2;
        }
        else
        {
            break;    
        }   

    case s1: //在s1状态
        if(e2_event) //如果发生e2事件,那么就执行a2动作,并将状态转移到s2态; 
        {                
            //执行a2动作;
         nxt_state = s2;
        }           
        else
        {
      break;
        }

    case s2: //在s2状态
        if(e0_event)  //如果发生e0事件,那么就执行a0动作,并将状态转移到s0态;
        {
            //执行a0动作;               
            nxt_state = s0;
        }
}

2.2 横着写(在事件中判断状态)

C代码片段:

//e0事件发生时,执行的函数
void e0_event_function(int * nxt_state)
{   
    int cur_state;   
    cur_state = *nxt_state;   
    switch(cur_state)
    {       
        case s0: //观察表1,在e0事件发生时,s1处为空   
        case s2: //执行a0动作;           
        *nxt_state = s0;
    }
}

//e1事件发生时,执行的函数
void e1_event_function(int * nxt_state)
{   
    int cur_state;   
    cur_state = *nxt_state;   
    switch(cur_state)
    {       
        case s0: //观察表1,在e1事件发生时,s1和s2处为空           
            //执行a1动作;           
            *nxt_state = s1;
    }
}

//e2事件发生时,执行的函数
void e2_event_function(int * nxt_state)
{   
    int cur_state;   
    cur_state = *nxt_state;   
    switch(cur_state)
    {       
        case s0: //观察表1,在e2事件发生时,s2处为空       
        case s1:           
            //执行a2动作;           
            *nxt_state = s2; 
    }
}

上面横竖两种写法的代码片段,实现的功能完全相同,但是,横着写的效果明显好于竖着写的效果。具体原因相信大家都能明白。

三、新型事件驱动型有限状态机实现

一般情况下,大家一想到状态机,核心考虑的都是软件代码的逻辑层面,使用状态机能够将代码的逻辑层次和状态清晰的表现出来,以便于代码的实现。

但实际情况是:状态机不仅仅可以表示代码的逻辑层次和逻辑关系,还能很好的将源代码做到分离和区分,从而实现代码框架的时间与空间的隔离(逻辑与存储的分离),这才是状态机存在的真正价值和实际意义

比如前面两种老的状态机写法,除了switch()的代码可以放在顶层目录下的源码外,各个状态/事件下的代码可以根据状态/事件进行子文件夹命名,然后把相关的代码放在对应的文件夹中。这样就可以很好的根据不同状态进行人员分工,还可以实现并行开发了

但这样,问题又来了:这样虽然把物理代码分离了,但是各个状态/事件下的代码是需要交互的,是有逻辑沟通的

要解决这个问题,就要站在面向对象的角度来思考了:我们把每一个状态看成一个实际的对象,每个对象都会处理一组相同的事件,对于某个状态对象不关心的事件,只需要将对应的处理置位NULL即可

基于这个思想,我实现了一套EFSM(Event Finite State Machine),目前已经基于MIT协议完全开源了。下面是代码地址:

具体实现理论方法是:内部每个状态已事件-处理的key-value对的形式保存为一个hash表,不同的状态对应一个hash表;我们的状态机就是一个指向这个hash表的指针而已,整个状态机机制实现全部由efsm_event.h和efsm.h两个头文件实现!同时,为了简化应用,我还定义了一个运转状态机的线程(efsmt.c/efsmt.h),并且采用面向对象的方法,实现了命名空间的独立!

换句话说,只要你合理安排不同的模块,你可以在一个进程中创建多个状态机,你甚至可以通过EFSM实现层次状态机。

那么,基于EFSM开发模块/项目,我们核心要做的就是定义清楚各个事件,以及真正的状态对象即可

接下来一篇,将详细介绍EFSM的接口和使用方法,详见:

https://blog.csdn.net/a123441/article/details/89841160

有关技术的更多干货和分享,可关注我的个人公众号,内容涵盖单片机、FreeRTOS、Linux驱动、Linux驱动、Linux中间件、产品原型设计、设计模式、软件框架、软件重构、网络设计、数据库、人工智能、深度学习等多方面内容,内容将持续不断更新。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

事件驱动型状态机EFSM介绍及C语言实现 的相关文章

  • Verilog 有限状态机

    状态机基本概念 状态机 xff0c 全称是有限状态机 xff08 Finite State Machine xff0c 缩写为FSM xff09 xff0c 是一种在有限个状态之间按一定规律转换的时序电路 xff0c 可以认为是组合逻辑和时
  • 单片机裸机环境下编写AT指令程序

    1 写在前面 AT指令在各种WIFI模块 2G 4G模块以及一些无线通讯模块中应用广泛 但是用过的朋友都知道 这种方式对于单片机编程来说 并不友好 本篇文章将以ESP8266 WIFI模块为例介绍在单片机裸机环境下编写AT指令程序的一种方式
  • 剑指Offer53Java代码

    public class T53 public static boolean match String str String pattern if str null pattern null return false return matc
  • 一个自动将状态机生成代码的软件

    如果你是一个程序员 对状态机应该有一定的了解 甚至会经常使用 使用状态机的时候 一般都是自己设计程序去实现状态机 但 当要维护代码时 就会显得不方便 特别是比较复杂的时候 我幻想着有一个软件 能在图形界面上设计状态图 然后自动生成C C 代
  • FPGA学习回顾

    最近正在重新学习FPGA开发 把之前忽略的一些点记录下来 以便日后进行查阅 1 Output 和Output reg的区别 这个问题的回答具体可以看这篇博客 https blog csdn net crjmail article detai
  • 嵌入式ERPC框架正式发布了

    一 ERPC开发的原由 随着科技日新月异的快速发展 电子产品的功能越来越多 业务也越来越复杂 以前靠单打独斗完成电子产品的研发的时代已经慢慢远去 更多的是靠一个团队协作共同努力才能完成 这就为电子产品的设计和研发带来了新的问题 团队的协作
  • Java使用有限状态机算法实现判断字符串是否合法

    题目描述 请根据给出的正则表达式来验证邮箱格式是否合法 如果用户输入的格式合法则输出 邮箱格式合法 否则输出 邮箱格式不合法 正确格式对应的正则表达式 a zA Z0 9 a zA Z0 9 a zA Z0 9 输入 123123 nowc
  • 动画状态机Animator-Unity3d

    该模型一直处于奔跑状态 点击跳跃则跳跃一次后回到奔跑状态 点击攻击后则攻击一次回到奔跑状态 控制代码如下 using UnityEngine using System Collections 该人物一直处于奔跑状态 点击跳跃则跳跃一次后回到
  • 事件驱动型状态机EFSM介绍及C语言实现

    一 什么是状态机 有限状态机 英语 Finite state machine FSM 又称有限状态自动机 简称状态机 是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型 有限状态机是一种用来进行对象行为建模的工具 其作用主要是描
  • [从零开始学习FPGA编程-37]:进阶篇 - 基本时序电路-有限状态机实现(Verilog)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第1章 状态机概述 1 1 UML描述状态机 1 2 数字电路描述状态机
  • verilog之状态机详细解释(二)

    一 有限状态机设计的一般步骤 1 逻辑抽象 得出状态转换图 就是把给出的一个实际逻辑关系表示为时序逻辑函数 可以用状态转换表来描述 也可以用状态转换图来描述 这就需要 分析给定的逻辑问题 确定输入变量 输出变量以及电路的状态数 通常是取原因
  • squirrel-foundation状态机的使用细节

    上一篇文章介绍了stateless4j spring statemachine以及squirrel foundation三款状态机引擎的实现原理 以及我为何选择squirrel foundation作为解决方案 本文主要介绍一下项目中如何使
  • 3种方法:字符串转换整数 (atoi)

    文章目录 题目 解法一 排除法Python 解法二 正向逻辑C 解法三 有限状态机 C语言 题目 请你来实现一个 atoi 函数 使其能将字符串转换成整数 首先 该函数会根据需要丢弃无用的开头空格字符 直到寻找到第一个非空格的字符为止 接下
  • 将正则表达式转换为有限状态机

    您是否有关于将任何正则表达式转换为有限状态机 FSM 的算法的提示 例如 解析正则表达式并适当地将状态添加到 FSM 的算法 有什么参考或更深层次的想法吗 我正在用 Python 写这个 使用迈克尔 西普瑟的计算理论导论 第 1 章给出了将
  • 如何用 Java 实现 FSM - 有限状态机

    我有工作要做 需要你的帮助 我们想要实施一个FSM Finite State Machine 识别字符序列 如 A B C A C 并判断是否接受 我们认为要实现三个类 State Event and Machine The state类代
  • C++ FSM 设计和所有权

    我想为此语法实现一个 FSM 下推自动机 解析器 具有范围和条件的解析器已经被 lexed 到有限状态机解析器 我有以下内容 class State public virtual State event const string token
  • 使用xstate,是否可以配置一个适用于所有状态并在所有状态和子状态下以相同方式处理的事件?

    我是 xstate 的新手 我尝试在应用程序中使用它 用户可以根据父状态和 或子状态在应用程序中请求不同的内容 但是 无论应用程序处于什么状态 子状态 用户都应该能够发出一些请求 无论之前的状态是什么 对这些事件的响应都是相同的 如何配置此
  • 等待多个 Akka FSM 消息

    我有一个 Akka FSM actor 在收到消息后运行以下伪代码ReadyState lookupA Wrapper Lookup A lookupB Wrapper Lookup B lookupC Wrapper Lookup C g
  • 有限状态机和 FSM 间信令

    对具有本机 因此没有 FSM 生成工具 支持状态机开发的语言的建议执行以及消息 信号的传递 这适用于电信 例如实现这种复杂程度的 FSM 我考虑过 Erlang 但希望得到一些反馈 建议 教程指针 替代方案 特别是基于 Java 的框架 也
  • VHDL - FSM 未启动(仅在时序仿真中)

    我正在写我的硕士论文 而且我对 VHDL 还很陌生 但我仍然必须实现一些复杂的东西 这是我必须编写的最简单的结构之一 但我仍然遇到了一些问题 它是一个 FSM 采用低电平有效同步信号 用于对 DAC 进行编程 实现 24 位移位寄存器 这只

随机推荐

  • 核方法计算

    什么是核方法 往简单里说 核方法是将一个低维的线性不可分的数据映射到一个高维的空间 并期望映射后的数据在高维空间里是线性可分的 我们以异或数据集为例 在二维空间中 异或数据集是线性不可分的 但是通过将其映射到三维空间 我们可以非常简单地让其
  • Unity—反向动力学IK

    每日一句 人生最精彩的不是实现梦想的瞬间 而是坚持梦想的过程 目录 定义 准备 API 设置IK 头部IK 设置人物的头部根据视角旋转 手脚IK 案例 脚步IK 定义 一般来说 骨骼动画都是传统的从父节点到子节点的带动方式 即正向动力学 I
  • Django-Apscheduler定时任务

    常用方法 django crontab 最简单 类似crontab的方法进行定时任务的设置 但不支持Windows平台 django celery 非常晚上的定时任务库 但通常需要结合redis es等中间件结合使用 重 django ap
  • 一种改进的鲸鱼优化算法-附代码

    一种改进的鲸鱼优化算法 文章目录 一种改进的鲸鱼优化算法 1 鲸鱼优化算法 2 改进鲸鱼优化算法 2 1 准反向学习初始化种群 2 2 非线性收敛因子 2 3 自适应权重策略与随机差分法变异策略 3 实验结果 4 参考文献 5 Matlab
  • 直观理解神经网络最后一层全连接+Softmax

    直观理解神经网络最后一层全连接 Softmax 云 社区 腾讯云 tencent com
  • SeleniumLibrary4.5.0 关键字详解(十一)

    SeleniumLibrary4 5 0 关键字详解 十一 库版本 4 5 0 库范围 全局 命名参数 受支持 简介 SeleniumLibrary是Robot Framework的Web测试库 本文档说明了如何使用SeleniumLibr
  • pydantic学习与使用-11.pycharm插件pydantic 语法提示功能

    前言 虽然 pydantic 可以很好地与任何开箱即用的 IDE 配合使用 但在 PyCharm 的 JetBrains Plugins Repository 上提供了一个提供改进的 pydantic 集成的PyCharm 插件 可以更高效
  • 使用stm32进行ota升级

    主要方案 1 硬件方案 只使用mcu内部flash 没有外置flash 2 数据传输协议 ymodem 如果不了解ymodem值得去了解下 3 bootloader和app存放方案 将mcu内部flash分为两块内存 分别存放bootloa
  • 时序预测

    时序预测 MATLAB实现LSTM长短期记忆神经网络时间序列预测 多指标评价 目录 时序预测 MATLAB实现LSTM长短期记忆神经网络时间序列预测 多指标评价 效果一览 基本描述 模型结构 程序设计 效果一览 基本描述 长
  • 亚马逊云科技Build On2022技能提升计划第二季——揭秘出海爆款新物种背后的黑科技

    Build On是什么 亚马逊云科技开发者Build On是由亚马逊团队策划 开发者社区联合打造的动手实操系列活动 它是以现实技术应用和需求场景为核心 结合时下重点技术领域与亚马逊云科技的前沿技术方案打造的 面向开发人员 IT技术人员 或技
  • mysql插入新字段方法

    MySQL 允许在开头 中间和结尾处添加字段 一 开头 MySQL 默认在表的最后位置添加新字段 开头位置 第一列的前面 添加新字段 那么可以使用 FIRST 关键字 ALTER TABLE lt 表名 gt ADD lt 新字段名 gt
  • PAT C入门题目-7-19 计算天数 (15 分)

    7 19 计算天数 15 分 本题要求编写程序计算某年某月某日是该年中的第几天 输入格式 输入在一行中按照格式 yyyy mm dd 即 年 月 日 给出日期 注意 闰年的判别条件是该年年份能被4整除但不能被100整除 或者能被400整除
  • 图数据库(十二):Neo4j中数据类型及部分数据类型转换函数

    数据类型可以分为三大类 属性类型 数值类 Integer 和 Float 字符类 String 布尔类 Boolean 空间类 Point 时间类 Date Time LocalTime DateTime LocalDateTime 和 D
  • ChatGPT中文版Prompt提示工程超详细指南《提示工程高级技巧与技术》Github最新破万星项目Meta AI前工程师解密百万年薪提示工程师GPT-4模型优化利器(二)不定期更新

    提示工程高级技巧与技术 前言 Introduction 导言 零样本提示 少样本提示 少样本提示的限制 Chain of Thought Prompting 链式思考 CoT 提示 零样本COT提示 Zero shot COT 自我一致性
  • 【华为OD机试真题 JAVA】最长的指定瑕疵度的元音子串

    JS版 华为OD机试真题 JS 最长的指定瑕疵度的元音子串 标题 最长的指定瑕疵度的元音子串 时间限制 1秒 内存限制 262144K 语言限制 不限 开头和结尾都是元音字母 aeiouAEIOU 的字符串为 元音字符串 其中混杂的非元音字
  • 微信小程序中如何实现微信支付

    微信支付是微信公众平台提供的一种在线支付服务 可以为用户提供快速 方便 安全的支付体验 而在微信小程序中实现微信支付 则可以为应用程序提供更多的功能和服务 提高用户体验和商业价值 因此 在本文中 我们将介绍如何在微信小程序中实现微信支付 步
  • 轻量级linux桌面环境,Linux发行版最为轻量级的桌面环境之一Xfce 桌面

    开源多样性应该是 Linux 最好的特性之一 用户可以不断尝试各种自己喜欢的新鲜玩法与花样 并从中选择最适合自己的应用 无论你是 Linux 新人还是老鸟 层出不穷的应用和桌面环境可能都会让我们应接不暇 特别是尝试不同的 Linux 桌面环
  • Android之仿今日头条顶部导航栏效果

    随着时间的推移现在的软件要求显示的内容越来越多 所以要在小的屏幕上能够更好的显示更多的内容 首先我们会想到底部菜单栏 但是有时候像今日头条新闻客户端要显示的内容太多 而且又想在主界面全部显示出来 所以有加了顶部导航栏 今日头条顶部导航栏区域
  • 报错: org.springframework.boot.builder.SpringApplicationBuilder.([Ljava/lang/Object;)V

    springboot中引入eureka报错 java lang NoSuchMethodError org springframework boot builder SpringApplicationBuilder
  • 事件驱动型状态机EFSM介绍及C语言实现

    一 什么是状态机 有限状态机 英语 Finite state machine FSM 又称有限状态自动机 简称状态机 是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型 有限状态机是一种用来进行对象行为建模的工具 其作用主要是描