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