QEP_FSM有限状态机框架
目录
1. 有限状态机框架介绍
有限状态机在C语言或者C++中的典型实现方式主要包含以下几种:
-
嵌套的switch语句
-
状态表
-
面向对象的设计模式
-
基于以上方法的结合变体
典型的实现方法可以参考这篇博客,对嵌套switch和状态表的设计做了详细介绍:
C语言_有限状态机FSM: link
本文介绍一种新的有限状态机的实现方法QEP,是一种基于事件的状态处理方式,QEP是QP框架的一个组件,这里简单介绍一下QP框架。
QP(Quantum Platform, 量子平台,简称QP,)是一个用于实时嵌入式系统的软件框架,QP是轻量级的、开源的、基于层次式状态机的、事件驱动的平台。
QP由一个合乎UML规范的事件处理器(QEP),一个可移植的事件驱动实时框架(QF),一个小型化的运行至完成的内核(QK)和一个软件跟踪系统(QS)组成。

其中,QEP(Quantum Event Processor)是一个合乎UML规范的事件处理器。它使得UML状态机的直接编码(使用UML状态图)成为可能,并能生成高度可维护的C/C++代码。每一个状态机元素都精确无歧义地对应到唯一的代码片段。QEP完全支持层次化状态嵌套,这方便了子状态机的复用而无需重复进行编码。
2. QEP实现原理
QEP结合了状态表的设计方法,但是状态表的设计有一个缺陷,状态表通常是一个二维数组,数组的行和列表示状态和触发事件,数组元素则是事件处理的函数指针,当状态和事件比较多是,将需要大量的函数实现事件的处理。QEP则每个状态需要一个函数,函数中采用switch case结构处理事件。
QEP的创新点在于把状态映射为函数指针,QEP状态机提供给了标准接口init()和dispatch()。其中的核心结构是QFsm,是一个抽象类,不需要直接实例化,而是在创建实例状态的时候继承QFsm父类,派生出实际需要的状态,其中可以添加需要的状态变量。例如本例中,Bomb实例继承了QFsm类,但是有自己的状态便令timeout, code等。QEP事件处理器的结构如下:

2.1 QFsm结构
QStateHandler是QFsm中的核心结构,使用一个函数指针来表示状态,函数指针所指向的函数里面使用一个switch结构处理该状态下所有的事件,处理完事件返回一个状态值,已处理/忽略/需要状态迁移。
Q_TRAN宏中直接在需要状态迁移时改变了实例状态(myBomb)即状态函数指针,并且返回了一个状态值Q_RET_TRAN,dispatch根据这个返回的值判断是否进行状态切换,或者状态不需要切换继续执行当前状态。
这个宏的定义是有技巧的,是一个逗号表达式,return执行了逗号之前的内容,返回了逗号之后的值
这里定义的基本事件,是每一个状态必须有的
typedef U8 QState;
typedef QState (*QStateHandler)(void *me, QEvent const *e);
typedef struct QFsmTag{
QStateHandler state;
}QFsm;
#define QFsm_ctor(me_, initial_) ((me_)->state = (initial_))
void QFsm_init (QFsm *me, QEvent const *e);
void QFsm_dispatch (QFsm *me, QEvent const *e);
#define Q_RET_HANDLED ((QState)0)
#define Q_RET_IGNORED ((QState)1)
#define Q_RET_TRAN ((QState)2)
#define Q_HANDLED() (Q_RET_HANDLED)
#define Q_IGNORED() (Q_RET_IGNORED)
#define Q_TRAN(target_) ((

本文介绍了QEP_FSM,一种基于事件处理的有限状态机框架,它是QP软件框架的一部分。QEP利用函数指针表示状态,通过switch-case结构处理事件,简化了状态迁移和事件处理。QFsm类作为抽象基类,提供init()和dispatch()接口,状态和事件定义在应用层,使得状态机易于扩展和维护。QFsmDispatch过程涉及状态的进入和退出动作,同时处理状态迁移。这种设计减少了代码冗余,优化了资源占用。

2957

被折叠的 条评论
为什么被折叠?



