搜索
bottom↓
回复: 42

STM32F4移植量子平台(QP)教程

  [复制链接]

出0入0汤圆

发表于 2014-2-2 20:33:17 | 显示全部楼层 |阅读模式
     
         斗胆以教程作为本文标题,经过两天对状态机的学习与理解后,楼主今天完成了量子平台的移植。量子平台是为嵌入式处理器定制的轻量,事件驱动,功能类似于RTOS的组件。
         本文将分为三个部分:1:准备工作,2:具体移植过程 3:如何用QM编写可在QP上运行的状态机
         
准备工作:
进入QP官网 http://www.state-machine.com/downloads/index.php下载QP 组件的代码与例程,即Baseline Code,然后再下载QM 即状态机建模工具。本文选用的是移植QP/C,当然,QP/C++也是适用于各类嵌入式处理器的,不用过于担心C++与C所谓的效率问题,优化我们的代码才是对效率最有利的。
                  
                   本文假设读者已经安装完毕KEIL以及拥有一台STM32 F4开发板,如果没有的话可以使用KEIL的软仿功能。
具体移植过程:
1.      库文件
进入qpc所解压出来的目录,ports\arm-cm\vanilla\arm_keil

将make_Cortex-M4.fp.bat更名为,make_Cortex-M4.fp.txt.打开它,搜索ARM_KEIL,找到这句话
if"%ARM_KEIL%"=="" set ARM_KEIL="默认目录"将默认目录改成KEIL软件安装目录下的ARM\ARMCC示例:楼主的是D:\Keil_5\ARM\ARMCC,更改完毕后,名字改回bat.运行它,然后进dbg目录取出库文件,加入KEIL的工程。

编译,如果你编译失败了,不要慌。右键单击该文件,设置属性,将File Type 更改为LIB,楼主今天在这上面折腾2个多小时……

如果编译成功,那么这一步就完成啦~
2.      移植BSP:进入QPC目录下的examples\arm-cm\vanilla\arm_keil\blinky_ek-tm4c123gxl,将该文件下的BSP.c与.h复制到我们的KEIL工程。需要修改的地方不是很多,原程序是不是基于STM32F4 的,所以将程序改为适合F4的即可,楼主不再赘述。值得一提的是如果要在状态机增加事件,应该将与事件有关的中断加入KernelAwareISRs这个枚举类型。并通过NVIC_SetPriority(中断服务名称,KernelAwareISRs中该中断的名称);实现BSP与QP的对接。
还有需要注意的是SysTick_Config中的ROM_SysCtlClockGet() 用 SystemCoreClock代替即可。
3.      初试QP:做完前两步后我们就可以尝试一下QP的基本效果了,将examples\arm-cm\vanilla\arm_keil\blinky_ek-tm4c123gxl下的blinky.c加入工程。将main函数部分的两个参数给去掉,不然启动代码是跑不进main函数的。然后,将qp目录下\include 头文件与ports\arm-cm\vanilla\arm_keil中的头文件复制到工程中,加入包括目录。编译后就可以下载程序,仿真了。看到两个断点隔0.5s 轮流执行就说明成功啦

3.如何用QM编写可在QP上运行的状态机        
                   这一部分才是真正重要的,我们用量子平台就是为了方便的设计状态机并用到项目中。本文以一个最简单的时间事件状态机为例。
在QM中建立模型,不需要基于模板。

右击这个小球,创建一个包。

为包命名,并将stereotype设定为component.

在包内创建一个类,为类命名,设置为QActive类型。

在类中创建一个属性,类型设定为QTimeEvt

现在开始画状态机,这个。。。大家自己琢磨下怎么画,要贴太多图了。。。贴个结果。。。

注意,在每个状态的属性里,将entry动作进行的过程填在

状态机解决后,再创建一个C文件,楼主该C文件中的代码如下
  1. #include "qp_port.h"
  2. #include "bsp.h"
  3. enum BlinkySignals {
  4. TIMEOUT_SIG = Q_USER_SIG,
  5. MAX_SIG
  6. };
  7. $declare(TASK::LCD)
  8. $define(TASK::LCD)
  9. static LCD LcdFir;
  10. QActive *TASK_LCD = &LcdFir.super;
  11. void LCD_ctor(LCD * const me) {
  12. QActive_ctor(&me->super, (QStateHandler)&LCD_initial);
  13. QTimeEvt_ctorX(&me->TimeEvt, &me->super,TIMEOUT_SIG, 0U);
  14. }
  15. int main() {
  16. static QEvt const *LCD_queueSto[10];
  17. LCD_ctor(&LcdFir);
  18. QF_init();
  19. QActive_start(TASK_LCD, 1,
  20. LCD_queueSto, Q_DIM(LCD_queueSto),
  21. (void *)0, 1024, (QEvt *)0);
  22. return QF_run();
  23. }
复制代码


通过这个编译按钮就可以生成C代码了
拍一下楼主嵌入C代码后实现的效果。
这是初始界面:

状态A(5秒切换到状态B):
状态B(5秒切换到状态A):

借助QP,我们可以解决很多比较复杂的逻辑状态问题。楼主目前也只做了最简单的应用,准备接下来实现配合触摸的多菜单HMI,这个如果不借助自动化的状态机工具手写太麻烦了。期待和大家交流,楼主是学生,时间比较大把。 :)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出130入129汤圆

发表于 2014-2-2 20:43:00 | 显示全部楼层
我在库文件设置地方浪费一天时间,.a格式的默认是汇编,一直没发现,总说编译错误,早上改回库文件就搞定了。

出0入0汤圆

 楼主| 发表于 2014-2-2 20:43:42 | 显示全部楼层
68336016 发表于 2014-2-2 20:43
我在库文件设置地方浪费一天时间,.a格式的默认是汇编,一直没发现,总说编译错误,早上改回库文件 ...

哎,同感

出0入0汤圆

发表于 2014-2-2 21:29:34 | 显示全部楼层
F407还是F29?KEIL的版本?
谢谢。

出0入0汤圆

 楼主| 发表于 2014-2-2 21:33:24 | 显示全部楼层
Excellence 发表于 2014-2-2 21:29
F407还是F29?KEIL的版本?
谢谢。

F407哦 :)

出0入0汤圆

 楼主| 发表于 2014-2-2 22:36:49 | 显示全部楼层
哎,第一个技术帖,木人顶,自顶一下

出0入0汤圆

发表于 2014-2-2 23:05:45 | 显示全部楼层
LZ很厉害!火钳刘明

出0入0汤圆

发表于 2014-2-2 23:20:28 | 显示全部楼层
谢谢分享~~

出0入0汤圆

发表于 2014-2-2 23:31:05 | 显示全部楼层
顶一下汗,一起努力。

出0入9汤圆

发表于 2014-2-2 23:42:11 | 显示全部楼层
LZ厉害。
先标记一下。

出130入129汤圆

发表于 2014-2-3 07:44:59 | 显示全部楼层
本帖最后由 68336016 于 2014-2-3 07:48 编辑

QP怎么自定义事件?楼主清楚不?
闪灯例子的TIMEOUT_SIG事件,Q_ENTRY_SIG事件都是QP自带的,但没留意到如何自定义事件(比如按键对应一个事件)。
其它的例子只看到定义 几个事件,但什么时候才产生这些事件却没看到。


还有 想放主循环执行的语句用QP后应该放在哪里?
QP里面好像用        return QF_run()  接管了,难道要自己重新定义 QF_run()  

出0入0汤圆

 楼主| 发表于 2014-2-3 10:01:51 | 显示全部楼层
68336016 发表于 2014-2-3 07:44
QP怎么自定义事件?楼主清楚不?
闪灯例子的TIMEOUT_SIG事件,Q_ENTRY_SIG事件都是QP自带的,但没留 ...

今天起来比较晚,才烧了早点吃掉,你的问题需要比较详细的回答,估计折腾到下午才能搞定,别急 :)

出0入0汤圆

发表于 2014-2-3 10:19:58 | 显示全部楼层
重量级的好资料!!!

出0入0汤圆

 楼主| 发表于 2014-2-3 10:36:42 | 显示全部楼层
68336016 发表于 2014-2-3 07:44
QP怎么自定义事件?楼主清楚不?
闪灯例子的TIMEOUT_SIG事件,Q_ENTRY_SIG事件都是QP自带的,但没留 ...

为了解决我们先来些预备知识
1.量子平台(QP)包括四个部分 QE:事件处理器,QF:事件驱动架构 QK:抢占式内核(在我们现在的程序中还没用到) QS:软件追踪(SPY 间谍)我们现在也没用到。因此 QF_run()就启动了QP这个事件驱动的状态机了。
2.QP的 XXX_ctor函数用于注册事件

关于QP如何自定义事件:QP自定义事件可以通过自己码代码完成,但是既然QP提供了QM这一强大的软件,我们在添加事件也好,状态也好,使用QM是良策。

这一次楼主自己做了3个信号量,分别是TimeEvtA,B,C


以下是楼主的关联代码。
  1. #include "qp_port.h"
  2. #include "bsp.h"

  3. enum BlinkySignals {
  4.     TIMEOUTA_SIG = Q_USER_SIG,
  5.     TIMEOUTB_SIG,
  6.     TIMEOUTC_SIG,
  7.     MAX_SIG
  8. };

  9. $declare(TASK::LCD)
  10. $define(TASK::LCD)

  11. static LCD LcdFir;
  12. QActive *TASK_LCD = &LcdFir.super;

  13. void LCD_ctor(LCD * const me) {
  14.    
  15.     QActive_ctor(&me->super, (QStateHandler)&LCD_initial);
  16.     QTimeEvt_ctorX(&me->TimeEvtA, &me->super,TIMEOUTA_SIG, 0U);
  17.     QTimeEvt_ctorX(&me->TimeEvtB, &me->super,TIMEOUTB_SIG, 0U);
  18.     QTimeEvt_ctorX(&me->TimeEvtC, &me->super,TIMEOUTC_SIG, 0U);
  19. }



  20. int main() {
  21.     static QEvt const *LCD_queueSto[10];
  22.     BSP_init();
  23.     LCD_ctor(&LcdFir);
  24.     QF_init();

  25.     QActive_start(TASK_LCD, 1,
  26.                   LCD_queueSto, Q_DIM(LCD_queueSto),
  27.                   (void *)0, 1024, (QEvt *)0);
  28.     return QF_run();
  29. }
复制代码

以下是初始化状态时的代码



可以看出来,创建,使用一个信号量在于三步:
1.在活动中创建一个信号量(attr)
2.通过QTimeEvt_ctorX将该信号量与事件关联。
3.通过QTimeEvt_armX将该事件与状态机关联。

关于你的按键事件问题:由于按键不是TimeEvt 楼主昨天是基于TimeEvt做的,所以今天做这个实验比较把稳,其它的事件楼主在研究出结果后第一时间发上来。




第二个问题:如预备知识所说,QF_run()  就是启动了QP的事件驱动的任务机制,我们不需要改它们的底层,而是用好这个架构。
解决方法一:创建一个空闲状态,当没有特殊事件发生时,就在该状态中跑你需要循环的代码。
解决方法二:将状态机按照时间机制来运行,每个循环中分配特定的时间执行希望循环的代码。
解决方法N:待大家一起探讨


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-2-3 10:53:21 | 显示全部楼层
码一个···支持楼主,期待后续

出130入129汤圆

发表于 2014-2-3 16:25:23 | 显示全部楼层
E-WALKER 发表于 2014-2-3 10:36
为了解决我们先来些预备知识
1.量子平台(QP)包括四个部分 QE:事件处理器,QF:事件驱动架构 QK:抢占 ...

比如有按键扫描,按我的习惯还是放中断函数里面去处理方便些,要是用QP的一个状态来扫描按键,感觉挺奇怪的

出0入0汤圆

 楼主| 发表于 2014-2-3 18:02:27 | 显示全部楼层
68336016 发表于 2014-2-3 16:25
比如有按键扫描,按我的习惯还是放中断函数里面去处理方便些,要是用QP的一个状态来扫描按键,感觉挺奇怪 ...

肯定可以做到的,这个属于事件的一种,按照UML标准,触发事件可以没有参数的,也就是可以没有状态量,如果我理解的没错的话
过段时间试一试就知道了 :)

出0入0汤圆

发表于 2014-2-3 20:23:38 | 显示全部楼层

出0入0汤圆

发表于 2014-2-5 08:34:08 | 显示全部楼层
推楼主的学习精神

出0入0汤圆

发表于 2014-2-16 22:01:29 | 显示全部楼层
···支持楼主,期待后续

出0入0汤圆

发表于 2014-4-6 23:21:34 | 显示全部楼层
MARK,支持楼主

出0入0汤圆

发表于 2014-4-7 11:50:03 | 显示全部楼层
楼主继续啊,我们支持你

出0入0汤圆

发表于 2014-4-10 09:15:12 | 显示全部楼层
火钳流明,楼主牛人,期待下一次连载!

出0入0汤圆

发表于 2014-5-14 11:42:58 | 显示全部楼层
不懂帮顶

出0入0汤圆

发表于 2014-6-7 08:36:40 | 显示全部楼层
学习中。。。。

出0入0汤圆

发表于 2014-6-30 00:13:54 | 显示全部楼层
顶顶, 希望能看到更多的好东西

出0入0汤圆

发表于 2014-8-14 17:05:01 | 显示全部楼层
关注,,,,感谢分享,能形成一个文档最好了,

出0入0汤圆

发表于 2014-8-14 19:25:51 | 显示全部楼层
好贴,顶一个

出0入0汤圆

发表于 2014-8-19 20:41:20 | 显示全部楼层
mark下,量子平台(QP)

出0入4汤圆

发表于 2014-8-19 20:52:15 | 显示全部楼层
欲懂还学

出0入0汤圆

发表于 2014-10-28 18:30:09 | 显示全部楼层
多谢楼主分享,对于入门来说,这资料太宝贵了!

出0入0汤圆

发表于 2014-10-29 11:51:24 | 显示全部楼层
楼主,请指教一下,BSP.c和BSP.h如何修改才可以应用到STM32F4中,谢谢

出0入0汤圆

发表于 2015-2-14 22:02:19 | 显示全部楼层
想移植QPC到cortexM0的单片机上 用KEIL开发环境,不知道这个汇编库去哪儿找,请问楼主知道吗?

出0入0汤圆

发表于 2015-2-15 09:24:29 | 显示全部楼层
持续关注中.......没有移植过  不过使用官网移植msp430以及在项目中使用了年把

出0入0汤圆

发表于 2016-3-21 15:23:49 | 显示全部楼层
请问楼主 你现在学的怎么样了?问一下可不可以分享 有关这个的学习的资料啊

出0入0汤圆

发表于 2016-3-21 15:41:29 | 显示全部楼层
两年前就在用了,很好用。可以移植在各种rtos上面,也可以直接移植到mcu。QK有调度功能,功能比rtos弱但是效率高。

出0入4汤圆

发表于 2016-7-26 13:58:01 | 显示全部楼层
楼主太牛了,两天就搞定了移植!膜拜大神!

出0入0汤圆

发表于 2016-7-27 10:44:00 | 显示全部楼层
标记一下,看着好犀利

出0入0汤圆

发表于 2016-10-24 10:55:24 | 显示全部楼层
赞一个,最近在学习Qp

出0入0汤圆

发表于 2016-10-25 22:58:52 | 显示全部楼层
最近才发现有这个好文章

出140入8汤圆

发表于 2016-10-31 16:32:47 | 显示全部楼层
正好要写比较复杂的状态机,最近才发现这个东西,现在已经更新到5.73了,下载所有东西已经安装了,和以前的版本貌似用法有点不一样了...

出0入0汤圆

发表于 2017-7-4 08:39:38 | 显示全部楼层
学习一下,谢谢

出0入0汤圆

发表于 2019-1-10 11:43:30 | 显示全部楼层
谢谢分享
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 20:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表