嵌入式專欄
1
寫在前面幾乎所有RTOS操作系統都提供了隊列和信號量的功能,對于大部分新手來說,使用隊列和信號量是必備技能。
但是,在大多數情況下,他們都是使用“中介對象”進行通信,而并非“直接任務消息”通信。
通過“中介對象”進行通信,每一組隊列或信號量都會分配一段內存(消息緩沖區和流緩沖區)。就存在一個問題,如果隊列或信號量比較多,勢必造成更大的內存開支。
但是,如果通過本文說的“直接消息”通信,會節約很多內存。
嵌入式專欄
2
什么是直接任務通知?大多數任務間通信方法都通過中介對象,例如隊列,信號量或事件組。發送任務寫入通信對象,接收任務從通信對象讀取。
比如FreeRTOS的隊列通信,首先創建隊列之前要定義一個隊列:
而這個隊列包含了很多中介對象:
大家可以算一下這個“中介對象”會占用多少RAM空間?
通過一個代碼示意圖理解中介對象通信:
直接任務通知:當使用直接任務通知時,顧名思義,發送任務將通知直接發送給接收任務,而無需中介對象。
通過一個代碼示意圖理解:
從FreeRTOS V10.4.0開始,每個任務都有一系列通知。每個通知都包含一個32位值和一個布爾狀態,它們一起僅消耗5個字節的RAM。
就像任務可以阻止二進制信號量等待該信號量變為“可用”一樣,任務可以阻止通知以等待該通知的狀態變為“待處理”。同樣,就像任務可以阻止計數信號量以等待該信號量的計數變為非零一樣,任務可以阻止通知以等待該通知的值變為非零。下面的第一個示例演示了這種情況。
通知不僅可以傳達事件,還可以通過多種方式傳達數據。
嵌入式專欄
3
進一步分析直接任務通知通過對比FreeRTOS V10.4.0和之前版本,你會發現V10.4.0多了一些API,比如ulTaskNotifyTake / ulTaskNotifyTakeIndexed:
在官網也有針對這些API的詳細介紹和說明,以及應用代碼例子:
直接任務通信API說明地址:
https://www.freertos.org/RTOS-task-notification-API.html
(公號不支持外鏈接,請復制鏈接到瀏覽器打開)
嵌入式專欄
4
使用直接任務通知性能優勢和使用限制任務通知的靈活性使它們可以在需要創建單獨的隊列、 二進制信號量、 數信號量或事件組的情況下使用。
與使用中介對象(例如信號量)來取消阻止任務相比,使用直接通知取消阻止RTOS任務的速度快了45%(來自官方數據),并且使用的RAM更少。
當然,有這些性能優勢,也肯定一些限制:
僅當只有一個任務可以作為事件的接收者時,才可以使用RTOS任務通知。但是,在大多數實際使用情況下都可以滿足此條件,例如中斷使執行任務處理的任務中斷時,該任務將處理該中斷接收的數據。
僅在使用RTOS任務通知代替隊列的情況下:接收任務可以在“阻塞”狀態下等待通知(因此不占用任何CPU時間),而發送任務不能在“阻塞”狀態下等待消息。如果發送無法立即完成,則發送完成。
嵌入式專欄
5
使用方法使用方法其實很簡單,只要你會使用RTOS的隊列、信號量,基本看一眼官方例子就能使用。
我這里也拿官方例子說明一下:
/*main()創建的兩個任務的原型*/
static void prvTask1( void *pvParameters );
static void prvTask2( void *pvParameters );
/*處理由main()創建的任務的句柄*/
static TaskHandle_t xTask1 = NULL, xTask2 = NULL;
/*創建兩個任務,來回發送通知,然后啟動RTOS調度程序*/
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( ;; )
{
/* 發送通知到prvTask2() ,使其脫離“已阻止”狀態。*/
xTaskNotifyGiveIndexed( xTask2, 0 );
/*阻止等待prvTask2()通知此任務*/
ulTaskNotifyTakeIndexed( 0, pdTRUE, portMAX_DELAY );
}
}
/*———————————————————–*/
/* prvTask2()使用API的原始版本(不帶“索引”) */
static void prvTask2( void *pvParameters )
{
for( ;; )
{
/*等待prvTask1()通知此任務 */
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
/*向prvTask1()發送通知,使它退出“已阻止”狀態*/
xTaskNotifyGive( xTask1 );
}
}
責任編輯:xj
原文標題:如何改善FreeRTOS運行的速度、RAM大小
文章出處:【微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。
-
RAM
+關注
關注
8文章
1369瀏覽量
114901 -
FreeRTOS
+關注
關注
12文章
484瀏覽量
62329 -
運行速度
+關注
關注
0文章
2瀏覽量
6734
原文標題:如何改善FreeRTOS運行的速度、RAM大小
文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論