天天看點

社群新人的RT-Thread學習筆記5——事件集

本文學習RT-Thread的事件集,事件集也是線程間同步的機制之一,一個事件集可以包含多個事件,利用事件集可以完成一對多,多對多的線程間同步。将理論講事件集的工作機制以及相關函數,後面用RTT&正點原子聯合出品的潘多拉開發闆進行實驗。

1、一個線程與多個事件的關系可設定為:其中任意一個事件喚醒線程,或幾個事件都到達後才喚醒線程進行後續的處理;同樣,事件也可以是多個線程同步多個事件。

2、RT-Thread 定義的事件集有以下特點:(1)事件隻與線程相關,事件間互相獨立。(2)事件僅用于同步,不提供資料傳輸功能;(3)事件無排隊性,即多次向線程發送同一事件 (如果線程還未來得及讀走),其效果等同于隻發送一次。

3、每個線程都擁有一個事件資訊标記,它有三個屬性,分别是 <code>RT_EVENT_FLAG_AND</code>(邏輯與),<code>RT_EVENT_FLAG_OR</code>(邏輯或)以及 <code>RT_EVENT_FLAG_CLEAR</code>(清除标記)。當線程等待事件同步時,可以通過 32 個事件标志和這個事件資訊标記來判斷目前接收的事件是否滿足同步條件。 如下圖所示,線程 #1 的事件标志中第 1 位和第 30 位被置位,如果事件資訊标記位設為邏輯與,則表示線程 #1 隻有在事件 1 和事件 30 都發生以後才會被觸發喚醒,如果事件資訊标記位設為邏輯或,則事件 1 或事件 30 中的任意一個發生都會觸發喚醒線程 #1。如果資訊标記同時設定了清除标記位,則當線程 #1 喚醒後将主動把事件 1 和事件 30 清為零,否則事件标志将依然存在(即置 1)。

社群新人的RT-Thread學習筆記5——事件集

事件集工作示意圖(來源RT-Thread程式設計指南)

當建立一個事件集時,核心首先建立一個事件集控制塊,然後對該事件集控制塊進行基本的初始化。

(1)入口參數:

name:事件集的名稱。

flag:事件集的标志,它可以取如下數值:<code>RT_IPC_FLAG_FIFO</code> 或<code>RT_IPC_FLAG_PRIO</code>。

(2)傳回值:

RT_NULL:建立失敗。

事件對象的句柄:建立成功。

系統不再使用 rt_event_create() 建立的事件集對象時,通過删除事件集對象控制塊來釋放系統資源。在删除一個事件集對象時,應該確定該事件集不再被使用。在删除前會喚醒所有挂起在該事件集上的線程(線程的傳回值是RT_ERROR),然後釋放事件集對象占用的記憶體塊。

event:事件集對象的句柄。

RT_EOK:成功。

這裡所說的建立靜态事件集和《RT-Thread程式設計指南》所說的初始化事件集是一樣的,靜态事件集對象的記憶體是在系統編譯時由編譯器配置設定的,一般放于讀寫資料段或未初始化資料段中。

flag:事件集的标志,它可以取如下數值:<code>RT_IPC_FLAG_FIFO</code> 或 <code>RT_IPC_FLAG_PRIO</code>。

當系統不再使用 <code>rt_event_init()</code> 初始化的事件集對象時,通過脫離事件集對象控制塊來釋放系統資源,系統首先喚醒所有挂在該事件集等待隊列上的線程(線程的傳回值是<code>RT_ERROR</code>),然後将該事件集從核心對象管理器中脫離。
發送事件函數可以發送事件集中的一個或多個事件,使用該函數接口時,通過參數 set 指定的事件标志來設定 event 事件集對象的事件标志值,然後周遊等待在 event 事件集對象上的等待線程連結清單,判斷是否有線程的事件激活要求與目前 event 對象事件标志值比對,如果有,則喚醒該線程。

set:發送的一個或多個事件的标志值。

核心使用 32 位的無符号整數來辨別事件集,它的每一位代表一個事件,是以一個事件集對象可同時等待接收 32 個事件,核心可以通過指定選擇參數 “邏輯與” 或 “邏輯或” 來選擇如何激活線程,使用 “邏輯與” 參數表示隻有當所有等待的事件都發生時才激活線程,而使用 “邏輯或” 參數則表示隻要有一個等待的事件發生就激活線程。 系統首先根據 set 參數和接收選項 option 來判斷它要接收的事件是否發生,如果已經發生,則根據參數 option 上是否設定有 <code>RT_EVENT_FLAG_CLEAR</code> 來決定是否重置事件的相應标志位,然後傳回(其中 recved 參數傳回接收到的事件);如果沒有發生,則把等待的 set 和 option 參數填入線程本身的結構中,然後把線程挂起在此事件上,直到其等待的事件滿足條件或等待時間超過指定的逾時時間。如果逾時時間設定為零,則表示當線程要接受的事件沒有滿足其要求時就不等待,而直接傳回<code>RT_ETIMEOUT</code>。

set:接收線程感興趣的事件。

option:接收選項。

timeout:指定逾時時間。

recved:指向接收到的事件。

RT_ETIMEOUT:逾時。

RT_ERROR:錯誤。

前面講了RT-Thread事件集的一些理論知識,光說不練都是假把式,那麼接下來進行實際的操作。建立一個事件集和兩個線程,一個線程用于發送事件,另一個線程用于接收事件,實體RTT&amp;正點原子聯合出品潘多拉開發闆進行實驗,實作事件标志位或觸發線程、事件标志位與觸發線程,通過按鍵來發送事件标志位,或觸發時蜂鳴器響一下,與觸發RGB紅燈亮一下。

1、實作代碼

2、觀察FinSH

(1)當按下KEY0或KEY1時,發送事件标志FLAG3或FLAG5,這個時候蜂鳴器響:

社群新人的RT-Thread學習筆記5——事件集

(2)當按下KEY0和KEY1時,發送事件标志FLAG3和FLAG5,這個時候RGB紅燈亮一下:

社群新人的RT-Thread學習筆記5——事件集

RT-Thread

讓物聯網終端的開發變得簡單、快速,晶片的價值得到最大化發揮。Apache2.0協定,可免費在商業産品中使用,不需要公布源碼,無潛在商業風險。

長按二維碼,關注我們

下一篇: javaweb