ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

当单片机遇上状态机(二) 为什么QP难以入门?

2021-12-27 17:02:52  阅读:208  来源: 互联网

标签:QP 单片机 总线 Actor 嵌入式 状态机 面向对象 设计模式


非常抱歉,上次的博客发表完以后,就中断了。不少网友在网上揶揄我。我当然没忘记我的承诺,只是前段时间事情多,耽误了。上次的《QP的入门》一篇,发表在网上后,有个网友的回复给我留下了深刻印象:

qingfeng_ling
这是刚开始给个大体的框架吗,还是已经开始正式讲解了,要是正式讲解的话,我觉得还是有点深了,也可能我太菜[捂脸]
学习者阿曼酱回复qingfeng_ling
你不是一个人[捂脸]

这说明,《QP的入门》一文,写的还是不够浅显明了,有些网友没有成功的由此文入门QP。我用了QP很多年了,尽管我在写博文的时候,很用心的揣摩初学者的心情,但也难免按摩的不到位,还是把一些不必要的概念引入进来。但是,除了上述原因外,我觉得可能还有一些其他的原因,有必要写一下,说清楚,作为《QP入门》一文的补充。

QP涉及到了太多与传统的嵌入式编程思维不同的编程思想。例如,面向对象的C编程,Actor模型,事件总线,发布-订阅模式,设计模式,RTC等等。这些概念,无论是传统的前后台的编程,还是RTOS编程中,都是不曾涉及的概念。QP实际上是将PC上的某些编程技术引入了进来。比如,Actor模型,是Erlang语言内置的并发模型;面向对象的C编程,尽管应用广泛,但对于大部分的嵌入式工程师来说,还是比较陌生;事件总线或者消息总线,在物联网、机器人或者分布式领域,会有所涉及(比如ROS、MQTT和微软的COM编程)。这些概念,都要求QP的学习者,要事先掌握,或者在QP的学习中,同步掌握。如果没有理解这些概念,在QP学习中,会感觉非常困惑,因为它颠覆了你的之前的固有思维。

面向对象的C编程

很多嵌入式工程师,对C语言的理解,还是停留在谭浩强的《C程序设计》一书的水平上,认为C语言是一门面向过程的语言,因此只能写面向过程的程序,如果要写面向对象的程序,只能用C++、Java、C#才行。还有一部分工程师,他们是了解OOPC(面向对象的C编程)的,但思想局限在Lwoopc等面向对象的框架上,注重面向对象的形式,要想C++等语言靠拢,而不注重面向对象的思想。

在这个问题上,我的建议是,看官方文档,看优秀源码(RT-Thread设备框架、STM32标准库)!QP有一份官方的技术文档,《》,就是专门介绍入门OOPC的,完全可以借鉴。另外,有几个源代码,是非常严格的OOPC实现,我最推荐的是RT-Thread的设备框架。为什么是设备框架,而不是它的内核源码?因为面向对象的三大特性,封装、继承和多态,设备框架都有涉及到,而内核代码,仅仅是涉及到了封装与继承。

Actor模型

关于对Actor模型的说明,我推荐两本书《七周七并发模型》和《程序员修炼之道:通向务实的最高境界》(我可不是卖书的,哈哈)。
《七周七并发模型》一书最大的意义在于,它告诉你多任务的本质是什么。并发有多种实现方式,不仅仅是线程与锁模型(多任务)一种。它会将嵌入式工程师们,从【多任务是实现并发的唯一手段】的思想禁锢中解放出来,让你开始关注在计算机和软件发展的历史长河里,出现多很多种并发模型,而线程与锁(多任务)只是非常普通的一种,让你开始意识到协程是怎么回事,线程又是什么,Actor是啥,CSP模型有是啥?
《程序员修炼之道》一书的并发的部分,从另外的角度上,阐述了Actor模型和线程与锁模型,尽管篇幅不大,却非常切中要害。

事件总线

事件总线(Event Bus)、消息总线(Message Bus)和软件总线(Software Bus)的概念,应用不多,资料也不多,很多应用,都是把它集成在软件内部,不对外开放,因此我们不太能感受到。在QP里,对这个概念也仅仅出现在很少量的文档里,一笔带过。如果想深入了解,机器人领域的小伙伴们,肯定都知道ROS,它有一个分布式消息机制,就是一个典型的分布式消息总线;物联网领域的小伙伴,可以用一下MQTT,这也是一个的分布式消息总线;如果大家对鸿蒙操作系统感兴趣,它的系统底层,就有一个分布式软总线。当然,QP的事件总线,并不是分布式的,但它山之石,可以攻玉,对其他类似技术的了解,可以加深对事件总线概念的理解。

设计模式

有很多书和资料,都在介绍设计模式,但大多针对的是C++、Java、C#等可以面向对象的语言。对于嵌入式工程师来说,设计模式的应用是陌生的。我觉得有三大原因:一是设计模式要以面向对象为基础,长期以来嵌入式应用过于简单,没有面向对象的需求,面向过程即可应对;二是嵌入式的代码规模太小,根本不需要使用设计模式来应对需求的变化,三是大家一直在讨论的23种经典设计模式,有不少并不适用于嵌入式软件,而嵌入式中,形成的很多设计模式,相对来说比较简单,没有对主流软件界形成影响。举一个例子,按键去抖动,就是一个典型的嵌入式设计模式,但很多工程师只知道这个“套路”,并没有把它抽象到设计模式的高度。

有几种嵌入式中常见的设计模式以及学习资料,列举在这里:单例模式、工厂模式、命令模式、适配器模式、状态模式、观察者模式、发布-订阅模式、状态模式、去抖动模式、黑板模式、中断模式、轮询模式、队列模式、临界区模式等等。后续会专门讲解《设计模式》。

RTC原则

要想理解RTC原则,需要了解两个前置知识,一是Actor模型对事件是怎么处理的,二是协程。
Actor模型中,每一个Actor一次只能处理一个事件。可能网友问了,难道还能处理多个事件?是的,当一个队列里的事件都在一个线程里处理的时候,它就只能一次处理的一个事件;二当处理一个队列的事件是一个线程池的时候,多个事件同时被分配了多个线程,这时可能会出现同时处理的情况。当一个Actor处理完当前事件,才能进行下一个事件的处理时,不管这个事件处理的过程会不会被其他的Actor打断,这个事件处理过程都是RTC的。RTC有很强的优势,也带来了一些坏处,我们在后续的博客里进行讨论。
当QP框架使用了QV的内核来调度时,每一个Actor作为一个调度单元,就从线程退化为了协程。协程的QP有着独特而有趣的优势,如果你的实时性要求没那么大的话(10ms的误差可以接受),而又完全不设计我非常推荐使用QV内核来进行嵌入式开发。它能让你的程序非常非常稳定可靠,这个问题我们会在后续的博客中进行详细阐述。

总结

综上所述,QP有一定的学习曲线,最关键的是把握QP的前置知识,理解QP的思维。下次博客会直接讲QP的哲学思想。

标签:QP,单片机,总线,Actor,嵌入式,状态机,面向对象,设计模式
来源: https://blog.csdn.net/moderncode/article/details/122175926

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有