1.QP简介:

量子平台(Quantum Platform, 简称QP)是一个用于实时嵌入式系统的软件框架,QP是轻量级的、开源的、基于层次式状态机的、事件驱动的平台。

QP包括事件处理器(QEP)、轻量级的事件驱动框架(QF)、任务调度微内核(QK)和实时跟踪调试器(QS)四个部分。

利用QP可以开发出结构清晰的嵌入式应用程序(使用C或C++语言)。

2.QEP核心思想

QEP的核心思想就是,用一个函数指针指向当前状态函数,使用这个函数指针有条件地执行某状态函数,并根据执行结果执行其它的相应动作。

(1)状态图到C语言的转换
状态图可以很容易地转换到C语言表示,下面举例说明(略去了构造函数和初始化函数)。

例如下面的平面状态机FSM,图中有两个状态:设置状态setting和定时状态timing。

可以转换成C代码如下
两个状态函数声明:

static QState Bomb4_setting(Bomb4 *me, QEvent const *e);/*声明设置状态函数*/

static QState Bomb4_timing (Bomb4 *me, QEvent const *e);/*声明计时状态函数*/

两个状态函数的实现(对事件的处理):

QState Bomb4_setting(Bomb4 *me, QEvent const *e) {
switch (e->sig) {
case UP_SIG: {/*UP_SIG事件处理---增加定时处理*/
...
return Q_HANDLED();
}
case DOWN_SIG: {/*DOWN_SIG事件处理---减少定时事件处理*/
...
return Q_HANDLED();
}
case ARM_SIG: {/*ARM_SIG事件处理---定时事件处理*/
return Q_TRAN(&Bomb4_timing); /* 转到定时状态*/
}
}
return Q_IGNORED(); /*忽略事件*/
} /*----6.4-状态函数(定时状态处理)-----.*/
QState Bomb4_timing(Bomb4 *me, QEvent const *e) {
switch (e->sig) {
case Q_ENTRY_SIG: {/*状态进入处理*/
...
return Q_HANDLED();
}
case UP_SIG: {/*UP_SIG事件处理---保存密码设置*/
...
return Q_HANDLED();
}
case DOWN_SIG: {/*DOWN_SIG事件处理---保存密码设置*/
...
return Q_HANDLED();
}
case ARM_SIG: {/*ARM_SIG事件处理---密码正确则解除定时引爆,转到设置状态*/
if (me->code == me->defuse) {
return Q_TRAN(&Bomb4_setting);
}
return Q_HANDLED();
}
case TICK_SIG: {/*定时事件处理*/
...
return Q_HANDLED();
}
}
return Q_IGNORED();
}

(2)状态函数指针
在QP中用函数表示状态,叫状态函数,一个状态用一个状态函数表示,系统有多个状态,也就可以用多个函数来表示。在QEP中定义了一个状态函数指针QStateHandler,用这个函数指针可以指向任何一个状态函数。在状态函数内使用了结构清晰的switch---case语句,对不同的事件(信号)进行分类处理。

状态函数指针定义如下:

typedef QState  (*QStateHandler)(void *me, QEvent const *e);  /*状态函数指针,指向状态机中任何一个状态函数*/

其中 QState是调用状态函数的返回值,其定义如下:

typedef uint8_t QState;/*状态返回值,状态机状态处理函数返回值*/

有四种返回值:0---QRETHANDLED,表示事件被处理了,但没有转换,叫内部转换; 1---QRETIGNORED, 表示事件被忽略,没有处理; 2---QRETTRAN,表示事件被处理了,并有转换,转换到其它状态; 3---QRETSUPER,表示进入父状态了,只用于层次状态机HSM中。

(3)状态机的当前状态

平面状态机FSM或层次状态机HSM内部定义了一个QStateHandler类型的state变量,它是一个指向状态函数的指针,state指向哪个状态函数,哪个状态函数就是当前状态,有事件时,总是把事件发给当前状态的状态函数来处理。状态机有多个状态,但同一时刻,只有一个“焦点”(当前状态),“焦点”可以用QTRAN(target)来改变。

当前状态变量定义如下:

typedef struct QFsmTag {QStateHandler  state;  /*状态变量,当前活动状态,也就是经常用到的me->state */
} QFsm; /*平面状态机FSM数据结构*/ typedef struct QFsmTag QHsm; /*层次状态机HSM数据结构,与FSM一样*/

状态转换定义如下:

#define Q_TRAN(target_)(((QFsm *)me)->state = (QStateHandler)(target_), Q_RET_TRAN)

发给状态机的事件,总是发到当前状态变量所指向的状态函数来处理。

(4)事件处理器
事件处理器,也可以理解为一个状态机引擎,当处理有事件时,调用当前状态的状态函数处理这个事件,并处理调用状态函数的返回值,根据返回值进行相应的状态变换(如转移到父状态)。

同时状态引擎也处理状态的进入(ENTER)、退出(EXIT),并处理初始伪状态。

事件处理器利用状态函数指针来调用状态函数,总是把事件发送到当前状态,但事件不是在当前状态处理了,由调用的结果来判断。

3.结论

用状态函数指针从原理上可以调用任何状态函数,并检查调用结果。状态机引擎也就成了一个事件分派执行器。QHsm_dispatch()函数是QP中最复杂的函数,是理解状态机处理的关键。

参考:
【1】QP量子平台、量子编程:http://www.state-machine.com

QP之QEP原理的更多相关文章

  1. QP之QF原理

    1.QP简介: 量子平台(Quantum Platform, 简称QP)是一个用于实时嵌入式系统的软件框架,QP是轻量级的.开源的.基于层次式状态机的.事件驱动的平台. QP包括事件处理器(QEP). ...

  2. QP之QK原理

    QK是一个很小的抢占式微内核调度程序,它专用用QP中. QK的思想源于SST,Miro Samek重写了自己前期编的SST(Super Simple Task)代码. QK循环查询AO队列的状态表QK ...

  3. java web学习总结(十四) -------------------JSP原理

    一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...

  4. 深入解析SQL Server并行执行原理及实践(下)

    谈完并行执行的原理,咱们再来谈谈优化,到底并行执行能给我们带来哪些好处,我们又应该注意什么呢,下面展开. Amdahl’s  Law 再谈并行优化前我想有必要谈谈阿姆达尔定律,可惜老爷子去年已经驾鹤先 ...

  5. javaweb学习总结(十四)——JSP原理

    一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...

  6. java web 学习十四(JSP原理)

    一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...

  7. xtrabackup原理1

    http://www.cnblogs.com/Amaranthus/archive/2014/08/19/3922570.html Percona XtraBackup User Manual 阅读笔 ...

  8. POJ- Find a multiple -(抽屉原理)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6452   Accepted: 2809   Special Judge D ...

  9. javaWeb学习总结(8)- JSP原理

    一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...

随机推荐

  1. matlab练习程序(弧形、圆柱投影的复原)

    前一段介绍了从矩形图像到圆柱的正向投影,看这里和这里.今天介绍如何从已经投影的图像反映射到原图像上. 本来此种变换一定是需要数学公式的,不过这里只是用了一个很简单的方式来完成反映射. 具体就把每一列有 ...

  2. 清理SharePoint 2010的SQL Server 2008 R2日志数据库的方法

    最近发现Sharepoint的数据库磁盘经常满,导致无法保存数据,经检查发现数据磁盘的所有日志文件远远大于数据文件,因此需要收缩日志文件,一开始利用图形化的收缩文件方式,只有收缩数据文件的大小,对于日 ...

  3. js:正则表达式

    <script type="text/javascript"> function SubmitCk() { var reg = /^([a-zA-Z0-9]+[_|\_ ...

  4. SQL Server 2012安装配置(Part2 )

    2 服务器安装 运行安装程序后,首先进入 SQL Server 安装中心.选择左侧导航树中的"安装"菜单项. 图2-1 SQL Server 安装中心 在右侧菜单中点击" ...

  5. JAVA利用jxl读取Excel内容

    JAVA可以利用jxl简单快速的读取文件的内容,但是由于版本限制,只能读取97-03  xls格式的Excel. import java.io.File; import java.io.FileInp ...

  6. react-webpack-express

    这是一个整合react express 实现前后台交互,并且采用webpack进行打包和解析文件.其实react官方有一个脚手架create react app,也可以看那个,但是这个脚手架webpa ...

  7. IIS环境搭建

    IIS环境搭建 IIS环境搭建首先是建立在一个干净的.无毒的系统上,再进行相应操作.本文用到的是windows 2003的镜像文件,有条件的用户也可以使用windows的系统安装光盘. 下面进入操作步 ...

  8. Perl 基础笔记: 使用 cpanm 安装 Perl 模块

    cpanm 其实只是一个可执行文件而已.将它下载到 bin 目录,然后添加执行权限就可以用了. $ sudo wget http://xrl.us/cpanm -O /usr/bin/cpanm; s ...

  9. IOS Runtime的用法

    什么是runtime? 1> runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型.C语言函数)2> 实际上,平时我们编写的OC代码,底层都是基于runtime实现的* ...

  10. bzoj4999 This Problem Is Too Simple!

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...