上帝视角 | QPC代码框架是什么样的?
共 2933字,需浏览 6分钟
·
2021-05-10 15:15
关注、星标公众号,直达精彩内容
来源:技术让梦想更伟大
作者:李肖遥
本文介绍一些QP的代码结构以及特点,帮助我们对QP的代码框架有一定了解。
QP/C代码框架
打开QPC代码路径,其目录与文件如下:
doxygen
里面包含了一些图片和代码片段。
examples
包含了很多例子,可以演示各种QP/C功能。每个示例项目都有具体操作描述,而且都是完整的工作项目,并且带有正确的预配置工具,例如编译器选项,链接器脚本,调试器设置等,同时也提供单元测试支持。
include
平台无关的QP/C API接口。
ports
继承好了很多平台的端口,可以适应各种操作系统,处理器体系结构和编译器,并且QP/C框架是从头开始设计的,以使移植变得容易。
qep/qf/qk/qs
包含了平台一些独立的代码。
qpc帮助文件 这个qpc.chm 真的很好,是一个不错的学习的教程。
QP/C框架的分层结构
如下图所示,QP/C框架从上到下包含了活动对象、板级支持软件包BSP、QS软件追踪系统、QEP分层事件处理器、QF活动对象框架、QV协作内核、QK抢占式非阻塞内核、QXK抢占式阻塞内核以及目标硬件。
我们来看看这些QPC框架的组成部分是什么,以及有什么作用,又是怎么协调合作的。
QEP Hierarchical Event Processor
QEP是一种通用的兼容UML的事件处理器,可以在可读性强的ANSI-C中对UML状态机进行编码 ,QEP状态机实施策略的特点是可追溯性,可以使每个状态机元素精确的追溯到代码上。
QEP完全支持分层状态嵌套,这是在许多状态之间重用行为的基本机制,而不是重复相同的动作并一遍又一遍地转换。
对事件驱动系统进行编程的主要挑战是,确定响应给定事件而执行的适当操作。通常,这些动作由两个因素决定:事件的性质和当前的上下文(即,涉及系统的过去事件的顺序)。
QEP的代码包含文件:
QF Active-Object Framework
QF是一个轻量级的,事件驱动的活动对象框架,专门为实时嵌入式(RTE)系统设计。
实时嵌入式框架(RTEF)提供了事件驱动的基础结构,用于基于实时内核(RTOS内核)执行活动对象,以确保确定性的实时性能。而且也比比传统的RTOS小,具体对比如下:
这个框架的主要任务是保证每个活动对象的线程安全,从运行到完成的事件处理。它包含了直接的事件传送,发布-订阅的事件转发,事件队列,时间事件等等。
QF的代码包含文件:
QV Cooperative Kernel
QV是一个简单的协作内核,该内核始终一次处理一个事件,直到完成为止,并在处理每个事件后对活动对象执行基于优先级的调度。
QV内核是隐式合作
的,因为活动对象不需要显式产生CPU,而仅在事件处理完成后返回到QV调度程序。由于状态机中事件处理的持续时间很短,因此简单的QV内核通常足以满足许多实时系统的需求,这是执行活动对象的最快、最小和最容易理解的方式。
在任何活动对象的每个RTC步骤之后,将使用QV调度程序来选择要执行的下一个活动对象,QV调度程序始终选择事件队列中优先级最高的活动对象。
然后,QV调度程序从此队列中提取下一个事件,并将其分派到与活动对象关联的状态机上。状态机运行到结束,然后QV调度程序继续运行并且循环重复,如下图所示:
由于状态机总是在每个RTC步骤之后返回到QV调度程序,因此可以使用单个堆栈来处理所有状态机。QV调度程序还可以非常容易地检测到所有事件队列何时为空,此时它可以调用空闲回调,以使应用程序将CPU和外围设备置于低功耗睡眠模式。
鉴于其简单性,可移植性和低资源消耗等优点,我们可以有序执行这些活动对象。该调度程序的线程级响应是整个系统中最长的RTC步骤,但是由于事件驱动的活动对象不会阻塞,因此RTC步骤往往很短(通常只有几微秒)。
此外,通常可以通过将事件发布到自身并返回(“提醒”状态模式)来将较长的RTC步骤分解为更短的部分。然后,自发布事件触发了更长处理的继续。
QV的代码包含文件:
QK Preemptive Non-Blocking Kernel
QK是一种超快的、抢占式的、基于优先级的单栈实时内核,并且始终确保CPU执行最高优先级活动对象,在执行的时候,不像传统的RTOS内核那样无休止的循环,而是将事件作为一键式函数调用来处理。
如果新事件的优先级高于当前处理的事件,QK内核仍然允许这些单次事件处理功能相互抢占,类似于优先级中断控制器允许中断相互抢占。
只有两种情况可以导致准备更高优先级的线程:
当低优先级线程将事件发布到高优先级线程时,内核必须立即挂起低优先级线程的执行并启动高优先级线程。这种类型的抢占称为 同步抢占
,因为它与将事件发布到线程的事件队列中同步发生。
当中断向比被中断线程高优先级的线程发布事件时,内核必须开始执行高优先级的线程,而不是恢复低优先级的线程。这种类型的抢占称为 异步抢占
,因为它可以异步发生,只要不显式禁用中断即可。
QK的代码包含文件:
QXK Preemptive Blocking Kernel
QXK是一个小的、可抢占的、基于优先级的双模式阻塞内核,它执行诸如QK内核之类的活动对象,但也可以执行传统的阻塞线程,在这方面与常规RTOS(实时操作系统)完全相同。
QXK专为将事件驱动的活动对象与传统的代码混合而设计,可用于硬实时系统,支持基本线程,所有基本线程都嵌套在同一堆栈上,因此减少了堆栈使用量。
基本线程的另一个优点是,从基本线程切换到另一个基本线程只需要激活基本线程,这比QXK还支持的扩展线程所需的完整上下文切换要简单得多,而且速度也更快。
下图显示了QXK内核中引入的主要类以及它们与QP框架类的关系。
QXK的代码包含文件:
QS Software Tracing System
QS是软件追踪系统,使开发人员能够以最少的目标系统资源监视实时事件驱动的QP应用程序,而且无需停止或显着降低代码速度。QS是用于测试,故障排除和优化QP应用的理想工具。QS甚至可以用于支持产品制造验收测试。
QP/Spy软件跟踪系统的结构如下图:
QS的代码包含文件:
总而言之
QPC的目标硬件位于底部,它上方的板级支持软件包(BSP)提供对板级特定功能的访问,而实时内核(QV,QK,QXK或常规的第三方RTOS)为多任务处理提供了基础。
基于这些服务,活动对象框架(QF)提供了事件驱动的基础结构,用于执行活动对象,并且确保线程的事件驱动的安全。
最后,事件处理器(QEP)实现了基于UML状态图的分层状态机,顶层是由松散耦合的活动对象组成的应用程序级代码。
嵌入式编程专辑 Linux 学习专辑 C/C++编程专辑 Qt进阶学习专辑
关注我的微信公众号,回复“加群”按规则加入技术交流群。
点击“阅读原文”查看更多分享。