QP状态机学习②——QM的使用

news/2025/2/19 14:31:56/

QM的使用主要是生成UML的状态机图

例子的主要功能是每隔0.5s闪烁LED
在这里插入图片描述
具体的使用流程参考的是 状态机 | 如何从零开始构建一个QM项目 (qq.com)

  • 首先打开软件

在这里插入图片描述

在左上角找到新建模型的选项
在这里插入图片描述
在这里插入图片描述

我们可以看到有3种框架,qpc,qpcpp和qpn.其中qpcpp是C++的部分基本和我们用不上,之后qpn这个是qpc nano的意思,但是现在这个已经不用了,没有更新了。所以我们采用qpc。详情可以参见Quantum Leaps · GitHub

在这里插入图片描述

  • 新建QP模型

我们新建一个类似于官方闪灯的空白模型,然后生成到对应目录,选择qpc -> None
在这里插入图片描述

  • 根据要求新建类图以及状态机图

添加的第一项是包,UML中的包是一种分组构造,它允许我们将其他模型项组合到更高级别的单元(包)中。程序包最常见的用途是将类分组在一起,但是程序包也可以包含自由属性,自由操作甚至其他程序包。

Model Explorer视图中,右键单击模型项目以获取特定于该项目的弹出菜单,然后选择Add Package,在Property Editor视图中更改名字如下图:
在这里插入图片描述
接下来,向新包中添加一个类,因为只有类才能具有行为(即状态机)。
Model Explorer视图中,右键单击AOs以获取特定于该项目的弹出菜单,然后选择Add Class,在Property Editor视图中更改名字如下图:
在这里插入图片描述接下来添加时间事件属性,该属性将周期性触发“Blinky”状态机中的闪烁。
Model Explorer视图中,右键单击Blinky:QActive以获取特定于该项目的弹出菜单,然后选择Add Attribute,在Property Editor视图中更改配置如下图:
在这里插入图片描述

添加状态机

Model Explorer视图中,右键单击Blinky:QActive以获取特定于该项目的弹出菜单,然后选择Add State Machine,双击SM,如下图:在这里插入图片描述

添加状态

在图工具箱中,单击状态工具,将鼠标移动到图表窗口,在其中放置状态形状的左上角。单击鼠标并将其拖动到状态形状的右下角,释放鼠标。举个例子如下:
在这里插入图片描述
Property Editor中,将状态名称更改为off,然后将entry添加到此状态BSP_ledOff();,添加第二个状态就变为onBSP_ledOn()
再添加起始的默认状态,也就是起点。
在这里插入图片描述
在这里插入图片描述
注意添加起点之后也需要增加状态机的超时的事件。
在这里插入图片描述

QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2);

使用第一个箭头将全部的设置链接起来
在这里插入图片描述
注意需要更改为TIMEOUT
在这里插入图片描述
结束之后的成品是这样子的
在这里插入图片描述

#include "qpc.h"
#include <stdio.h>
#include <stdlib.h> /* for exit() */Q_DEFINE_THIS_FILEenum { BSP_TICKS_PER_SEC = 100 };void BSP_ledOff(void) {// 添加操作代码printf("LED OFF\n");
}
void BSP_ledOn(void) {// 添加操作代码printf("LED ON\n");
}
void Q_onAssert(char const * const module, int loc) {printf("Assertion failed in %s:%d", module, loc);
}
void QF_onStartup(void) {NVIC_SetPriority(SysTick_IRQn, 1); // 设置中断优先级
}
void QF_onCleanup(void) {}
void QF_onClockTick(void) {QF_TICK_X(0U, (void *)0);  /* perform the QF clock tick processing */
}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;static void Blinky_ctor(void) {Blinky *me = (Blinky *)AO_Blinky;QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial));QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U);
}int StateMachine_Start() {/* statically allocate event queue buffer for the Blinky AO */static QEvt const *blinky_queueSto[10];QF_init(); /* initialize the framework */Blinky_ctor(); /* explicitly call the "constructor" */QACTIVE_START(AO_Blinky,1U, /* priority */blinky_queueSto, Q_DIM(blinky_queueSto),(void *)0, 0U, /* no stack */(QEvt *)0);    /* no initialization event */return QF_run(); /* run the QF application */
}/*================ ask QM to define the Blinky class ================*/
$define${AOs::Blinky}

后面通过生成代码我们就可以生成代码了
在这里插入图片描述
生成的文件大概如下:

/*.$file${Code::Blinky.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
/** Model: model.qm* File:  ${Code::Blinky.c}** This code has been generated by QM 5.1.4 <www.state-machine.com/qm/>.* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.** This program is open source software: you can redistribute it and/or* modify it under the terms of the GNU General Public License as published* by the Free Software Foundation.** This program is distributed in the hope that it will be useful, but* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License* for more details.*/
/*.$endhead${Code::Blinky.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
#include "main.h"
#include "qpc.h"
#include <stdio.h>Q_DEFINE_THIS_FILEenum
{BSP_TICKS_PER_SEC = 1000
};void BSP_ledOff(void)
{HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);// printf("LED OFF\n");
}
void BSP_ledOn(void)
{HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);// printf("LED ON\n");
}void Q_onAssert(char const *const module, int loc)
{}void QF_onStartup(void)
{NVIC_SetPriority(SysTick_IRQn, 1); // 设置中断优先级
}
void QF_onCleanup(void) {}
void QV_onIdle(void) {}void QF_onClockTick(void)
{QF_TICK_X(0U, (void *)0); /* perform the QF clock tick processing */
}enum BlinkySignals
{TIMEOUT_SIG = Q_USER_SIG,MAX_SIG
};/*============== ask QM to declare the Blinky class ================*/
/*.$declare${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
/*.${AOs::Blinky} ..........................................................*/
typedef struct
{/* protected: */QActive super;/* private: */QTimeEvt TimeEvt;
} Blinky;/* protected: */
static QState Blinky_initial(Blinky *const me, void const *const par);
static QState Blinky_LED_ON(Blinky *const me, QEvt const *const e);
static QState Blinky_LED_OFF(Blinky *const me, QEvt const *const e);
/*.$enddecl${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/static Blinky l_blinky;
QActive *const AO_Blinky = &l_blinky.super;static void Blinky_ctor(void)
{Blinky *me = (Blinky *)AO_Blinky;QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial));QTimeEvt_ctorX(&me->TimeEvt, &me->super, TIMEOUT_SIG, 0U);
}int StateMachine_Start()
{/* statically allocate event queue buffer for the Blinky AO */static QEvt const *blinky_queueSto[10];QF_init(); /* initialize the framework */Blinky_ctor(); /* explicitly call the "constructor" */QACTIVE_START(AO_Blinky,1U, /* priority */blinky_queueSto, Q_DIM(blinky_queueSto),(void *)0, 0U, /* no stack */(QEvt *)0);    /* no initialization event */return QF_run();             /* run the QF application */
}/*================ ask QM to define the Blinky class ================*/
/*.$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
/*. Check for the minimum required QP version */
#if (QP_VERSION < 690U) || (QP_VERSION != ((QP_RELEASE ^ 4294967295U) % 0x3E8U))
#error qpc version 6.9.0 or higher required
#endif
/*.$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
/*.$define${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
/*.${AOs::Blinky} ..........................................................*/
/*.${AOs::Blinky::SM} ......................................................*/
static QState Blinky_initial(Blinky *const me, void const *const par)
{/*.${AOs::Blinky::SM::initial} */QTimeEvt_armX(&me->TimeEvt, BSP_TICKS_PER_SEC / 2, BSP_TICKS_PER_SEC / 2);return Q_TRAN(&Blinky_LED_ON);
}
/*.${AOs::Blinky::SM::LED_ON} ..............................................*/
static QState Blinky_LED_ON(Blinky *const me, QEvt const *const e)
{QState status_;switch (e->sig){/*.${AOs::Blinky::SM::LED_ON} */case Q_ENTRY_SIG:{BSP_ledOn();status_ = Q_HANDLED();break;}/*.${AOs::Blinky::SM::LED_ON::TIMEOUT} */case TIMEOUT_SIG:{status_ = Q_TRAN(&Blinky_LED_OFF);break;}default:{status_ = Q_SUPER(&QHsm_top);break;}}return status_;
}
/*.${AOs::Blinky::SM::LED_OFF} .............................................*/
static QState Blinky_LED_OFF(Blinky *const me, QEvt const *const e)
{QState status_;switch (e->sig){/*.${AOs::Blinky::SM::LED_OFF} */case Q_ENTRY_SIG:{BSP_ledOff();status_ = Q_HANDLED();break;}/*.${AOs::Blinky::SM::LED_OFF::TIMEOUT} */case TIMEOUT_SIG:{status_ = Q_TRAN(&Blinky_LED_ON);break;}default:{status_ = Q_SUPER(&QHsm_top);break;}}return status_;
}
/*.$enddef${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

可以看到这边生成的文件相较于之前的多了状态的流转以及一些 其他的部分。这个文件我们就可以真正用于QP的移植了。


http://www.ppmy.cn/news/867371.html

相关文章

i.MX8QM环境搭建

1、代码下载地址 面向Android Auto的恩智浦软件_NXP 半导体 2、工具下载 2.1 gcc工具下载并拷贝到本地解压&#xff1a; sudo tar -xvJf gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz -C /opt sudo tar -jxvf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2 …

u-boot学习笔记一:u-boot 2019启动流程分析

一目了然 1 简述2 启动流程分析2.1 Boot ROM2.2 启动追踪 1 简述 u-boot学习笔记是基于NXP i.MX8系列芯片中imx8mq芯片学习记录的心得体会&#xff0c;各位大神在阅读过程中如发现有错误的地方&#xff0c;还请在评论区中指出&#xff0c;小生在此先拜谢了。 学习过程中使用的…

imx8qm wifi sdio调试

imx8qm平台用的是有WIFI和BT功能的Murata 芯片&#xff0c;型号是LBEE6U41LQ&#xff0c;WIFI采用sdio接口&#xff0c;由WL_EN控制上电&#xff1b;BT是UART1接口&#xff0c;由BT_EN控制上电&#xff1b; 一.硬件原理 二.引脚信息 /* bt enable*/SC_P_USDHC2_VSELECT /* uar…

Matlab锂离子电池pi模型(附上完整源码+数据)

文章目录 介绍完整源码下载 介绍 锂离子电池是一种常见的可充电电池&#xff0c;广泛应用于移动设备、电动汽车和储能系统等领域。为了更好地理解和优化锂离子电池的性能&#xff0c;研究人员开发了各种数学模型来描述其动力学行为。其中&#xff0c;pi模型是一种常用的电化学…

SAP QM数据库表清单

QM 数据库表清单&#xff1a; 主数据 QMAT 检验类型 - 物料参数 QMHU 检验批和处理单位项目间的 QM 链接 QMTB 检验方法记录 QMTT 检验方法文本 QPAC 检验选择集的目录代码 QPAM 检验选择集目录 QPMK 检验主特性 QPMT 检验主特性文本 QPMZ 分配表检验方法/…

QM模块常用表

QM 数据库表清单&#xff1a; 主数据 QMAT 检验类型 - 物料参数 QMHU 检验批和处理单位项目间的 QM 链接 QMTB 检验方法记录 QMTT 检验方法文本 QPAC 检验选择集的目录代码 QPAM 检验选择集目录 QPMK 检验主特性 QPMT 检验主特性文本 QPMZ 分配表检验方法/主…

QM法化简C语言程序,QM基础教程

中文翻译教程首发CSDN,转载请标明出处:http://www.voidcn.com/article/p-qbuyghua-bpr.html NOTE:本中文教程相对官方原版教程,删减了Building Blinky on Windows/Linux 这章,读者可以参考我的另外一篇博文《使用QM的外部工具功能编译代码》中gcc的例子,其次增加了Add Free…

CSS---CSS面试题

目录 1.盒模型 2.offsetHeight /clientheight/scrollHeight 3.left与offsetLeft 4.对BFC规范的理解 5.解决元素浮动导致的父元素高度塌陷的问题 6.CSS样式的先级 7.隐藏页面元素 8.display: none 与 visibility: hidden 的区别 9.页面引入样式时&#xff0c;使用link与import有…