中文翻译教程首发CSDN,转载请标明出处:http://www.voidcn.com/article/p-qbuyghua-bpr.html

NOTE:本中文教程相对官方原版教程,删减了Building Blinky on Windows/Linux 这章,读者可以参考我的另外一篇博文《使用QM的外部工具功能编译代码》中gcc的例子,其次增加了Add Free Operation章

这个教程介绍了怎么使用QM建模,并实现一个简单的、可以在嵌入式板子上闪烁一个LED的或者在桌面环境能够下打印LED的状态转换的”Blinky”应用。

NOTE:这个教程是使用的是QP/C框架(version 5).在其它的QP框架下运行也是类似

Blinky on TivaC LaunchPad

Creating New Model

打开File->Model…菜单或者点击在Edit Toolbar上的

按钮。接下来将会打开New Model Dialog Box窗口:

New Model dialog

选择model基于那个 QP framework type (“Frameworks” 面板)。这里可以选择:qpc for QP/C™, qpcpp for QP/C++™, and qpn for QP-nano™。在这个教程中,你保留默认的qpc framewords type。

给model命名(“Name:” 框)。NOTE:.qm后缀名会自动添加。在这个教程中,重命名model为blinky。

选择model文件存放的目录(“Location:” 框)。你可以手动输入目录路径,也可以点击右侧图标选择路径。NOTE:model的路径也是生成代码的地方。所有成的目录和文件都是相对于model文件目录来说的。

点击OK按钮。

Adding Model Items

现在你可以开始添加items到一个新的model中。

Add a Package

第一个要添加的是Package。在UML中package是一个组结构,用于合并其他model items到一个higher-level单元。它一般用来将classes组合到一起,但package同样可以持有free attributes,free operations,和其他的packages。

在 Model Explorer 窗口右击blinky item,在弹出菜单中,选择Add Package。

`

Add Package

在Property Editor窗口中修改package的名字为AOs(Active Objects),并选择stereotype为components。

`

Package Properties

Add a Class

接下来添加一个class到新的package中,因为只有class可以拥有行为 (i.e.,State Machines).

在Model Explorer窗口下右击AOs package并在弹出菜单中选择Add Class

`

Add Class

在Property Editor窗口中修改class名字为Blinky,并且选择superclass为qpc::QMActive.

Setting Superclass

NOTE:

在QM™ 一个状态机只可以和继承QP state machine classes的class相关联。所选择的状态机superclass决定状态机实现策略.

Add a Time Event

通过添加一个Time Event,以便传递周期事件到目标的blinky状态机中的blinking状态。

在Model Explorer窗口下右击Blinky类,并在弹出菜单中选择Add Attribute

`

Adding Attribute

在Property Editor窗口中修改attribute的名字为timeEvt,类型为QTimeEvt,visibility选择为private。

`

Attribute Properties

Add Free Operation (改动:新增)

增加一个Free Operation可以生成对应的普通函数,提供调用。

在Model Explorer窗口下右击AOs Package

`

Add Free Operation

在Property Editor窗口中修改Operation的名字为Blinky_ctor,并选择return type为void。添加如下代码:

Blinky * const me = &l_blinky;

QMActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial));

QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U);

`

Operation Properties

Note 1:

上面的代码第二行的构造函数,应该和对应的类所选用的superclass一致

QMActive_ctor()对应qpc::QMActive

QActive_ctor()对应qpc::QActive

QMsm_ctor()对应qpc::QMsm

QHsm_ctor()对应qpc::QHsm

这几个构造函数的参数都是一致的。

Note 2:

之所以使用Operation定义构造函数,而不是在对应的源文件中手动定义,其中一个原因可能是因为free Operation和class同在AOs下,修改class的superclass后,很容易就找到对应的构造函数进行修改。无需翻看源文件。

Add State Machine

在Model Explorer窗口下右击Blinky类,并在弹出菜单中选择Add Start Machine

`

Adding State Machine

Drawing State Machine Diagram

在Property Editor窗口中右击SM状态机,并在弹出菜单中选择Show Diagram(显示图表)。另外你可以双击SM状态机执行默认动作:Show Diagram

`

Show State Machine Diagram

Add States

在Diagram Toolbox 点击选中state工具,移动鼠标(不用按下左键)到diagram窗口合适的地方,这里选择左上角。注意到现在鼠标的形状发生了变化(如下图)。按下鼠标左键放置state形状,然后鼠标右键不要放松,往右下角拖动改变大小。释放鼠标。

`

Adding the off State

在Property Editor窗口中修改state的名字为off,并增加entry动作BSP_ledOff();到这个状态。

使用类似的方法添加第二个state。在Property Editor窗口中修改state的名字为on,并增加entry动作BSP_ledOn();到这个状态。

`

Setting Properties of State ‘off’

Add Initial Transition

在Diagram Toolbox 点击选中initial transition工具。移动鼠标(不用按下左键)到diagram窗口合适的地方。注意到现在鼠标的形状发生了变化(如下图)。按下鼠标左键,并拖动它(长按左键)到state的边缘。注意鼠标形状变化在接触到边缘后。释放鼠标。

`

Adding the Initial Transition

在Property Editor窗口中给Initial Transition 增加动作QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2);

Note

在Initial Transition的动作代码为起始BSP_TICKS_PER_SEC/2次clock ticks,和其后每次BSP_TICKS_PER_SEC/2次clock ticks投递time event。

Add Transitions

在Diagram Toolbox 点击选中transition工具。移动鼠标(不用按下左键)到diagram窗口合适的地方。注意到现在鼠标的形状发生了变化(如下图)。按下鼠标左键,并拖动它(长按左键)到state的边缘。注意鼠标形状变化在接触到边缘后。释放鼠标。

`

Adding a Transition

在Property Editor窗口中修改这个transition的trigger为TIMEOUT。

使用类似的方法添加第二个transition并改变它的trigger为TIMEOUT。

`

Complete State Machine

Generating Code

相比于其他的图形化状态机工具,QM™ 让生成代码”上下颠倒(upside down)”了.QM™ 让你确定生成代码的结构,目录名,文件名和进入文件里的每个元素(看物理设计)。你可以混合你自己的代码到生成代码中,并使用QM生成你觉得合适的,尽可能多或者尽可能少的总代码。

Add Directory

首先需要创建一个目录,这个目录的设置决定了生成代码相对于

·

Adding a Directory

在Model Explorer窗口下右击Blinky model项,并在弹出菜单中选择Add Directory。这将会是代码生成的目录。目录的路径参考于QM Model File并可以在Property Editor中编辑。在directory中填入”.”符号,代表了生成的代码使用和QM Model File相同的目录。

Add File

在directory里可以添加Files。在实际的项目中,通常会将代码分成头文件和源文件,并使用独立的源文件作为板级支持包(BSP)和mian()。但为了简单起见,这个教程在会在下面的步骤中,将会将他们都放到一个文件里:blinky.c里:

Adding a File

在Model Explorer窗口下右击directory项,并在弹出菜单中选择Add File。在这个文件创建后,你可以在Property Editor里编辑它的名字为blinky.c

Edit File (改动:手工代码,增加ctor函数的生成)

你需要为QP™每个file-template提供一个前体(body),在其中你可以输入自己的代码以及代码生成指令。下面的代码将会演示最重要的两个指令 $declare(AOs::Blinky)用于生成Blinky class的声明;$define(AOs::Blinky) 用于生成Blinky class的定义和$define(AOs::Blinky_ctor)用于生成对应的构造函数。

#include "qp_port.h"

#include

#include

#define BSP_TICKS_PER_SEC 100

void BSP_ledOff(void) {

printf("LED OFF\r\n");

}

void BSP_ledOn(void) {

printf("LED ON\r\n");

}

void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) {

fprintf(stderr, "Assertion failed in %s, line %d", file, line);

exit(0);

}

void QF_onStartup(void) {}

void QF_onCleanup(void) {}

void QF_onClockTick(void) {

QF_TICK((void *)0);

}

enum BlinkySignals {

TIMEOUT_SIG = Q_USER_SIG,

MAX_SIG

};

/*************** ask QM to declare the Blinky class ******************/

$declare(AOs::Blinky)

static Blinky l_blinky;

QActive * const AO_Blinky = &l_blinky.super;

/*************** ask QM to define the Blinky_ctor operation *********/

$define(AOs::Blinky_ctor)

/*************** ask QM to define the Blinky class ******************/

$define(AOs::Blinky)

int main() {

static QEvt const *blinky_queueSto[10];

Blinky_ctor();

QF_init();

QActive_start(AO_Blinky, 1U,

blinky_queueSto, Q_DIM(blinky_queueSto),

(void *)0, 1024U, (QEvt *)0);

return QF_run();

}

`

Creating a Fully-Qualified Item Name by Drag-n-Drop

Opening blinky.c File and Pasting the Code

Generate Code

点击工具条中的Generate Code按键,生成代码。

Code Generation

这时QM已经在blinky.qm这个QM Model File相同的目录下生成了代码。可以使用一个代码编辑器对代码进行查看。

Building the Project (改动:删除)

QM法化简C语言程序,QM基础教程相关推荐

  1. c语言程序设计基础项目教程,C语言程序设计基础项目教程

    摘要: <C语言程序设计基础项目教程/高职高专计算机教学改革新体系规划教材>通过项目实例,重点讲解C语言结构化程序设计的基本思想,方法和解决实际问题的技巧,培养学习者设计,分析应用程序的能 ...

  2. c语言驱动程序开发基础教程,C 语言入门介绍

    C 语言入门介绍 适用于初学者和专业人士的C语言教程采用编程方法,可帮助您轻松理解C语言教程.我们的C教程通过程序解释了每个主题. C语言是由Dennis Ritchie开发的,用于创建与硬件设备(例 ...

  3. 微信小程序开发基础教程

    文章目录 1.什么叫做微信小程序 2.微信小程序开发功能特点 3.微信小程序开发流程 3.1 微信公众平台注册 3.2 微信开发者工具下载 3.3 微信开发者工具界面上的基本功能介绍 3.3.1 开发 ...

  4. c语言程序设计项目化教程第二版130,C语言程序设计项目化教程pdf(附答案)电子版...

    通过了C语言入门的学习,很多朋友已经掌握了一定的C语言知识,那么想要进一步深入了解,就可以开始学习这本C语言程序设计项目化教程了,让你深入了解项目开发,感兴趣的朋友快来下载使用吧. C语言介绍 C语言 ...

  5. c语言设计项目化pdf下载,C语言程序设计项目化教程pdf(附答案)电子版

    通过了C语言入门的学习,很多朋友已经掌握了一定的C语言知识,那么想要进一步深入了解,就可以开始学习这本C语言程序设计项目化教程了,让你深入了解项目开发,感兴趣的朋友快来下载使用吧. C语言介绍 C语言 ...

  6. C语言程序设计基础实验教程,C语言程序设计基础实验教程

    本书是教育科学"十五"国家规划课题的研究成果,是<C语言程序设计基础>一书的实验配套教程,它为C语言初学者上机实验提供指导.全书提供了13个方面的验证性.设计性实验,对 ...

  7. c语言字符动画教程,C语言程序设计项目式教程(在线实验+在线自测 )

    项目一 搭建C语言图形编程环境 1 学习目标 1 项目描述 1 任务一 VC6.0集成开发环境的搭建及图形库的安装 1 任务说明 1 相关知识 1 1.1 C语言简述 1 1.2 C语言程序的开发流程 ...

  8. 输入48个数字从低到高c语言程序,计算机应用基础选择精选100题

    选择题精选 1. 目前人们普遍使用的电子计算机是() A.数字电子计算机 B.模拟电子计算机 C.数字模拟混合电子计算机 D.优化电子计算机 2. 20世纪50年代到60年代,3. 电子计算机的功能元 ...

  9. Python语言程序与基础(第二版)

    P56习题部分 2.1实例1的修改,改造实例代码1.1,采用eval(input(<提示内容>)),形式替换现有的输入内容,并使输出的温度值为整数.代码如下: ##2.1温度转换实例 改写 ...

最新文章

  1. themleaf返回可以带目录结构
  2. Nhibernate使用动态Expression的问题解决
  3. java开发简易计算器
  4. python全局变量赋值_Python全局变量和局部变量
  5. 学习python遇到的一些有趣点(每日更新)
  6. BERT4GCN:利用BERT中间层特征增强GCN进行基于方面的情感分类
  7. 菲律宾马尼拉华人区一大厦发生火灾 致1人遇难
  8. 【Gym - 101848D】XOR【多个数异或的典型问题】【费马小定理】
  9. android腾讯微博吹一吹实现原理
  10. 关于Java Web打印
  11. Scratch 简单的小游戏 --- 碰碰球
  12. 安装mysql详细教程(windows 10安装mysql详细教程新手必看)
  13. H盘显示数据错误循环冗余检查要怎样办啊
  14. QNAP领衔进击2014vNAS內置虚拟机横空出世
  15. icns文件_感染phobos家族勒索病毒文件后缀.phobos如何应对处理?
  16. 华为Mate40 Pro 66w充电器冒火花怎么回事?
  17. 人工智能AI实训平台
  18. thymeleaf中 th:href使用笔记
  19. Apple芯片Mac安装ARM版Win10完美教程(结尾附视频)
  20. 关于循环调用Variable RNN的reuse问题

热门文章

  1. 设计模式的理解:组合模式 (Composite)
  2. http / 关于长连接和短链接的理解
  3. 乐鑫代理启明云端分享:用ESP32单片机控制LED教程示例
  4. 一般屏幕的3D模型是公开的吗?
  5. 乾云服务器虚拟化,乾云服务器虚拟化系统
  6. mysql主主同步配置_MySQL 主主同步配置步骤
  7. vim 插件_你不得不知道的适用于程序员的VIM插件
  8. 2021年度人工智能产品TOP10,百度飞桨EasyDL再获业界认可
  9. java中所有函数都是虚函数_关于Java:虚拟函数与纯虚函数之间的区别是什么?...
  10. java集群_身为Java程序员的你知道分布式与集群的联系及区别吗?