freeRtos学习笔记 (5)事件组
freeRtos學習筆記
freeRtos事件組
為什么要用事件組?
多任務環境下, 任務、中斷之間往往需要同步操作,一個事件發生會告知等待中的任
務,即形成一個任務與任務、中斷與任務間的同步。事件可以提供一對多、多對多的同步
操作。一對多同步模型:一個任務等待多個事件的觸發,這種情況是比較常見的;多對多
同步模型:多個任務等待多個事件的觸發。
為什么不直接使用全局變量?
在裸機編程時,使用全局變量的確比較方便,但是在加上 RTOS 后
就是另一種情況了。 使用全局變量相比事件標志組主要有如下三個問題:
- 使用事件標志組可以讓 RTOS 內核有效地管理任務, 而全局變量是無法做到的,任務的超時等機制需
要用戶自己去實現。 - 使用了全局變量就要防止多任務的訪問沖突,而使用事件標志組則處理好了這個問題,用戶無需擔心。
- 使用事件標志組可以有效地解決中斷服務程序和任務之間的同步問題
事件組創建
EventGroupHandle_t xEventGroupCreate(void);函數 xEventGroupCreate 用于創建事件標志組。
- 返回值,如果創建成功,此函數返回事件標志組的句柄,如果 FreeRTOSConfig.h 文件中定義的 heap
空間不足會返回 NULL
設置事件組
EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, /* 事件組句柄 */const EventBits_t uxBitsToSet); /* 要設置的事件標志位 */EventBits_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup, /* 事件組句柄 */const EventBits_t uxBitsToSet, /* 要設置的事件標志位 */BaseType_t *pxHigherPriorityTaskWoken ); /* 高優先級任務是否被喚醒的狀態保存 */函數 xEventGroupSetBits 用于設置指定的事件標志位為 1。
- 第 1 個參數是事件標志組句柄。
- 第 2 個參數表示可設置的事件標志位, 當單片機為16位時 EventBits_t 是定義的 16 位變量,低8位用于事件標志位設置;當單片機位32位時 EventBits_t 是定義的 32 位變量,低24位用于事件標志位設置;變量 uxBitsToSet 的低 24 位的某個位設置為 1,那么被設置的事件標志組的相應位就設置為 1。 變量 uxBitsToSet 設置為 0 的位對事件標志相應位沒有影響。比如設置變量 uxBitsToSet = 0x0003 就表示將事件標志的位 0 和位 1 設置為 1, 其余位沒有變化。
- 第 3 個參數用于保存是否有高優先級任務準備就緒。 如果函數執行完畢后,此參數的數值是 pdTRUE,
說明有高優先級任務要執行, 否則沒有??梢岳么藚蹬袛嗍欠裥枰⒖踢M行任務切換 taskYIELD()。 - 返回值: 返回當前的事件標志組數值。
- 注意事項:
- 中斷服務程序中使用的是 xEventGroupSetBitsFromISR();
函數 xEventGroupSetBitsFromISR 對事件標志組的操作是不確定性操作,因為不知道當前有多少個
任務在等待此事件標志(消息隊列有對應的列表,信號量底層也是根據消息隊列實現的,因此信號量和消息隊列不需要這樣)。而 FreeRTOS 不允許在中斷服務程序和臨界段中執行不確定性操作。 為了不在中斷服務程序中執行,就通過此函數給 FreeRTOS 的 daemon 任務(就是 FreeRTOS 的定時器任務)發送消息,在 daemon 任務中執行事件標志的置位操作。 同時也為了不在臨界段中執行此不確定操作,將臨界段改成由調度鎖來完成。這樣不確定性操作在中斷服務程序和臨界段中執行的問題就都得到解決了。由于函數 xEventGroupSetBitsFromISR 對事件標志的置位操作是在 daemon 任務里面執行的, 所以如果使用xEventGroupSetBitsFromISR函數需要使能軟件定時器,如果想讓置位操作立即生效,即讓等此事件標志的任務能夠得到及時執行,需要設置 daemon 任務的優先級高于使用此事件標志組的所有其它任務。
想讓置位操作立即生效,即讓等此事件標志的任務能夠得到及時執行,需要設置 daemon 任務的優先
級高于使用此事件標志組的所有其它任務。
2. 用戶通過參數 uxBitsToSet 設置的標志位并不一定會保留到此函數的返回值中, 下面舉兩種情況:
a. 調用此函數的過程中,其它高優先級的任務就緒了,并且也修改了事件標志,此函數返回的事件標志位會發生變化。
b. 調用此函數的任務是一個低優先級任務, 通過此函數設置了事件標志后,讓一個等待此事件標志的高優先級任務就緒了,會立即切換到高優先級任務去執行, 相應的事件標志位會被函數xEventGroupWaitBits 清除掉,等從高優先級任務返回到低優先級任務后, 函數xEventGroupSetBits 的返回值已經被修改。
等待事件標志位
EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup, /* 事件組句柄 */const EventBits_t uxBitsToWaitFor, /* 等待被設置的事件標志位 */const BaseType_t xClearOnExit, /* 選擇是否清除被置位的事件標志位 */const BaseType_t xWaitForAllBits, /* 是否等待所有標志位被置位 */TickType_t xTicksToWait); /* 超時事件 */函數 xEventGroupWaitBits 等待事件標志被設置。
- 第 1 個參數是事件標志組句柄。
- 第 2 個參數表示等待事件標志位中的指定標志, EventBits_t 是定義的 32 位變量時低 24 位用于事件標志設置。 此參數切不可設置為 0。
- 第 3 個參數選擇是否清除已經被置位的事件標志, 如果這個參數設置為 pdTRUE, 且函數
xEventGroupWaitBits 在參數 xTicksToWait 設置的溢出時間內返回,那么相應被設置的事件標志
位在xEventGroupWaitBits()函數退出前會被清零。 如果這個參數設置為 pdFALSE,對已經被設置的事件標志位沒有影響。 - 第 4 個參數選擇是否等待所有的標志位都被設置, 如果這個參數設置為 pdTRUE,要等待第 2 個參
數 uxBitsToWaitFor 所指定的標志位全部被置 1, 函數才可以返回。當然,超出了在參數
xTicksToWait 設置的溢出時間也是會返回的。如果這個參數設置為 pdFALSE, 第 2 個參數
uxBitsToWaitFor 所指定的任何標志位被置 1, 函數都會返回, 超出溢出時間也會返回。 - 第 5 個參數設置等待時間,單位時鐘節拍周期。 如果設置為 portMAX_DELAY, 表示永久等待。
- 返回值,由于設置的時間超時或者指定的事件標志位被置 1,導致函數退出時返回的事件標志組數值。第三個參數不會影響返回值。
- 注意事項: 不要在中斷中調用該函數
清除事件組標志位
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToClear);EventBits_t xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToClear);函數 xEventGroupClearBits 清除事件標志位。
- 第 1 個參數是事件標志組句柄。
- 第 2 個參數表示等待清除的指定標志, EventBits_t 是定義的 32 位變量時低 24 位用于事件標志設置。 此參數切不可設置為 0。
- 返回值:清除前的事件組值。
本文參考 freertos官方文檔 https://freertos.org/a00110.html
《野火-FreeRTOS 內核實現與應用開發實戰指南》
《安富萊 STM32-V6 開發板 FreeRTOS 教程》
總結
以上是生活随笔為你收集整理的freeRtos学习笔记 (5)事件组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: freeRtos学习笔(4)消息队列
- 下一篇: freeRtos学习笔记 (6)软件定时