简介:
QP由Quantum Leaps公司开发异于传统顺序式系统(前后台架构即main+ISR)和传统多任务系统(操作系统)的事件驱动型状态机框架,实现了在C语言下的面向对象编程,该框架支持有限状态机FSM和层次式状态机HSM
QP大体的框架如下图

 

对于开发者使用该框架的开发步骤如下:
1.理解整个项目需求
2.顺序图,划分出具有行为的活动对象并且将系统的资源分配到各个活动对象中,降低对象间的耦合,整理出各个活动对象间的事件交换
3.信号和事件的枚举,各个活动对象间的事件交换和自身对象下的触发信号事件。信号是只有触发信号而事件是带有参数的信号触发例如串口接收不仅有串口接收这一触发事件并且还有与之一起的数据
4.各个活动对象下的具体状态机实现
5.初始化并启动应用程序 给事件列队分配内存,初始化活动对象分配优先级最后启动QP将系统控制权交给QP管理,QP则根据你的事件触发来执行各个活动对象下的状态机
6.调试
如下图所示
 
更多关于QP的资料请看点击http://www.state-machine.com/psicc2/index.html,里面有电子版本的PSiCC2-CN文档详细介绍了整个QP框架

接下来简单介绍下QpNano,因为我的建模是使用QpNano.她是由事件驱动型框架下的裁剪版本,顾名思义,是针对资源有限的单片机。如低端的8位和16位单片机8051,PIC,AVR,MSP,STM8等当然也适应于32位处理器。

下面介绍如何在StateMachines板上运用QP官网上Blinky(闪灯)的例程之前简单介绍下StateMachines板的资源:
1.使用STM32F030C8T6 Cortex-m0处理器
2.板载按键、12864液晶屏、字库、数码管、串口转USB,LED灯

简单介绍完QP和QpNano后,下面才是我要重点推荐使用QP框架的原因。QP框架允许完全手工编程和使用自动生成代码工具QM。QM(QP™ Modeler)建模是基于QP框架和层次式状态机UML语言图形自动代码生成工具,可以在该软件下实现各个对象的状态机和事件交换,而状态机实现方式是使用UML图形,真正做到应用层使用图形编程,更适合我们的编程思维。

Blinky例程是一个LED闪灯程序,是学习QP、QM最基本的例程,以下是使用qm_3.3.0-win64下建立Blinky模型:

第一步在QM中新建工程

如下图所示在File菜单下点击New Modle新建一个QM工程,然后在弹出的页面Frameworks下选择使用qpn即qp-nano框架,Templates模板选择None,Name我暂且命名为Project,Location选择工程保存位置
 
点击OK后可以看到已经生成了Project的项目如下图所示
 
第二步:建立对象

在上一步骤中生成的工程左上角Mode Explorer下Project处鼠标右键选择Add Package建立一个包,在Property Editor处nane命名为AOs, stereotype选择components如下图所示
 
然后在AOs处鼠标右键选择Add Class建立一个类,在Property Editor处nane命名为Blinky, superclass 处选择qpn::QActive,如下图所示
 
接着在AOs处鼠标右键选择Add Attribute增加属性,在Property Editor处
nane处命名为AO_ Blinky
type为struct Blinky,即使Blinky类的具体实例对象
如下图所示
 
接着在AOs处鼠标右键选择Add Operation增加类构造,在Property Editor处
nane处命名为Blinky_Ctor
teturn type 选择void
在下方Code处具体添加代码构造
Blinky * const me = &AO_Blinky;

QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial));是qpn框架自带的API函数用于类构造
Q_STATE_CAST(&Blinky_initial)是指定初始化状态为Blinky_initial
如图所示
 
第三步:为对象建立状态机

在上一步骤的类Blinky处右键选择Add State Machine建立状态机,双击SM如下图所示
 
可以看到有会弹出SM of Blinky带有珊格的状态机工作区域,工作区域小大可由珊格最右下角拉伸。

第四步:画具体状态实现图

在上一步骤中已经在类里新建了一个状态机,下面需要实现具体的状态图。
闪灯程序非常简单,LED有两种状态即亮与灭,互相触发的事件为延时。亮与灭的两种状态只要等待延时事件,延时事件一旦触发就执行亮灯灭灯的动作。
如下图所示在右方有一个小宽框即为状态

点击该状态图标到珊格工作区域建立一个状态,在Property Editor属性编辑name处命名为LedOn如下图所示
 
同样的方法建立第二个状态LedOff,如下图所示
 
然后点击LedOn该状态图,在Property Editor属性编entry状态机进入事件处理中加入代码QActive_armX((QActive *)me, 0U, BSP_TICKS_PER_SEC/8U, 0);
和Led改变状态函数UpdataLesState(LedOn);
在exit状态机退出事件中加入代码QActive_disarmX((QActive *)me, 0U);

QActive_armX((QActive *)me, 0U, BSP_TICKS_PER_SEC/8U, 0)是qpn框架提供的API函数,用于产生(BSP_TICKS_PER_SEC/8U)个Tick延时,BSP_TICKS_PER_SEC是板子定义每秒多少个Tick,即心跳时钟。

QActive_disarmX((QActive *)me, 0U); 也是qpn框架系统提供的API函数,用于取消延时
相同的方法LedOff也是如此,将entry事件Led执行状态改为LedOff即可
如下图所示

 
接下来就要使两个状态建立转换了同样在右方状态机图标下方有一个Transition图标表示状态转换迁移
从LedOn状态转换到LedOff状态是延时事件,因为qpn框架提供了延时事件的枚举为Q_TIMEOUT,可以直接使用。
点击图标,从LedOn拉伸至LedOff状态,并在属性编辑里trigger触发为Q_TIMEOUT如下图所示
 
最后需要为该对象下的状态机指定一个初始化转移,即初始化转换到哪一个状态
点击右方图标Initial Transition指定为转换到LedOn状态如下图所示

第五步:生成C代码

首先需要为对象建立一个文件声明和定义对象,在Model Explorer中鼠标右键选择Add Directory,在Property Editor属性中path指定目录我命名为Code(默认是在建立工程文件目录下)
然后在Model Explorer可以看到Code选项右键选择Add File,并在Property Editor属性name中命名为Blinky.c
同样的方法建立文件Project.h主要用于事件枚举、包含外部使用到的.h文件、外部声明对象
如下图所示
 

接着在Blinky.c中定义和声明Blinky对象和初始化,QM中有以下代码生成指令
$declare()   声明
$define()    定义
如图所示
 
 
最后点击工具栏Tools选择Generate Code或直接按F7生成C代码

第六步:将QM生成代码加入到项目工程中
首先需要将qpn移植到STM32F030中,我使用qpn合作式内核,只需要在SysTick_Handler加入qpn 定时服务API QF_tickXISR(0)并在QF_onStartup()函数中加入SysTick配置中断时间和优先级
如图所示
 
然后需要为Blinky对象分配事件队列内存,并制定整个项目中所使用到的活动对象个数本例程只有一个在#include "qpn_conf.h" 宏定义QF_MAX_ACTIVE配置
如图所示
 

整个Blinky QM建模由
第一步在QM中新建工程
第二步:建立对象
第三步:为对象建立状态机
第四步:画具体状态实现图
第五步:生成C代码
第六步:将QM生成代码加入到项目工程中
介绍完成,看起来一个非常简单的闪灯程序由QM生成非常耗时,不如自己敲几行代码来的快,但这是飞跃,逻辑代码层完全由图形实现,意味着以后不同复杂的项目都可以使用图形来管理并且图形比起代码来说更加易懂和维护,图形编程是以后的方向。

如须了解更多关于StateMachines板信息请淘宝搜索 “QP学习板”找到全然电子或加入扣扣群129063491交流QM UML QP状态机等技术。

QM UML状态机建模实例之Blinky for cortex-m0的更多相关文章

  1. QM UML状态机建模实例之移植 cortex-m0

    ---恢复内容开始--- 在上一期“Blinky for cortex-m0”中我们介绍了如何在QM中建立一个工程和生成代码,如何使生成的代码在我们的工程师运行起来,为此这一期要介绍如何将QP-NAN ...

  2. UML标准建模语言与应用实例

    一.基本信息 标题:UML标准建模语言与应用实例 时间:2012 出版源:科技创新导报 领域分类:UML标准建模语言 面向对象 系统分析与设计 二.研究背景 问题定义:UML建模语言用图形来表现典型的 ...

  3. UML类建模(强烈推荐-思路很清晰)

    UML类建模(强烈推荐-思路很清晰) 2016年10月23日 15:17:47 mbshqqb 阅读数:2315 标签: uml面向对象设计模式 更多 个人分类: 面向对象程序设计   UML的构造快 ...

  4. UML类图实例分析

    登录模块 某基于C/S的即时聊天系统登录模块功能描述如下: 用户通过登录界面(LoginForm)输入账号和密码,系统将输入的账号和密码与存储在数据库(User)表中的用户信息进行比较,验证用户输入是 ...

  5. 利用UML语言建模--以图书馆管理系统为例

    一.基本信息 标题:利用UML语言建模--以图书馆管理系统为例 时间:2016 出版源:内蒙古科技与经济 领域分类:UML:RFID:图书馆:模型: 二.研究背景 问题定义:建立图书馆管理系统 难点: ...

  6. UML状态机图【图3】--☆

    UML状态机图 基本概述    状态机图描述的是围绕某一事物状态变化的图.它也是三大流程分析利器之一.它和活动图的区别在于,活动图是描述事物发生的流程,是多个角色参与的,而状态机描述的是事物的状态变化 ...

  7. uml面向对象建模基础总结

    uml九种图,其中的细节不说了.在后面的具体使用中提到这九种图. 建模流程: 1.分析需求. 2.通过分析名词,发现类,使用到类图. 3.建立用例模型,通过参与者分析用例,使用到用例图. 4.为用例建 ...

  8. 设计模式学习总结(一)——设计原则与UML统一建模语言

    一.概要 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证代码可靠性. 设计 ...

  9. 1. UML统一建模语言

    (1)UML概述: 建模: 对现实系统进行适当的过滤, 用适当的表现规则描述出简洁的模型. 建模是一种深入解决问题的方法. UML: UML(United Modeling Language, 统一建 ...

随机推荐

  1. Android Fragment 深度解析

    1.Fragment的产生与介绍 Android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视.针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套app,然后拷贝一份,修改布局以适应 ...

  2. Evolutionary Computing: [reading notes]On the Life-Long Learning Capabilities of a NELLI*: A Hyper-Heuristic Optimisation System

    resource: On the Life-Long Learning Capabilities of a NELLI*: A Hyper-Heuristic Optimisation System ...

  3. centos各版本信息

    CentOS version Architectures RHEL base Kernel CentOS release date RHEL release date Delay (days) 2.1 ...

  4. 【转】 XDC介绍

    转:http://blog.sina.com.cn/s/blog_693301190100sitz.html XDC是TI公司为嵌入式实时系统可重用软件组件(在XDC里被成为packages,以下成为 ...

  5. CSS3 选择器——基本选择器

    CSS的选择器,我想大家并不会陌生吧,因为天天在使用,但对于CSS3的选择器,要运用的灵活到位,我想对很多朋友还是一定的难度,特别是CSS3中的:nth选择器.那么从现在开始我们先丢开他们版本的区别, ...

  6. swiper横向轮播--3d

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. ES5——函数,对象,方法,this

    JS由表达式和语句组成 表达式:计算出一个值,但并不进行任何操作,不改变计算机运行状态 语句:包括 声明语句,赋值语句,控制结构 函数,对象,方法,this 数组和对象:是两个非常重要的数据类型 函数 ...

  8. 怎么让我们自己开发的Android程序设为默认启动

    怎么让我们自己开发的Android程序设为默认启动呢?其实很简单,只要在AndroidManifest.xml文件中配置一下首次启动的那个Activity即要. <activity        ...

  9. Java中如何克隆集合——ArrayList和HashSet深拷贝

    编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法.需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味 ...

  10. Spring——jar包详解(转)

    Spring——jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spr ...