這一篇我們來聊聊關于事件的派發機制,狀態機要真正的被激活進行相應的處理是需要事件的輸入的??梢园阉醋魇鞘录南M者,事件的生產者和消費者之間不能通過共享全局變量的方式來進行信息交換,這好像是我們前面講的QP開發應用程序的第一條準則,因此需要有人來承接事件傳輸的任務,這個由QF框架來負責。
QF框架提供了兩種事件的派發機制:
第一種、直接發送事件機制。這種是最實用的機制,他的原理很簡單,事件產生者,直接將事件發送給事件的消費者(活動對象)事件的生產者有很多,例如ISR、設備驅動代碼、運行在框架之外的代碼。但是事件的消費者只能是活動對象,為什么?因為事件之間的通信是異步的,只有活動對象擁有事件隊列。QPC6.9.1中給出了三種直接發送事件的API,如下圖:
然而其API中,關于這個函數有什么區別以及怎么用只是很簡單的提了提,并不是很詳細,所以我們全局搜索了整個源碼包中,所有使用到的API,挑幾個有代表性的應用是來看下:
第二種、發行-訂閱機制。這一種是比較高級的用法,假如你第一次接觸QP并且沒有RTOS編程的經驗,第一次接觸QP建議你先忽略掉這種方法,會第一種就足夠了,你在實際應用中完全可以通過第一種用法,解決繁瑣問題,當然有些場合應用第二種方法會簡便很多,例如一個活動對象要發送一個事件給很多其它的活動對象時,應用第一種,你需要知道每個活動對象的名字(指針)這樣要進行很多次的發送操作,然而應用第二種時,你只需要告訴QF框架,你要發行某個事件,至于發給誰那就要QF框架自己看看都有誰(哪個活動對象訂閱了這個事件了)
發行訂閱機制有個需要注意的點,就是QF框架需要記住訂閱者的信息, 當接收到某事件發行的信號時,需要查找這個記錄集合,找到某事件對應的活動對象,這樣才能完成指定的發送。這個記錄的結構體集合在QPC6.9.1的說明,如下圖:
講到這里了,其實可以筆鋒一轉,接著講API ,然后后面是例子中的應用了,但是甘心嗎?你不想知道這個發行訂閱機制是怎么實現的嗎?哈哈,雖然可能會有點混亂,但是那就讓我們混亂下去吧,接下來讓我們深度解析一下,這個我不推薦新手用的發行訂閱機制,QF框架是怎么找到對應活動對象的(面對疾風吧~?。?/strong>,其實,他是通過查表法來實現的,先來講原理,看一下他的表圖構造:
首先這是一個二維表,縱向是事件,不同的事件放在不同的位置上,橫向的每個bit上代表活動狀態機的優先級,因為活動對象的優先級是唯一的,所以可以通過它找到對應的對象,在QP量子編程中,一個應用里面最多有64個狀態機,一個應用會有多少個事件呢,好像沒有嚴格限制。接下來看一下這個結構集合的定義:
從上面可以看到他定位的是一個一維表,或者叫一維數組,他只有活動對象方向,并不完整,它還需要縱向的事件維度,這里其實它把控制權交給了我們的應用,因為你最大需要訂閱幾個事件,那么你就定義一個特定大小的數組,如下:
定義好了我們的事件-對象二維表以后,在使用前,我們需要先把他初始化,QF提供了專門的API來完成該部分內容:
完成初始化以后,我們就可以使用訂閱API函數,訂閱某個事件了,同樣也可以使用發行事件API,進行事件的發布:
對于發行-訂閱機制,又訂閱就有解除訂閱,解除訂閱可以是為某個活動對象解除特定事件的訂閱,也可以清空某個對象的所有訂閱,如下:
到這里關于事件的派發機制相關內容都分析完了,看到這里如果你也很感興趣,不妨自己找個demo實踐一下筆記中給大家講解的相關理論是否正確,下篇再見。