作者:ming_mei
前言
前些日子在微信上看到李肖遥的公众号,里面系统讲述了QP框架,我很有感触。我用QP框架很多年了,一开始是使用QM和QPC ,到后来抛弃了QM,直接使用QPC裸写程序,到后来自己写
状态机框架。
可以这么说,QP框架引导了我的技术成长。我共享的博文,虽然都以QP为起点进行展开,但很多东西,都是QP官网的资料所没有的。我希望接受大家的意见、建议和批评,相信对我来说,会有更大的提升。
这一系列的博文,称为《当
单片机遇上状态机》系列,暂时先规划以下几篇:
让大家开始使用QP,消除对QP的畏难心理,建立起初步的信心。这一步非常重要。
大家很难理解,自己用switch-case实现状态机,用的好好的,干嘛要用状态机框架。这篇博文,就是为了说明,switch-case状态机,是如何一步一步进化到一个状态机框架的。我们所写的这个状态机框架,和QP之间,到底有着什么关系,有着多少差距。
QM作为一个辅助工具?它的作用是什么?它是怎么生成代码的?它和QP之间是什么关系?在这一篇里,将会做详细介绍。
精通QP,理解其哲学思想非常重要。它的哲学思想是什么样的?是如何体现的?
后续的规划,我希望根据大家的反馈意见而定。我用状态机框架多年,难免做不到换位思考,不能照顾到初学者的感受。希望大家踊跃反馈意见。无论是赞扬还是批评,我都虚心接受。
入门QP
我们学习一个语言,或者一项技术,第一件要做的事情,就是实现一个类似于Hello world的最小程序。在
单片机上,当然就是LED灯的闪烁。不说废话了,先上代码。
代码结构
代码结构,可以在Keil工程中看到,是一个QP的运行最小系统。QP版本使用的是最新的V6.9.3版本。
为了便于大家的学习,我抛弃了官方例程。官方例程有些繁琐,里面还有大量的doxygen格式的注释,对初学者不友好。与官方例程相比,能删掉的部分,全部都删掉了,只留下代码和必要中文注释,目的就是为了最大限度降低大家学习QP的入门门槛,也算是中国特色吧。这四个源码,代码未来我们程序架构的不同层次,以后所有的例程,就是以这个代码结构为基础,进行扩充。
还有一个需要说明的,第一个例程,我并没有使用QM建模工具进行LED状态机的建模和代码生成。QM工具,本质上基于模型的开发方法,是形式化开发方法之一。在软件开发中,这种方法一直饱受争议。这个世界现存的大部分软件框架,是不存在所谓代码生成工具的。目前我对QM等建模工具持保守态度,软件开发还是要回归代码本身,能利用工具,但不要依赖工具。QM工具,我认为是QP框架在营销和商业上的需求推动的。因此,在未来的教程中,我将QM的使用,放在次要位置,主要还直接编程为主,我认为这样才会给大家带来真正的提升。
这四个源码分别是:
-
main.c 包含了硬件的初始化、QP框架的初始化、各状态机模块(暂定称呼,严谨应叫AO模块)的构建,框架的启动等一系列流程。
-
bsp.c 硬件初始化,此处仅包含SysTick的初始化和SysTick中断函数。
-
ao_led.c LED状态机的源码。
-
hook.c QP框架的回调函数的实现,此处都为空函数,暂时不予实现。
-
evt_def.h 事件的定义。QP框架的事件定义,使用枚举实现。个人觉得,事件的定义,如果用字符串实现,更加有利于模块的解耦和对分布式的支持(这个问题可参考后续的博客《将软总线进行到底》)。QP使用枚举来定义事件,个人认为是为了降低RAM和CPU的开销。
-
其他
-
QP源码
-
QP接口代码
-
QP框架对硬件平台或者RTOS的接口源码。
-
MCU相关代码,包含Startup文件、CMSIS相关、固件库相关代码
QP的启动流程
以下代码就是QP框架的启动过程。
#include "qpc.h" // qpc框架头文件
#include "evt_def.h" // 事件定义头文件
#include "bsp.h" // 硬件初始化
#include "ao_led.h" // LED状态机
Q_DEFINE_THIS_MODULE(
"Main") // 定义当前的模块名称,此名称在QS和断言中会使用。
ao_led_t led; // 状态机LED对象
int main(void)
{
static QSubscrList sub_sto[MAX_PUB_SIG]; // 定义订阅缓冲区
static QF_MPOOL_EL(m_evt_t) sml_pool_sto[128]; // 定义事件池
QF_init(); //
状态机框架初始化
QF_psInit(sub_sto, Q_DIM(sub_sto)); // 发布-订阅缓冲区的初始化
QF_poolInit(sml_pool_sto, // 事件池的初始化
sizeof(sml_pool_sto),
sizeof(sml_pool_sto[0]));
ao_led_ctor(
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。