使用visual studio 2013建立一个基于QPC的简单工程

本文介绍如何在VS2013上配置基于UML状态图框架QPC的简单工程,以便进行仿真调试。包括新建工程、设置环境变量、添加包含目录等步骤。

转载请标明出处:http://blog.youkuaiyun.com/chenbb8/article/details/52330032
注:本文的软件环境是QPC5.6.5+QM3.3+vs2013+WIN7

在上篇文章《使用QM的外部工具功能编译代码》中,介绍了在PC机上如何使用gcc对单文件进行编译。本文则是通过VS2013建立一个基于UML状态图框架QPC的简单的工程,方便在没有嵌入式目标版的时候提前通过vs2013进行初步的仿真调试。
另外QPC_5.3.1中的WIN32下的VC例子也可以在通过vs2013打开,自动转换成vs2013的工程后,通过本文的相关设置就能再次运行了。
本文利用是《QM™ Tutorial》中生成的单文件blinky.c,但同样可以推广到多文件上。

  • 建立工程

首先新建工程,打开VS2013的FILE菜单->NEW->project…,在弹出窗口中填入工程名字和目录。
这里写图片描述

确定后,在接卸来的application set窗口中,只选择console application一个选项。然后点击finish。
这里写图片描述

接下来将Solution Explorer中Source Files文件夹的两个cpp文件删掉,然后右击Source Files->Existing Item..添加之前使用QM生成的blinky.c。

  • 设置环境变量

下一步将会用到QPC的相对目录,如果是使用绝对目录,可以跳过这一步。
回到桌面,鼠标右击”我的电脑”->属性->高级系统设置->高级->环境变量->系统变量->Path。在Path中,添加QPC的目录,注意目录和目录之间使用’;’号分隔。
这里写图片描述

  • 添加包含目录

回到VS2013中,在Solution Explorer中右击工程名字blinky->propertis->configuration properties->vc++ directories->include directories->edit,在弹出窗口中添加:

$(QPC)\include
$(QPC)\ports\win32

如果使用的是QPC5.3.1,还要添加$(QPC)/ports/win32/vc,具体根据调试信息查找添加

然后在上面打开的blinky Property窗口下->configuration properties->VC++ directories->Library Directories->edit下添加:

$(QPC)\ports\win32\Debug

如果使用的是QPC5.3.1,则是添加$(QPC)\ports\win32\vc\Debug
这里写图片描述

最后在上面打开的blinky Property窗口下->configuration properties->Linker->Input->Additional Dependencies->Edit下添加qp.lib
这里写图片描述
设置完毕。

好的,开始仿真调试吧
这里写图片描述

qp官网下载qpc,移植到stm32f103单片机,在正点原子战舰V3开发板上实验成功 qp搭建步骤重要提示: #define RED_QUEUE_LEN 3 #define BLUE_QUEUE_LEN 3 #define TACKER_EVENT_POOL_LEN (RED_QUEUE_LEN + BLUE_QUEUE_LEN) static QEvt const * l_redQueueSto[RED_QUEUE_LEN]; //事件队列 static QEvt const * l_blueQueueSto[BLUE_QUEUE_LEN]; //事件队列 static LedEvt LedEvtPoolSto[TACKER_EVENT_POOL_LEN]; //事件池 static QSubscrList SubSrcSto[MAX_PUB_SIG]; //订阅列表 typedef struct LedEvtTag LedEvt; //定义事件结构 struct LedEvtTag{ QEvt super_; uint16_t uiParaH; uint16_t uiParaL; }; //定义信号枚举 enum LedSignals{ START_SIG = Q_USER_SIG, KEY0_SIG, KEY1_SIG, KEY2_SIG, KEYUP_SIG, ALL_OFF_SIG, ONLY_BULE_SIG, ONLY_RED_SIG, ALL_ON_SIG, MAX_PUB_SIG }; void PublishLedEvt(uint16_t uiSig, uint16_t uiParaH, uint16_t uiParaL) //发布事件函数 { LedEvt* peTacker; peTacker = Q_NEW(LedEvt, uiSig); peTacker->uiParaH = uiParaH; peTacker->uiParaL = uiParaL; QF_publish_((QEvt*)peTacker); } QF_init(); //时间事件列表、活动对象查找表、优先级集合 QF_psInit(SubSrcSto, Q_DIM(SubSrcSto)); //初始化事件池 QF_poolInit(LedEvtPoolSto,sizeof(LedEvtPoolSto),sizeof(LedEvtPoolSto[0])); RedLed_Start(uiPrio++, l_redQueueSto, Q_DIM(l_redQueueSto), 0, 0); //建立活动对象 BlueLed_Start(uiPrio++, l_blueQueueSto, Q_DIM(l_blueQueueSto), 0, 0); /////////////////////////////////////////////////// typedef struct RedActiveTag RedActive; //构建一个活动对象活动类型 struct RedActiveTag{ QActive super_; volatile uint16_t RedLedStateNow; uint16_t a; uint16_t b; }; extern RedActive RedLed; RedActive RedLed; void RedLed_Start(uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize) { RedLed_Ctor(&RedLed;); QActive_start_((QActive*)&RedLed;, prio, qSto, qLen, stkSto, stkSize, (QEvt const *)0); //创立活动对象的线程并提醒 QF 开始管理活动对象 } void RedLed_Ctor(RedActive* me) { QActive_ctor(&me;->super_, (QStateHandler)RedLed_Initial); //初始化状态机基础类(成员 super) me->RedLedStateNow = 0; }
QPC(Quantum Platform C)是一种轻量级的事件驱动框架,适用于嵌入式系统和实时应用开发。它提供了一种高效的状态机实现机制,能够帮助开发者构建模块化、可移植性强的应用程序。以下是QPC的基本使用方法和关键步骤。 ### QPC 使用概述 1. **开发环境搭建** 在开始使用 QPC 之前,需要搭建开发环境。通常包括安装编译工具链(如 GCC)、调试工具(如 GDB)、以及必要的 IDE(如 Eclipse 或 VS Code)。此外,还需获取 QPC 的源代码并配置相关的构建系统(如 Makefile 或 CMake)。 2. **核心组件理解** QPC 由多个核心组件组成,包括: - **QEP(事件处理器)**:负责事件的分发和处理。 - **QF(事件驱动框架)**:提供事件队列、定时器、线程管理等功能。 - **QK(微内核)**:支持抢占式调度。 - **QS(调试器)**:用于运行时调试和跟踪事件流[^5]。 3. **初始化 QPC 框架** 在应用程序的入口点(如 `main()` 函数),需要初始化 QPC 框架。通常包括以下步骤: - 初始化事件池(Event Pool)以支持事件的动态分配。 - 启动 QF 框架。 - 创建并启动状态机或活动对象(Active Objects)。 示例代码如下: ```c #include "qf.h" #include "my_state_machine.h" int main(void) { // 初始化 QF 框架 QF_init(); // 初始化事件池 static QF_EVENT_POOL_EL_TYPE eventPool[10]; QF_poolInit(eventPool, sizeof(eventPool), sizeof(eventPool[0])); // 创建并启动状态机 MyStateMachine_ctor(); QACTIVE_START(&myStateMachine, 1, NULL, 0, NULL); // 启动 QF 调度器 QF_run(); return 0; } ``` 4. **定义状态机** QPC 使用状态机(State Machine)作为主要的编程模型。开发者需要定义状态机的结构、事件处理函数以及状态转移逻辑。QP 支持层次化状态机(HSM),允许状态嵌套,提高代码的组织性和可维护性。 示例状态机定义如下: ```c typedef struct { QActive super; // 其他成员变量 } MyStateMachine; QState MyStateMachine_initial(MyStateMachine *me, void const *param); QState MyStateMachine_state1(MyStateMachine *me, QEvt const *e); QState MyStateMachine_state2(MyStateMachine *me, QEvt const *e); void MyStateMachine_ctor(void) { MyStateMachine *me = (MyStateMachine *)QActive_getMe(); QActive_ctor(&me->super, (QStateHandler)&MyStateMachine_initial); } QState MyStateMachine_initial(MyStateMachine *me, void const *param) { // 初始状态处理 return Q_TRAN(&MyStateMachine_state1); } QState MyStateMachine_state1(MyStateMachine *me, QEvt const *e) { switch (e->sig) { case Q_ENTRY_SIG: // 进入 state1 的处理 return Q_HANDLED(); case SOME_EVENT_SIG: // 处理某个事件 return Q_TRAN(&MyStateMachine_state2); default: return Q_SUPER(&QHsm_top); } } QState MyStateMachine_state2(MyStateMachine *me, QEvt const *e) { switch (e->sig) { case Q_ENTRY_SIG: // 进入 state2 的处理 return Q_HANDLED(); default: return Q_SUPER(&QHsm_top); } } ``` 5. **事件处理与调度** QPC 使用事件驱动的方式处理任务。事件可以是外部中断、定时器触发、或其他状态机发送的消息。事件被放入队列中,由 QF 调度器分发给相应的状态机进行处理。 6. **平台适配与移植** QPC 可以运行在多种平台上,包括裸机系统、RTOS(如 FreeRTOS、uC/OS)或 Linux。为了在特定平台上使用 QPC,需要实现以下接口: - `qf_port.c`:提供平台相关的底层支持,如线程创建、定时器管理等。 - `QF_onStartup()` 和 `QF_onCleanup()`:用于初始化和清理平台资源。 - 事件池的配置与管理[^4]。 7. **调试与优化** 使用 QS(Quantum Spy)模块可以进行运行时调试,查看事件流、状态转换、线程调度等信息。这对于优化系统性能和排查问题非常有帮助。 ### 注意事项 - **资源管理**:合理配置事件池大小,避免内存不足或浪费。 - **实时性**:确保事件处理函数尽可能高效,避免长时间阻塞。 - **可移植性**:尽量将平台相关代码隔离在 `qf_port.c` 中,以便于移植到其他平台[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值