資料來源于硬件家園:資料匯總 - FreeRTOS實時操作系統課程(多任務管理)
目錄
一、任務通知的概念
1、概念
2、發送通知給任務的方式
3、任務通知使用限制
二、任務通知的運行機制
三、任務通知的API函數
1、任務通知的數據結構
2、常用的API函數
3、函數xTaskNotifyGive()
4、函數ulTaskNotifyTake()
5、函數xTaskNotify()
6、函數ulTaskNotifyWait()
7、使用說明
四、任務通知代替二值信號量
五、任務通知代替計數信號量
六、任務通知代替隊列
七、任務通知代替事件組
一、任務通知的概念
1、概念
FreeRTOS 從 V8.2.0 版本開始提供任務通知功能,每個任務都有一個 32位的通知值,在多數情況下,任務通可以替代二值信號量、計數信號量、事件組,也可以替代長度為1的隊列(可以保存一個 32位整數或指針值)。
相對于以前使用 FreeRTOS 內核通信的資源時必須創建隊列、二進制信號量、計數信號量或事件組的情況,使用任務通知顯然更靈活。按照 FreeRTOS 官方的說法,使用任務通知比通過信號量等ICP通信方式解除阻塞的任務速度快45%,并且更加省RAM內存空間,任務通知的使用無須創建隊列。要想使用任務通知,必須將FreeRTOSConfig.h中的宏定義configUSE_TASK_NOTIFICATIONS設置為1。其實 FreeRTOS 默認是為1的,所以任務通知是默認可用的。
2、發送通知給任務的方式
> 發送通知給任務,如果有通知未讀,則不覆蓋通知值。
>?發送通知給任務,直接覆蓋通知值。
>發送通知給任務, 設置通知值的一個或者多個位,可以當作事件組來使用。
>?發送通知給任務,遞增通知值,可以當作信號量使用。
通過對以上任務通知方式的合理使用,可以在一定場合下替代 FreeRTOS 的信號量、隊列、事件組等。
3、任務通知使用限制
當然,凡事都有利弊,消息通知雖然處理更快,RAM 開銷更小,但也有以下限制:
>只能有一個任務接收通知消息,因為必須指定接收通知的任務。
>只有等待通知的任務可以被阻塞,發送通知的任務在任何情況下都不會因為發送失敗
而進入阻塞態。
二、任務通知的運行機制
任務通知屬于任務附帶的資源,所以在任務被創建時,任務通知也被初始化,我們知道在使用隊列、信號量前,必須先創建隊列和信號量,目的是創建隊列數據結構,比如使用xQueueCreate() 函數創建隊列,用xSemaphoreCreateBinary()函數創建二值信號量等。再來看任務通知,由于任務通知的數據結構包含在任務控制塊中,只要任務存在,任務通知數據結構就已經創建完畢,可以直接使用,所以使用時很方便
任務通知可以在任務中向指定任務發送通知,也可以在中斷中向指定任務發送通知。FreeRTOS的每個任務都有一個32位的通知值,任務控制塊中的成員變量ulNotifiedValue 就是這個通知值。只有在任務中可以等待通知,而不允許在中斷中等待通知。如果任務在等待的通知暫時無效,任務會根據用戶指定的阻塞超時時間進入阻塞狀態,我們可以將等待通知的任務看作消費者;其他任務和中斷可以向等待通知的任務發送通知,發送通知的任務和中斷服務函數可以看作生產者,當其他任務或者中斷向這個任務發送任務通知,且任務獲得通知以后,該任務就會從阻塞態中解除,這與 FreeRTOS 中內核的其他通信機制一致。
三、任務通知的API函數
1、任務通知的數據結構
任務通知是任務控制塊的資源,屬于任務控制塊中的成員變量。
ulNotifiedValue:?任務通知值,用于保存一個32位整數或指針值
ucNotifyState:??任務通知狀態,用于標識任務的通知狀態
2、常用的API函數
①?替代二值信號量與計數信號量
發送任務通知:
xTaskNotifyGive()
vTaskNotifyGiveFromISR()
獲取任務通知:
ulTaskNotifyTake()
② 替代長為1的隊列與事件組
發送任務通知:
xTaskNotify()
vTaskNotifyFromISR()
獲取任務通知:
ulTaskNotifyWait()
3、函數xTaskNotifyGive()
①?函數原型
?功能如下:在任務中向指定任務發送通知,使任務通知值加1,這種方式用于信號量
②形參說明
形參1:任務句柄
形參2:?任務通知值,取0
形參3:?指示任務控制塊中的變量 ulNotifiedValue 實現加一操作
形參4:空
③返回值
沒有超時機制,永遠返回pdPASS
4、函數ulTaskNotifyTake()
①?函數原型
功能如下:在任務中獲取通知,與xTaskNotifyGive()配套使用,用于替代二值信號量與計數信號量
②形參說明
形參1:退出時是否清零計數。pdTRUE->清零, pdFALSE ->?減1
形參2:?超時時間,單位為系統節拍
③返回值
返回任務之前的任務通知值
5、函數xTaskNotify()
①?函數原型
功能如下:在任務中向指定任務發送通知,根據eAction的值完成不同操作
②形參說明
形參1:任務句柄
形參2:?任務通知值
形參3:?如下圖片
形參4:?空
③返回值
根據上面第 3 個形參的說明,將其設置為 eSetValueWithoutOverwrite,有可能返回pdFALSE,其余所有情況都返回值 pdPASS
6、函數ulTaskNotifyWait()
①?函數原型
功能如下:在任務中獲取通知,與xTaskNotify()配套使用,用于替代長度位1的隊列與事件組
②形參說明
形參1:進入函數時,清除哪些位? ->??0:無變化? ? 1:清除相應位
形參2:退出函數時,清除哪些位? ->??0:無變化? ? 1:清除相應位
形參3:保存通知值
形參4:?超時時間,單位為系統節拍
③返回值
pdTRUE:?獲取任務通知成功
pdFALSE:獲取任務通知失敗
7、使用說明
四、任務通知代替二值信號量
五、任務通知代替計數信號量
?
?
六、任務通知代替隊列
?
?
七、任務通知代替事件組
?
?