日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > > strongerHuang
[導(dǎo)讀]今天就來詳細講述其中的一個知識點:FreeRTOS的直接任務(wù)(消息)通知,這樣做的目的就是減少RAM占用空間并加快執(zhí)行速度。


作者 | strongerHuang

微信公眾號 | 嵌入式專欄

之前分享了《 FreeRTOS V10.4.0更新了哪些功能? 》,今天就來詳細講述其中的一個知識點:FreeRTOS的直接任務(wù)(消息)通知,這樣做的目的就是減少RAM占用空間并加快執(zhí)行速度。

1

寫在前面 幾乎所有RTOS操作系統(tǒng)都提供了隊列和信號量的功能,對于大部分新手來說,使用隊列和信號量是必備技能。

但是,在大多數(shù)情況下,他們都是使用“中介對象”進行通信,而并非“直接任務(wù)消息”通信。

通過“中介對象”進行通信,每一組隊列或信號量都會分配一段內(nèi)存(消息緩沖區(qū)和流緩沖區(qū))。就存在一個問題,如果隊列或信號量比較多,勢必造成更大的內(nèi)存開支。

但是,如果通過本文說的“直接消息”通信,會節(jié)約很多內(nèi)存。

2

什么是直接任務(wù)通知? 大多數(shù)任務(wù)間通信方法都通過 中介對象 ,例如隊列,信號量或事件組。 發(fā)送任務(wù)寫入通信對象,接收任務(wù)從通信對象讀取。
比如FreeRTOS的隊列通信,首先創(chuàng)建隊列之前要定義一個隊列:

QueueHandle_t xQueue; xQueue = xQueueCreate(10, sizeof( /* 長度 */ ) ); 而這個隊列包含了很多中介對象: 

大家可以算一下這個“中介對象”會占用多少RAM空間?

通過一個代碼示意圖理解中介對象通信:


直接任務(wù)通知: 當使用直接任務(wù)通知時,顧名思義,發(fā)送任務(wù)將通知直接發(fā)送給接收任務(wù),而無需中介對象。
通過一個代碼示意圖理解:

從FreeRTOS V10.4.0開始,每個任務(wù)都有一系列通知。每個通知都包含一個32位值和一個布爾狀態(tài),它們一起僅消耗5個字節(jié)的RAM。

就像任務(wù)可以阻止二進制信號量等待該信號量變?yōu)椤翱捎谩币粯樱蝿?wù)可以阻止通知以等待該通知的狀態(tài)變?yōu)椤按幚怼?。同樣,就像任?wù)可以阻止計數(shù)信號量以等待該信號量的計數(shù)變?yōu)榉橇阋粯?,任?wù)可以阻止通知以等待該通知的值變?yōu)榉橇?。下面的第一個示例演示了這種情況。

通知不僅可以傳達事件,還可以通過多種方式傳達數(shù)據(jù)。

3

進一步分析直接任務(wù)通知 通過對比 FreeRTOS V10.4.0 和之前版本,你會發(fā)現(xiàn) V10.4.0 多了一些API,比如ulTaskNotifyTake / ulTaskNotifyTakeIndexed:

在官網(wǎng)也有針對這些API的詳細介紹和說明,以及應(yīng)用代碼例子:

直接任務(wù)通信API說明地址:

https://www.freertos.org/RTOS-task-notification-API.html

4

使用直接任務(wù)通知性能優(yōu)勢和使用限制 任務(wù)通知的靈活性使它們可以在需要創(chuàng)建單獨的隊列、 二進制信號量、 數(shù)信號量或事件組的情況下使用。
與使用中介對象(例如信號量)來取消阻止任務(wù)相比,使用直接通知取消阻止RTOS任務(wù)的速度快了45% (來自官方數(shù)據(jù)) ,并且使用的RAM更少。
當然,有這些性能優(yōu)勢,也肯定一些限制

  • 僅當只有一個任務(wù)可以作為事件的接收者時,才可以使用RTOS任務(wù)通知。但是,在大多數(shù)實際使用情況下都可以滿足此條件,例如中斷使執(zhí)行任務(wù)處理的任務(wù)中斷時,該任務(wù)將處理該中斷接收的數(shù)據(jù)。

  • 僅在使用RTOS任務(wù)通知代替隊列的情況下:接收任務(wù)可以在“阻塞”狀態(tài)下等待通知(因此不占用任何CPU時間),而發(fā)送任務(wù)不能在“阻塞”狀態(tài)下等待消息。如果發(fā)送無法立即完成,則發(fā)送完成。

5

使用方法 使用方法其實很簡單,只要你會使用RTOS的隊列、信號量,基本看一眼官方例子就能使用。
我這里也拿官方例子說明一下:

/* main() 創(chuàng)建的兩個任務(wù)的原型 */static void prvTask1( void *pvParameters );static void prvTask2( void *pvParameters ); /* 處理由main() 創(chuàng)建的任務(wù)的句柄 */static TaskHandle_t xTask1 = NULL, xTask2 = NULL; /* 創(chuàng)建兩個任務(wù),來回發(fā)送通知,然后啟動RTOS調(diào)度程序 */void main( void ){ xTaskCreate( prvTask1, “Task1”, 200, NULL, tskIDLE_PRIORITY, &xTask1 ); xTaskCreate( prvTask2, “Task2”, 200, NULL, tskIDLE_PRIORITY, &xTask2 ); vTaskStartScheduler();}/*———————————————————–*/ /* prvTask1() 使用API的“索引”版本 */static void prvTask1( void *pvParameters ){ for( ;; ) { /* 發(fā)送通知到prvTask2() ,使其脫離“已阻止”狀態(tài)。*/ xTaskNotifyGiveIndexed( xTask2, 0 );  /* 阻止等待prvTask2() 通知此任務(wù) */ ulTaskNotifyTakeIndexed( 0, pdTRUE, portMAX_DELAY ); }}/*———————————————————–*/ /* prvTask2()使用API的原始版本(不帶“索引”) */static void prvTask2( void *pvParameters ){ for( ;; ) { /* 等待prvTask1()通知此任務(wù) */ ulTaskNotifyTake( pdTRUE, portMAX_DELAY );  /* 向prvTask1()發(fā)送通知,使它退出“已阻止”狀態(tài) */ xTaskNotifyGive( xTask1 ); }}

本文就介紹到這里,更多內(nèi)容請參看官方文檔:

https://www.freertos.org/2020/09/decrease-ram-footprint-and-accelerate-execution-with-freertos-notifications.html


免責聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉