zoukankan      html  css  js  c++  java
  • QP之QF原理

    1.QP简介:

    量子平台(Quantum Platform, 简称QP)是一个用于实时嵌入式系统的软件框架,QP是轻量级的、开源的、基于层次式状态机的、事件驱动的平台。

    QP包括事件处理器(QEP)、轻量级的事件驱动框架(QF)、任务调度微内核(QK)和实时跟踪调试器(QS)四个部分。

    利用QP可以开发出结构清晰的嵌入式应用程序(使用C或C++语言)。
    QP
    图1.QP总体结构

    2.QP之QF简介

    QF是QP的核心,可以把QF理解为软件总线(software bus,SBus)。在这个软件总线上连接着很多的AO和硬件中断服务程序ISR,QF负责事件的存贮、分发和回收等功能,也就是事件驱动。

    QF是一个事件驱动框架。应用程序可以创建事件实例,放到事件池中,并分发事件到相应注册了这个事件的活动对象(状态机,任务)AO中。应用程序可以注册特定的事件,当有事件发生时,QF就会分发事件到AO中。应用程序是由多个AO组成,每个AO可以认为是一个任务。把硬件中断程序也当做AO看待,只是优先级比较高。

    QF量子框架由五个数据结构及操作组成,其数据结构采用了uCOS-II相似的结构。

    9f2f070828381f30e47cb316ab014c086e06f023
    图2.细化的QF总体结构

    3.QF分发事件

    如图 1所示,QF是个软件总线,在这个软件总线上连接着AO和ISR。QF中包含5个主要的数据结构(受uCOS II影响很深,要看一下uCOS II内核)。

    有两种事件的分发方式:

    (1)直接分发事件

    一个AO直接分发事件到另一个AO,就是直接投递事件。这种方式分发事件的AO要知道目标AO。

    使用void QActive_postFIFO(QActive *me, QEvent const *e) 函数分发事件。

    (2)P/S分发事件

    利用QF中的AO订阅事件表,以P/S(Publish-Subscribe出版-订阅)方式分发事件,也就是P/S投递事件。 这种方式分发事件AO不用知道目标AO,QF查找AO订阅事件表就知道把事件分发到什么地方。P/S投递方式减少了AO之间的耦合度。

    使用void QF_publish(QEvent const *e)函数分发事件。

    1ff9d13f2e1bc7db7c1e717e
    图3.QF软件总线和两种投递事件方式

    框架QF包括活动对象AO,每个AO包含一个AO队列(QEQueue)和状态机。QF中还有5个主要的数据结构表,其中有3个AO相关的数据结构:AO订阅事件表,AO队列状态表,AO注册表;有1个事件池QMPool,用于保存事件实例,其它事件都是对这个事件实例的引用;有1个时间事件链表QtimeEvt,用于定时事件处理。图 2是相应数据表与QF和AO的关系。

    c7851ed5042bb4dd51da4bb4
    图4.QF框架及五个数据表

    4.QF运行

    QF运行时,包括的过程有:
    (1)QF初始化;
    (2)AO和ISR产生事件;
    (3)分发事件到AO队列;
    (4)循环调度分派事件到状态机。
    在把事件放到AO队列中时,会置位AO队列状态表相应位;从AO队列中取出事件时,会清零AO队列状态表相应位。总之,放事件到AO队列或从AO队列取事件,都会修改AO队列状态表。

    14b554da063bb7c2b7fd481f
    图5.QF运行过程及数据表关系

    (1)QF初始化
    在QF运行之前,首先要进行初始化,要创建AO、创建事件池、创建AO订阅事件表,创建AO队列等一系统开始工作。

    717f7eec7ddfa5c82f2e21a7
    图6.QF初始化

    (2)AO和ISR产生事件
    在AO或ISR中,用Q_NEW()宏可以创建用户事件实例,并放到事件池中。
    如用 UserEvt *pe = Q_NEW(UserEvt , UserSig1)
    创建了一个用户事件pe。可以分发这个用户事件pe到AO队列中。

    其中,UserEvt是增加了参数的用户自定义事件,它是继承自QEvent,UserEvt定义如下,

    typedef struct UserEvtTag {
    QEvent
    super; /
    继承自QEvent /
    uint8_t parameter;/
    增加的事件参数 /
    } UserEvt;

    UserSig1是用户定义的信号,用枚举来定义,定义如下,

    enum UserSignals {
    User1SIG = QUSER_SIG,/
    用户定义第一个信号 /
    User2_SIG, /
    第二个信号 /
    User3_SIG, /
    第三个信号 /
    ...

    /
    其它信号 /
    };

    (3)分发事件到AO队列

    可以用QActive_postFIFO(TargetAO, (QEvent *)pe)直接分发事件或用QF_publish((QEvent *)pe)间接分发事件到目标AO队列中。使用直接分发事件方式时,不需要AO订阅事件表QF_subscrList的参与,而间接分发事件时要用到AO订阅事件表。

    这两种分发事件都会修改AO队列状态表QF_readySet_(QK中,用QK_readySet),置位相应位,而在Vanilla调度或QK调度会清除AO队列状态表相应位。

    (4)循环调度分派事件到状态机
    - 有两种调度方式,一种是超级循环调度Vanilla方式,这种方式的任务是非抢占式的;
    - 另一种方式是QK调度方式,QK是一个微调度内核,这种方式任务是抢占式的。

    两种调度方式的流程:

    a212f3249e5a832a8744f9a2
    图7.Vanilla调度流程

    b2ba0f46e547d7106b63e587
    图8.QK调度流程

    5.总结

    QF是一个框架,用于事件的产生、保存、分发事件。有两种事件分发方式,并支持两种对任务的调度方式;可以理解QF为一个软件总线,其上安装了很多的AO和ISR。最多可以支持63个AO+ISR。

    参考:
    【1】QP量子平台、量子编程:http://www.state-machine.com

  • 相关阅读:
    Java SE 8 Archive Downloads (JDK 8u202 and earlier)
    MySql.Data.MySqlClient.MySqlProtocolException:“Packet received out-of-order. Expected 1; got 2.”
    docker image 镜像导入导出
    Windows设置国内源阿里云镜像加速与离线安装pip包的方法
    Python time strptime() 函数根据指定的格式把一个时间字符串解析为时间元组
    centos7下vs code编辑器字体与windows版本同步设置-安装中文字体,美化vscode
    windows10 pip install MySQL-python mysqlclient
    Failed to start docker.service: Unit not found.
    tcping测试端口是否畅通
    the type initializer for 'system.drawingcore.gdiplus' threw an exception
  • 原文地址:https://www.cnblogs.com/hyper99/p/QP-zhiQF-yuan-li.html
Copyright © 2011-2022 走看看