FreeRTOS如何減少RAM占用空間并加快執(zhí)行速度?
作者:strongerHuang
微信公眾號:strongerHuang
之前分享了《FreeRTOS V10.4.0更新了哪些功能?》,今天就來詳細(xì)講述其中的一個知識點:FreeRTOS的直接任務(wù)(消息)通知,這樣做的目的就是減少RAM占用空間并加快執(zhí)行速度。
一、寫在前面
幾乎所有RTOS操作系統(tǒng)都提供了隊列和信號量的功能,對于大部分新手來說,使用隊列和信號量是必備技能。
但是,在大多數(shù)情況下,他們都是使用“中介對象”進(jìn)行通信,而并非“直接任務(wù)消息”通信。
通過“中介對象”進(jìn)行通信,每一組隊列或信號量都會分配一段內(nèi)存(消息緩沖區(qū)和流緩沖區(qū))。就存在一個問題,如果隊列或信號量比較多,勢必造成更大的內(nèi)存開支。
但是,如果通過本文說的“直接消息”通信,會節(jié)約很多內(nèi)存。
QueueHandle_t xQueue;
xQueue = xQueueCreate(10, sizeof( /* 長度 */ ) );
大家可以算一下這個“中介對象”會占用多少RAM空間?
通過一個代碼示意圖理解中介對象通信:
從FreeRTOS V10.4.0開始,每個任務(wù)都有一系列通知。每個通知都包含一個32位值和一個布爾狀態(tài),它們一起僅消耗5個字節(jié)的RAM。
就像任務(wù)可以阻止二進(jìn)制信號量等待該信號量變?yōu)椤翱捎谩币粯?,任?wù)可以阻止通知以等待該通知的狀態(tài)變?yōu)椤按幚怼?。同樣,就像任?wù)可以阻止計數(shù)信號量以等待該信號量的計數(shù)變?yōu)榉橇阋粯?,任?wù)可以阻止通知以等待該通知的值變?yōu)榉橇?。下面的第一個示例演示了這種情況。
通知不僅可以傳達(dá)事件,還可以通過多種方式傳達(dá)數(shù)據(jù)。
https://www.freertos.org/RTOS-task-notification-API.html
僅當(dāng)只有一個任務(wù)可以作為事件的接收者時,才可以使用RTOS任務(wù)通知。但是,在大多數(shù)實際使用情況下都可以滿足此條件,例如中斷使執(zhí)行任務(wù)處理的任務(wù)中斷時,該任務(wù)將處理該中斷接收的數(shù)據(jù)。
僅在使用RTOS任務(wù)通知代替隊列的情況下:接收任務(wù)可以在“阻塞”狀態(tài)下等待通知(因此不占用任何CPU時間),而發(fā)送任務(wù)不能在“阻塞”狀態(tài)下等待消息。如果發(fā)送無法立即完成,則發(fā)送完成。
/*?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 );
}
}
https://www.freertos.org/2020/09/decrease-ram-footprint-and-accelerate-execution-with-freertos-notifications.html
長按前往圖中包含的公眾號關(guān)注
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!