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

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

3天内不再提示

状态机要实现哪些内容

科技绿洲 来源:一起学嵌入式 作者:一起学嵌入式 2023-06-22 14:26 次阅读

状态机模式是一种行为模式,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式环境下,有时只能写纯C代码,并且还需要考虑代码的重入和多任务请求跳转等情形,因此实现起来着实需要一番考虑。

近日在看到了一个状态机的实现,也学着写了一个,与大家分享。

首先,分析一下一个普通的状态机究竟要实现哪些内容。

状态机存储从开始时刻到现在的变化,并根据当前输入,决定下一个状态。这意味着,状态机要存储状态、获得输入(我们把它叫做跳转条件)、做出响应。

图片

如上图所示,{s1, s2, s3}均为状态,箭头c1/a1表示在s1状态、输入为c1时,跳转到s2,并进行a1操作。

最下方为一组输入,状态机应做出如下反应:

图片

当某个状态遇到不能识别的输入时,就默认进入陷阱状态,在陷阱状态中,不论遇到怎样的输入都不能跳出。

为了表达上面这个自动机,我们定义它们的状态和输入类型:

typedefintState;typedefintCondition;#defineSTATES 3 + 1#defineSTATE_1 0#defineSTATE_2 1#defineSTATE_3 2#defineSTATE_TRAP 3#defineCONDITIONS 2#defineCONDITION_1 0#defineCONDITION_2 1

在嵌入式环境中,由于存储空间比较小,因此把它们全部定义成宏。此外,为了降低执行时间的不确定性,我们使用O(1)的跳转表来vwin 状态的跳转。

首先定义跳转类型:

typedefvoid(*ActionType)(State state, Condition condition); typedefstruct{ Statenext; ActionType action; } Trasition, * pTrasition;

然后按照上图中的跳转关系,把三个跳转加一个陷阱跳转先定义出来:

// (s1, c1, s2, a1)Trasition t1 = { STATE_2, action_1 };// (s2, c2, s3, a2)Trasition t2 = { STATE_3, action_2 };// (s3, c1, s2, a3)Trasition t3 = { STATE_2, action_3 };// (s, c, trap, a1)Trasition tt = { STATE_TRAP, action_trap };

其中的动作,由用户自己完成,在这里仅定义一条输出语句。

voidaction_1(State state, Condition condition){ printf("Action 1 triggered.\\n"); }

最后定义跳转表:

pTrasition transition_table[STATES][CONDITIONS] = {/* c1, c2*//* s1 */&t1, &tt,/* s2 */&tt, &t2,/* s3 */&t3, &tt,/* st */&tt, &tt, };

即可表达上文中的跳转关系。

最后定义状态机,如果不考虑多任务请求,那么状态机仅需要存储当前状态便行了。例如:

typedefstruct { State current; } StateMachine, * pStateMachine; Statestep(pStateMachine machine, Condition condition){ pTrasition t = transition_table[machine- >current][condition]; (*(t- >action))(machine- >current, condition); machine- >current = t- >next;returnmachine- >current; }

但是考虑到当一个跳转正在进行的时候,同时又有其他任务请求跳转,则会出现数据不一致的问题。

举个例子:task1(s1, c1/a1 –> s2)和task2(s2, c2/a2 –> s3)先后执行,是可以顺利到达s3状态的,但若操作a1运行的时候,执行权限被task2抢占,则task2此时看到的当前状态还是s1,s1遇到c2就进入陷阱状态,而不会到达s3了,也就是说,状态的跳转发生了不确定,这是不能容忍的。

因此要重新设计状态机,增加一个“事务中”条件和一个用于存储输入的条件队列。修改后的代码如下:

#defineE_OK 0#defineE_NO_DATA 1#defineE_OVERFLOW 2typedefstruct{Condition queue[QMAX];inthead;inttail;booloverflow; } ConditionQueue, * pConditionQueue;intpush(ConditionQueue * queue, Condition c){unsignedintflags;Irq_Save(flags);if((queue- >head == queue- >tail +1) || ((queue- >head ==0) && (queue- >tail ==0))) { queue- >overflow =true;Irq_Restore(flags);returnE_OVERFLOW; }else{ queue- >queue[queue- >tail] = c; queue- >tail = (queue- >tail +1) % QMAX;Irq_Restore(flags); }returnE_OK; }intpoll(ConditionQueue * queue, Condition * c){unsignedintflags;Irq_Save(flags);if(queue- >head == queue- >tail) {Irq_Restore(flags);returnE_NO_DATA; }else{ *c = queue- >queue[queue- >head]; queue- >overflow =false; queue- >head = (queue- >head +1) % QMAX;Irq_Restore(flags); }returnE_OK; }typedefstruct{State current;boolinTransaction; ConditionQueue queue; } StateMachine, * pStateMachine;staticState __step(pStateMachine machine, Condition condition) { State current = machine - > current; pTrasition t = transition_table[current][condition]; (*(t- >action))(current, condition); current = t- >next; machine- >current = current;returncurrent; }Statestep(pStateMachine machine, Condition condition){ Condition next_condition;intstatus; State current;if(machine- >inTransaction) {push(&(machine- >queue), condition);returnSTATE_INTRANSACTION; }else{ machine- >inTransaction =true; current = __step(machine, condition); status =poll(&(machine- >queue), &next_condition);while(status == E_OK) { __step(machine, next_condition); status =poll(&(machine- >queue), &next_condition); } machine- >inTransaction =false;returncurrent; } }voidinitialize(pStateMachine machine, State s){ machine- >current = s; machine- >inTransaction =false; machine- >queue.head =0; machine- >queue.tail =0; machine- >queue.overflow =false; }
                                                                                                                                                                                                                                                                                                                                                                        
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4637

    浏览量

    67623
  • 状态机
    +关注

    关注

    2

    文章

    489

    浏览量

    27339
  • 存储空间
    +关注

    关注

    0

    文章

    53

    浏览量

    10623
收藏 人收藏

    评论

    相关推荐

    Spring状态机实现原理和使用方法

    说起 Spring 状态机,大家很容易联想到这个 状态机和设计模式中 状态模式的区别是啥呢?没错,Spring 状态机就是 状态模式的一种
    的头像 发表于12-26 09:39 1581次阅读
    Spring<b class='flag-5'>状态机</b>的<b class='flag-5'>实现</b>原理和使用方法

    如何写好状态机

    如何写好 状态机: 状态机是逻辑设计的重要 内容状态机的设计水平直接反应工程师的逻辑功底,所以许多公司的硬件和逻辑工程师面试中, 状态机设计几乎是
    发表于06-14 19:24 97次下载

    状态机举例

    状态机举例 你可以指定 状态寄存器和 状态机状态。以下是一个有四种 状态的普通 状态机。 // Th
    发表于03-28 15:18 938次阅读

    状态机原理及用法

    状态机原理及用法 状态机原理及用法 状态机原理及用法
    发表于03-15 15:25 0次下载

    利用状态机状态机实现层次结构化设计

    练习九.利用 状态机的嵌套 实现层次结构化设计目的:1.运用主 状态机与子 状态机产生层次化的逻辑设计;
    发表于02-11 05:52 3233次阅读
    利用<b class='flag-5'>状态机</b>的<b class='flag-5'>状态机</b><b class='flag-5'>实现</b>层次结构化设计

    状态机概述 如何理解状态机

    本篇文章包括 状态机的基本概述以及通过简单的实例理解 状态机
    的头像 发表于01-02 18:03 1w次阅读
    <b class='flag-5'>状态机</b>概述  如何理解<b class='flag-5'>状态机</b>

    基于FPGA实现状态机的设计

    状态机有三种描述方式:一段式 状态机、两段式 状态机、三段式 状态机。下面就用一个小例子来看看三种方式是如何 实现的。
    的头像 发表于08-29 06:09 2682次阅读
    基于FPGA<b class='flag-5'>实现状态机</b>的设计

    如何使用状态机实现对TLC549的采样控制

    本文档的主要 内容详细介绍的是如何使用 状态机 实现对TLC549的采样控制。
    发表于08-07 17:39 9次下载
    如何使用<b class='flag-5'>状态机</b><b class='flag-5'>实现</b>对TLC549的采样控制

    使用函数指针的方法实现状态机

    之前写过一篇 状态机的实用文章,很多朋友说有几个地方有点难度不易理解,今天给大家换种简单写法,使用函数指针的方法 实现状态机状态机简介 有限 状态机FSM是有限个
    的头像 发表于10-19 09:36 2283次阅读
    使用函数指针的方法<b class='flag-5'>实现状态机</b>

    FPGA:状态机简述

    本文目录 前言 状态机简介 状态机分类 Mealy 型 状态机Moore 型 状态机 状态机描述 一段式
    的头像 发表于11-05 17:58 7004次阅读
    FPGA:<b class='flag-5'>状态机</b>简述

    状态模式(状态机)

    share,作者:亚索老哥)),原来 状态机还可以这么简单地玩~~亚索老哥提出的 状态机六步法(1)、定义 状态接口(2)、定义系统当前 状态指针(3)、定义具体
    发表于12-16 16:53 8次下载
    <b class='flag-5'>状态</b>模式(<b class='flag-5'>状态机</b>)

    LABVIEW的状态机实现资料合集

    LABVIEW的 状态机 实现资料合集
    发表于01-04 11:18 41次下载

    如何在FPGA中实现状态机

    状态机往往是FPGA 开发的主力。选择合适的架构和 实现方法将确保您获得一款最佳解决方案。 FPGA 常常用于执行基于序列和控制的行动, 比如 实现一个简单的通信协议。对于设计人员来说,满足这些行动
    的头像 发表于07-18 16:05 899次阅读
    如何在FPGA中<b class='flag-5'>实现状态机</b>

    什么是状态机状态机的种类与实现

    状态机,又称有限 状态机(Finite State Machine,FSM)或米利 状态机(Mealy Machine),是一种描述系统 状态变化的模型。在芯片设计中,
    的头像 发表于10-19 10:27 7568次阅读

    如何在FPGA中实现状态机

    在FPGA(现场可编程门阵列)中 实现状态机是一种常见的做法,用于控制复杂的数字系统行为。 状态机能够根据当前的输入和系统 状态,决定下一步的动作和新的 状态。这里,我们将详细探讨如何在FPG
    的头像 发表于07-18 15:57 153次阅读