**1、freeRTOS中的消息郵箱 **
freeRTOS實現的消息郵箱是基于任務通知方式而實現的。
采用這種方式有什么優勢呢?
從官方給出的測試報告中有說明到,喚醒由于信號量和事件標志組而處于阻塞態的任務,消息郵箱的速度會提升大約 45%,而且這種方式需要的 RAM 空間更小。
freeRTOS中的消息郵箱使用是比較靈活的,它可以實現二值信號量、計數信號量、事件標志組、消息隊列等通知方式。
但用這種 方式實現信號量和事件標志組也有它的局限性,主要表現在以下兩個方面:
1)任務通知方式僅可以用在只有一個任務等待信號量,消息郵箱或者事件標志組的情況。
2)如果使用任務通知方式實現消息郵箱替代消息隊列時,發送消息的任務是不支持超時等待的。在消息隊列中,當數據已經滿時,是可以等待消息隊列有空間才存新的數據的,但是任務通知方式實現的消 息郵箱就不支持超時等待。
2、有關freeRTOS中的任務控制塊
freeRTOS中的每一個任務都有一個任務控制塊,而任務控制塊本質就是一個結構體變量,用于記錄任務的相關的消息。
而在結構體變量中有一個32位的變量成員ulNotifiedValue是可以專門用于任務通知的。這個變量可以實現計數信號量,二值信號量,事件標志組和消息郵箱(消息郵箱就是消息隊 列長度為 1 的情況)。
ulNotifiedValue 實現的:
1)設置接收任務控制塊中的變量 ulNotifiedValue 可以實現消息郵箱。
2)如果接收任務控制塊中的變量 ulNotifiedValue 還沒有被其接收到,也可以用新數據覆蓋原有數據 ,這就是 覆蓋方式的消息郵箱 。
3)設置接收任務控制塊中的變量 ulNotifiedValue 的 bit0-bit31 數值可以實現事件標志組。
4)設置接收任務控制塊中的變量 ulNotifiedValue 數值進行加一或者減一操作可以實現計數信號量和二 值信號量。
3、freeRTOS中消息郵箱的管理API函數
消息郵箱實現的相關API函數:
3.1、消息郵箱的創建
freeRTOS中的消息郵箱是用于任務之間的一種通知方式,它的使用是不需要像信號量這樣要專門創建的。是直接發送通知的。
3.2、消息郵箱的發送
1)在任務函數中發送
函數原型:
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, /* 任務句柄 */
uint32_t ulValue, /* 更新任務控制塊中的變量 ulNotifiedValue */
eNotifyAction eAction ); /* 任務通知模式設置 */
函數描述:
第 1 個參數是任務句柄。
第 2 個參數是用來更新任務控制塊中的 32 位變量 ulNotifiedValue。
第 3 個參數是任務通知模式設置,支持以下 5 個參數:
返回值,根據上面第3個參數的說明,將其設置為 :
eSetValueWithoutOverwrite ,有可能返回 pdFALSE,其余所有情況都返回值 pdPASS。
使用這個函數要注意以下問題:
1)任務創建后,任務控制塊中的變量 ulNotifiedValue 初始計數值是 0。
2)默認配置此函數可以使用的的宏定義已經在 FreeRTOS.h 文件中使能:
#define configUSE_TASK_NOTIFICATIONS 1
當然,如果不需要使用任務通知功能相關的函數,可以在 FreeRTOSConfig.h 文件中配置此宏定 義為 0 來禁止,這樣創建的每個任務可以節省 8 個字節的需求。
3)此函數是用于任務代碼中調用的,故不可以在中斷服務程序中調用此函數,中斷服務程序中使用的是 xTaskNotifyFromISR。
4)根據 FreeRTOS 的建議,實現二值信號量和計數信號量時使用函數 xTaskNotifyGive()替代此函數 xTaskNotify()。
2)在中斷中發送
函數原型:
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, /* 任務句柄 */
uint32_t ulValue, /* 更新任務控制塊中的變量 ulNotifiedValue */
eNotifyAction eAction, /* 任務通知模式設置 */
BaseType_t *pxHigherPriorityTaskWoken ); /* 高優先級任務是否被喚醒的狀態保存 */
函數描述:
函數 xTaskNotifyFromISR 通過設置任務控制塊中的變量 ulNotifiedValue 可以在中斷服務程序中實現任 務事件標志組,任務計數信號量,任務消息郵箱和任務二值信號量四種方式的消息通知。
第 1 個參數是任務句柄。
第 2 個參數是用來更新任務控制塊中的 32 位變量 ulNotifiedValue。
第 3 個參數是任務通知模式設置,支持以下 5 個參數:
第4個參數用于保存是否有高優先級任務準備就緒。如果函數執行完畢后,此參數的數值是 pdTRUE , 說明有高優先級任務要執行,否則沒有。
返回值,根據上面第 3 個參數的說明,將其設置為:
eSetValueWithoutOverwrite ,有可能返回 pdFALSE ,其余所有情況都返回值 pdPASS 。
使用這個函數要注意以下問題:
- 任務創建后,任務控制塊中的變量** ulNotifiedValue **初始計數值是 0。
- 默認配置此函數可以使用的的宏定義已經在 FreeRTOS.h 文件中使能:
#define configUSE_TASK_NOTIFICATIONS 1
當然,如果用戶不需要使用任務通知功能相關的函數,可以在 FreeRTOSConfig.h 文件中配置此宏定 義為 0 來禁止,這樣創建的每個任務可以節省 8 個字節的需求。
3)此函數是用于中斷服務程序中調用的,故不可以在任務代碼中調用此函數,任務代碼中使用的是 xTaskNotify。
4)FreeRTOS 的建議,實現二值信號量和計數信號量時使用函數 vTaskNotifyGiveFromISR ()替代 此函數 xTaskNotifyFromISR ()。
3.3、等待消息郵箱
(1)等待消息郵箱
函數原型:
BaseType_t xTaskNotifyWait(
/* 設置函數執行前清零任務控制塊中變量 ulNotifiedValue 那些位 */
uint32_t ulBitsToClearOnEntry,
/*設置函數退出前清零任務控制塊中變量 ulNotifiedValue 那些位 */
uint32_t ulBitsToClearOnExit,
/* 保存任務控制塊中的變量 ulNotifiedValue 到指針變量 pulNotifiedValue 所指向的存儲單元 */
uint32_t *pulNotificationValue,
/* 等待消息通知的最大等待時間 */
TickType_t xTicksToWait
);
函數描述:
函數 xTaskNotifyWait 可以在任務代碼中實現任務事件標志組,任務計數信號量,任務消息郵箱和任務二 值信號量四種方式的消息獲取。
第 1 個參數 ulBitsToClearOnEntry 用于函數執行之前,將任務控制塊中的變量 ulNotifiedValue 進 行如下操作 :
ulNotifiedValue &= ~ulBitsToClearOnEntry
簡單的說就是參數 ulBitsToClearOnEntry 哪個位是 1,那么變量 ulNotifiedValue 的那個位就會被 清零。比如 ulBitsToClearOnEntry = 0x01 表示將變量 ulNotifiedValue 的 bit0 清零,又比如 ulBitsToClearOnEntry = 0xffffffff 表示將變量 ulNotifiedValue 的所有位清零。
第 2 個參數 ulBitsToClearOnExit 用于函數退出前,將任務控制塊中的變量 ulNotifiedValue 進行如 下操作 :
ulNotifiedValue &= ~ ulBitsToClearOnExit
簡單的說就是參數 ulBitsToClearOnExit 哪個位是 1,那么變量 ulNotifiedValue 的那個位就會被清 零。比如 ulBitsToClearOnExit= 0x01 表示將變量 ulNotifiedValue 的 bit0 清零,又比如 ulBitsToClearOnExit= 0xffffffff 表示將變量 ulNotifiedValue 的所有位清零。
第 3 個參數用于將任務控制塊中的變量 ulNotifiedValue 保存到此參數指針所指向的存儲單元。如果 此參數沒有用上,可以將其設置為 NULL。
第 4 個參數是沒有消息時,等待消息的最大等待時間,單位系統時鐘節拍。
返回值,如果成功接收到消息返回 pdTRUE,否則返回 pdFALSE,比如在設置的超時時間內沒有收 到消息。
使用這個函數要注意以下問題:
1)任務創建后,任務控制塊中的變量 ulNotifiedValue 初始計數值是 0。
2)默認配置此函數可以使用的的宏定義已經在 FreeRTOS.h 文件中使能:
#define configUSE_TASK_NOTIFICATIONS 1
當然,如果用戶不需要使用任務通知功能相關的函數,可以在 FreeRTOSConfig.h 文件中配置此宏定 義為 0 來禁止,這樣創建的每個任務可以節省 8 個字節的需求。
3)如果用戶將 FreeRTOSConfig.h 文件中的宏定義 INCLUDE_vTaskSuspend 配置為 1 且第 2 個參數配 置為:
portMAX_DELAY ,那么此函數會永久等待直到消息可用。
4)根據 FreeRTOS 的建議,實現二值信號量和計數信號量時使用函數 ulTaskNotifyTake ()替代此函數 xTaskNotifyWait ()。
4、消息郵箱的應用示例
為了更好的說明freeRTOS中的消息郵箱的使用。下面給出了一個簡單的示例。
代碼思路如下:
創建3個任務:start_task,led0_task,led2_task。start_task任務用于創建led0_task和led2_task任務,led0_task任務判斷按鍵的情況,然后根據按鍵按下,消息郵箱發送不同的消息到任務led2_task,在這個任務中改變LED2和LED3的狀態。代碼示例如下:
void start_task(void *pvParameters)
{
pvParameters = pvParameters;
taskENTER_CRITICAL(); //進入臨界區
xTaskCreate((TaskFunction_t) led0_task,
(const char*) "led0_task",
(uint16_t) TASK_STK_LED0_SIZE,
(void*) NULL,
(UBaseType_t) TASK_LED0_PRIO,
(TaskHandle_t*) &LED0_Handler );
xTaskCreate((TaskFunction_t) led2_task,
(const char*) "led2_task",
(uint16_t) TASK_STK_LED2_SIZE,
(void*) NULL,
(UBaseType_t) TASK_LED2_PRIO,
(TaskHandle_t*) &LED2_Handler );
vTaskDelete(StartTask_Handler); //刪除開始任務
taskEXIT_CRITICAL(); //退出臨界區
}
void led0_task(void *pvParameters)
{
//pvParameters = pvParameters;
BaseType_t err = pdFALSE;
uint32_t MboxValue=0;
for(;;)
{
if(gd_eval_key_state_get(KEY_WAKEUP) == RESET)
{
MboxValue = 10;
err = xTaskNotify((TaskHandle_t ) LED2_Handler, //任務句柄,指明往哪個任務發送消息,很重要
(uint32_t ) MboxValue, //發送的消息
(eNotifyAction) eSetValueWithOverwrite //消息發送方式
);
}
else if(gd_eval_key_state_get(KEY_TAMPER) == RESET)
{
MboxValue = 50;
err = xTaskNotify((TaskHandle_t ) LED2_Handler, //任務句柄
(uint32_t ) MboxValue, //發送的消息
(eNotifyAction) eSetValueWithOverwrite //消息發送方式
);
}
else{}
gd_eval_led_toggle(LED4);
vTaskDelay(200);
}
}
void led2_task(void *pvParameters)
{
//pvParameters = pvParameters;
uint32_t notifyValue = 0;
BaseType_t err;
for(;;)
{
err = xTaskNotifyWait((uint32_t ) 0x00, //進入函數時不清楚bit
(uint32_t) 0xffffffff, //退出函數時清除所有的bit
(uint32_t*) ¬ifyValue, //保存消息的內容
(TickType_t) portMAX_DELAY //阻塞時間
);
if(err == pdTRUE)
{
switch(notifyValue)
{
case 10:
gd_eval_led_toggle(LED2);
break;
case 50:
gd_eval_led_toggle(LED3);
break;
default:
break;
}
}
vTaskDelay(100);
}
}
-
FreeRTOS
+關注
關注
12文章
484瀏覽量
62271 -
信號量
+關注
關注
0文章
53瀏覽量
8362 -
消息隊列
+關注
關注
0文章
33瀏覽量
3010
發布評論請先 登錄
相關推薦
評論