这一篇我们来聊聊关于事件的派发机制,状态机要真正的被激活进行相应的处理是需要事件的输入的。可以把他看作是事件的消费者,事件的生产者和消费者之间不能通过共享全局变量的方式来进行信息交换,这好像是我们前面讲的QP开发应用程序的第一条准则,因此需要有人来承接事件传输的任务,这个由QF框架来负责。
QF框架提供了两种事件的派发机制:
第一种、直接发送事件机制。这种是最实用的机制,他的原理很简单,事件产生者,直接将事件发送给事件的消费者(活动对象)事件的生产者有很多,例如ISR、设备驱动代码、运行在框架之外的代码。但是事件的消费者只能是活动对象,为什么?因为事件之间的通信是异步的,只有活动对象拥有事件队列。QPC6.9.1中给出了三种直接发送事件的API,如下图:
然而其API中,关于这个函数有什么区别以及怎么用只是很简单的提了提,并不是很详细,所以我们全局搜索了整个源码包中,所有使用到的API,挑几个有代表性的应用是来看下:
第二种、发行-订阅机制。这一种是比较高级的用法,假如你第一次接触QP并且没有RTOS编程的经验,第一次接触QP建议你先忽略掉这种方法,会第一种就足够了,你在实际应用中完全可以通过第一种用法,解决繁琐问题,当然有些场合应用第二种方法会简便很多,例如一个活动对象要发送一个事件给很多其它的活动对象时,应用第一种,你需要知道每个活动对象的名字(指针)这样要进行很多次的发送操作,然而应用第二种时,你只需要告诉QF框架,你要发行某个事件,至于发给谁那就要QF框架自己看看都有谁(哪个活动对象订阅了这个事件了)
发行订阅机制有个需要注意的点,就是QF框架需要记住订阅者的信息, 当接收到某事件发行的信号时,需要查找这个记录集合,找到某事件对应的活动对象,这样才能完成指定的发送。这个记录的结构体集合在QPC6.9.1的说明,如下图:
讲到这里了,其实可以笔锋一转,接着讲API ,然后后面是例子中的应用了,但是甘心吗?你不想知道这个发行订阅机制是怎么实现的吗?哈哈,虽然可能会有点混乱,但是那就让我们混乱下去吧,接下来让我们深度解析一下,这个我不推荐新手用的发行订阅机制,QF框架是怎么找到对应活动对象的(面对疾风吧~!),其实,他是通过查表法来实现的,先来讲原理,看一下他的表图构造:
首先这是一个二维表,纵向是事件,不同的事件放在不同的位置上,横向的每个bit上代表活动状态机的优先级,因为活动对象的优先级是唯一的,所以可以通过它找到对应的对象,在QP量子编程中,一个应用里面最多有64个状态机,一个应用会有多少个事件呢,好像没有严格限制。接下来看一下这个结构集合的定义:
从上面可以看到他定位的是一个一维表,或者叫一维数组,他只有活动对象方向,并不完整,它还需要纵向的事件维度,这里其实它把控制权交给了我们的应用,因为你最大需要订阅几个事件,那么你就定义一个特定大小的数组,如下:
定义好了我们的事件-对象二维表以后,在使用前,我们需要先把他初始化,QF提供了专门的API来完成该部分内容:
完成初始化以后,我们就可以使用订阅API函数,订阅某个事件了,同样也可以使用发行事件API,进行事件的发布:
对于发行-订阅机制,又订阅就有解除订阅,解除订阅可以是为某个活动对象解除特定事件的订阅,也可以清空某个对象的所有订阅,如下:
到这里关于事件的派发机制相关内容都分析完了,看到这里如果你也很感兴趣,不妨自己找个demo实践一下笔记中给大家讲解的相关理论是否正确,下篇再见。