RT thread核心之事件

2021-07-14 09:23:48 字數 2612 閱讀 4826

一、事件控制塊:在include/rtdef.h中

#ifdef rt_using_event/**

* flag defintions in event */

#define rt_event_flag_and 0x01 /**< logic and */

#define rt_event_flag_or 0x02 /**< logic or */

#define rt_event_flag_clear 0x04 /**< clear flag */

/** event structure */

struct

rt_event

;typedef

struct rt_event *rt_event_t;

#endif

二、事件相關介面:在src/ipc.c中

建立事件:

rt_event_t rt_event_create(

const

char *name, rt_uint8_t flag);

呼叫該函式介面時,系統會從動態記憶體堆中分配事件物件,然後進行物件的初始化,ipc物件初始化,並把set設定成0。

刪除事件:

rt_err_t rt_event_delete(rt_event_t

event

);在呼叫rt_event_delete函式刪除乙個事件物件時,應該確保該事件不再被使用。在刪除前會喚醒所有掛起在該事件上的執行緒(執行緒的返回值是

-rt_error),然後釋放事件物件占用的記憶體塊。

初始化事件:

rt_err_t rt_event_init(rt_event_t

event, const

char *name, rt_uint8_t flag);

呼叫該介面時,需指定靜態事件物件的控制代碼(即指向事件控制塊的指標),然後系統會初始化事件物件,並加入到系統物件容器中進行管理。

脫離事件:

rt_err_t rt_event_detach(rt_event_t

event

);系統首先喚醒所有掛在該事件等待佇列上的執行緒(執行緒的返回值是

- rt_error ),然後將該事件從核心物件管理器中刪除。

傳送事件:

rt_err_t rt_event_send(rt_event_t

event, rt_uint32_t set

);通過傳送事件服務,可以傳送乙個或多個事件。使用該函式介面時,通過引數set指定的事件標誌來設定event物件的事件標誌值,然後遍歷等待在event事件物件上的等待執行緒鍊錶,判斷是否有執行緒的事件啟用要求與當前event物件事件標誌值匹配,如果有,則喚醒該執行緒。

傳送事件首先會將事件集set儲存到事件控制內部,然後遍歷事件控制塊內所有因等待事件的接收執行緒,如果條件符合則喚醒它

接收事件:

rt_err_t rt_event_recv(rt_event_t

event

, //事件物件的控制代碼

rt_uint32_t

set, //接收執行緒感興趣的事件

rt_uint8_t option, //接收選項

rt_int32_t timeout, //指定超時時間

rt_uint32_t *recved); //指向收到的事件

核心使用32位的無符號整型數來標識事件,它的每一位代表乙個事件,因此乙個事件物件可同時等待接收32個事件,核心可以通過指定選擇引數「邏與」或「邏輯或」來選擇如何啟用執行緒,使用「邏輯與」引數表示只有當所有等待的事件都發生時才啟用執行緒,而使用「邏輯或」引數則表示只要有乙個等待的事件發生就啟用執行緒。

當使用者呼叫這個介面時,系統首先根據set引數和接收選項來判斷它要接收的事件是否發生,如果已經發生,則根據引數option上是否設定有rt_event_flag_clear來決定是否重置事件的相應標誌位,然後返回(其中recved引數返**到的事件); 如果沒有發生,則把等待的set和option引數填入執行緒本身的結構中,然後把執行緒掛起在此事件物件上,直到其等待的事件滿足條件或等待時間超過指定的超時時間。如果超時時間設定為零,則表示當執行緒要接受的事件沒有滿足其要求時就不等待,而直接返回-rt_timeout。

接收事件比較簡單,如果接收到事件則判斷它是否為它關心的事件,如果是,則儲存事件,如果不是,則當沒有接收到事件情況一起處理。接下來就是沒有事件到達的情況,還是老規矩,先判斷時間引數是否為0,如果是則直接返回超時,如果不是,則設定一定時器然後啟動它,接著重新排程執行緒,然後根據當前執行緒的error值是否為rt_eok來判斷是否有新的並且符合條件的事件到達,如果不是,則返回錯誤碼,如果是,則儲存事件,最終返回ok。

控制事件:

rt_err_t rt_event_control(rt_event_t

event, rt_uint8_t cmd, void *arg);

只支援rt_ipc_cmd_reset這個命令,表示復位事件,將事件集set清0。

核心態同步物件之「事件」

事件是一種很常使用到的,用於同步的核心物件。它分為兩種 手動擋的 自動擋的 手動擋 顧名思義,如果乙個事件啟用之後,你不顯式呼叫resetevent的話,那麼事件就一直處於啟用狀態。自動擋 在任何乙個執行緒waitfor函式成功之後,該事件就會被重新調整為未啟用狀態。手動擋的事件通常應用於這麼乙個場...

觸控事件之事件傳遞

uiview是如何判定這個事件是否是自己應該處理的呢?hittest withevent 方法的處理流程如下 呼叫當前view的pointinside withevent 方法來判定觸控點是否在當前view內部,如果返回no,則hittest withevent 返回nil 如果返回yes,則向當前...

RT Thread 核心小細節

訊號量 郵箱訊號 排程中斷鎖 事件訊號量是根據初始值分層的,例如訊號量建立時初始值為2,那麼可以在不釋放訊號量的情況下被獲取兩次此訊號量。釋放一次訊號量訊號量的值 semaphore value 就會加一,獲取一次訊號量的值就會減掉一,為零則不能獲取,被掛起。使用if rt mb recv mb,r...