18 freertos消息队列-任务通信
生活随笔
收集整理的這篇文章主要介紹了
18 freertos消息队列-任务通信
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
十八:18 freertos消息隊列-任務通信
試驗源碼:
#include <stdio.h> #include "board.h" #include "led.h" #include "key.h" #include "uart.h" //#include "tim_mrt.h"/*** System oscillator rate and clock rate on the CLKIN pin ****/ /**/const uint32_t OscRateIn = MAIN_OSC_XTAL_FREQ_HZ; /**/ /**/const uint32_t ExtRateIn = EXT_CLOCK_IN_FREQ_HZ; /**///系統復位 #define System_restart (LPC_SWM->PINENABLE0 = 0xffffffffUL) /**/ /***************************************************************/#include "FreeRTOSConfig.h" /* FreeRTOS頭文件 */ #include "FreeRTOS.h" #include "task.h" #include "event_groups.h"//事件頭文件 #include "queue.h"//隊列頭文件/**************************** 任務句柄 ********************************/ /* * 任務句柄是一個指針,用于指向一個任務。*//* LED任務句柄 */ static TaskHandle_t LED1_Task_Handle= NULL; static xTaskHandle KEY_Task_Handle = NULL; #define TASK_STACK_SIZE 32static QueueHandle_t xQueue1 = NULL; static QueueHandle_t xQueue2 = NULL; typedef struct Msg {uint8_t ucMessageID;uint16_t usData[2];uint32_t ulData[2]; }MSG_T;MSG_T g_tMsg; /* 定義一個結構體用于消息隊列 *//* Sets up system hardware *********************************************************************** @ 函數名 : BSP_Init* @ 功能說明: 板級外設初始化,所有板子上的初始化均可放在這個函數里面* @ 參數 : * @ 返回值 : 無 *********************************************************************/ static void prvSetupHardware(void) {SystemCoreClockUpdate();DEBUGINIT();led_Init() ; Key_INIT(); // MRT_Init();Board_UARTPutSTR("build date: " __DATE__ " build time: " __TIME__ "\n");}/*********************************************************************** @ 函數名 : vLED_Task0* @ 功能說明: LED_Task任務主體,接收任務 vKEY_task 發送的消息隊列數據(xQueue2)* @ 參數 : * @ 返回值 : 無********************************************************************/static void vLED1_Task (void *pvParameters) {MSG_T *ptMsg;BaseType_t xResult;const TickType_t xMaxBlockTime = pdMS_TO_TICKS(200); /* 設置最大等待時間為200ms */while (1) {// vTaskDelay(10);xResult = xQueueReceive(xQueue2, /* 消息隊列句柄 */(void *)&ptMsg, /* 這里獲取的是結構體的地址 */(TickType_t)xMaxBlockTime);/* 設置阻塞時間 */vTaskDelay(100); if(xResult == pdPASS){/* 成功接收,并通過串口將數據打印出來 */printf("接收到消息隊列數據 ptMsg->ucMessageID = %d\r\n", ptMsg->ucMessageID);printf("接收到消息隊列數據 ptMsg->ulData[0] = %d\r\n", ptMsg->ulData[0]);printf("接收到消息隊列數據 ptMsg->usData[0] = %d\r\n", ptMsg->usData[0]);Board_LED_Toggle(0);}else{/* 超時 */Board_LED_Toggle(2);Board_LED_Toggle(3);}} }/* ********************************************************************************************************* * 函 數 名: vKEY_task * 功能說明: 按鍵任務 * 形 參: pvParameters 是在創建該任務時傳遞的形參 * 返 回 值: 無 * 優 先 級: 1 (數值越小優先級越低,這個跟uCOS相反) ********************************************************************************************************* */ static void vKEY_task(void* pvParameters) {MSG_T *ptMsg;uint8_t ucCount = 0;uint8_t pcWriteBuffer[200];/* 初始化結構體指針 */ptMsg = &g_tMsg;/* 初始化數組 */ptMsg->ucMessageID = 0;ptMsg->ulData[0] = 0;ptMsg->usData[0] = 0;u8 key2=0;while(1){u8 key=0;if(Scan_Key())vTaskDelay(20);else continue;if(!Scan_Key())continue;else{key=Scan_Key();key2=key;}while(Scan_Key()){};//等按鍵抬起if(key2){switch(key2){case 1:{printf("=================================================\r\n");printf("任務名 任務狀態 優先級 剩余棧 任務序號\r\n");vTaskList((char *)&pcWriteBuffer);printf("%s\r\n", pcWriteBuffer);}break;case 2:{/* K2鍵按下,向xQueue1發送數據 */ucCount++;/* 向消息隊列發數據,如果消息隊列滿了,等待10個時鐘節拍 */if( xQueueSend(xQueue1,(void *) &ucCount,(TickType_t)10) != pdPASS ){/* 發送失敗,即使等待了10個時鐘節拍 */printf("K2鍵按下,向xQueue1發送數據失敗,即使等待了10個時鐘節拍\r\n");}else{/* 發送成功 */printf("K2鍵按下,向xQueue1發送數據成功\r\n"); }}break;case 3:{/* K3鍵按下,向xQueue2發送數據 */ptMsg->ucMessageID++;ptMsg->ulData[0]++;;ptMsg->usData[0]++;/* 使用消息隊列實現指針變量的傳遞 */if(xQueueSend(xQueue2, /* 消息隊列句柄 */(void *) &ptMsg, /* 發送結構體指針變量ptMsg的地址 */(TickType_t)10) != pdPASS ){/* 發送失敗,即使等待了10個時鐘節拍 */printf("K3鍵按下,向 xQueue2 發送數據失敗,即使等待了10個時鐘節拍\r\n");}else{/* 發送成功 */printf("K3鍵按下,向 xQueue2 發送數據成功 \r\n"); }}break;default:break;}key2=0;}} }/* ********************************************************************************************************* * 函 數 名: vTaskMsgPro * 功能說明: 使用函數 xQueueReceive 接收任務 vKEY_task 發送的消息隊列數據(xQueue1) * 形 參: pvParameters 是在創建該任務時傳遞的形參 * 返 回 值: 無 * 優 先 級: 3 ********************************************************************************************************* */ static void vTaskMsgPro(void *pvParameters) {BaseType_t xResult;const TickType_t xMaxBlockTime = pdMS_TO_TICKS(300); /* 設置最大等待時間為300ms */uint8_t ucQueueMsgValue;while(1){/* 獲取K2按鍵按下的消息隊列 */xResult = xQueueReceive(xQueue1, /* 消息隊列句柄 */(void *)&ucQueueMsgValue, /* 存儲接收到的數據到變量ucQueueMsgValue中 */(TickType_t)xMaxBlockTime);/* 設置阻塞時間 */if(xResult == pdPASS){/* 成功接收,并通過串口將數據打印出來 */printf("接收到消息隊列數據ucQueueMsgValue = %d\r\n", ucQueueMsgValue);Board_LED_Toggle(1);}else{/* 超時 */Board_LED_Toggle(4);}} }/* ********************************************************************************************************* * 函 數 名: AppObjCreate * 功能說明: 創建任務通信機制 * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ static void AppObjCreate (void) {/* 創建10個uint8_t型消息隊列 */xQueue1 = xQueueCreate(10, sizeof(uint8_t));if( xQueue1 == 0 ){/* 沒有創建成功,用戶可以在這里加入創建失敗的處理機制 */DEBUGSTR("隊列1創建失敗\n");}/* 創建10個存儲指針變量的消息隊列,由于CM3/CM4內核是32位機,一個指針變量占用4個字節 */xQueue2 = xQueueCreate(10, sizeof(struct Msg *));if( xQueue2 == 0 ){/* 沒有創建成功,用戶可以在這里加入創建失敗的處理機制 */DEBUGSTR("隊列2創建失敗\n");} } /************************************************************************ @ 函數名 : AppTaskCreate* @ 功能說明: 為了方便管理,所有的任務創建函數都放在這個函數里面* @ 參數 : 無 * @ 返回值 : 無**********************************************************************/ static void AppTaskCreate() {BaseType_t xReturn=pdPASS;/*定義任務返回值*/taskENTER_CRITICAL();//進入臨界區,禁止中斷打斷xReturn=xTaskCreate(vLED1_Task, "vLED1_Task",TASK_STACK_SIZE*2, NULL, (tskIDLE_PRIORITY + 1UL),(TaskHandle_t *) &LED1_Task_Handle);xReturn=xTaskCreate(vKEY_task, "vKEY_Task",TASK_STACK_SIZE*4, NULL, (tskIDLE_PRIORITY + 1UL),(TaskHandle_t *) &KEY_Task_Handle);xReturn=xTaskCreate(vTaskMsgPro, "vTaskMsgPro",TASK_STACK_SIZE*5, NULL, (tskIDLE_PRIORITY + 3UL),NULL);if(pdPASS==xReturn){printf("創建LED_Task任務成功\r\n");} // vTaskDelete(LED1_Task_Handle);//刪除AppTaskCreate任務 // vTaskDelete(UART_Task_Handle);//刪除AppTaskCreate任務taskEXIT_CRITICAL(); //退出臨界區}/*** @brief main routine for blinky example* @return Function should not exit.*/ int main(void) {prvSetupHardware();Board_UARTPutSTR("LPC824 FreeRTOS 任務管理\n\r");printf("Key按下掛起任務,Key按下恢復任務\r\n");AppTaskCreate();/* 創建任務通信機制 */AppObjCreate();vTaskStartScheduler();//任務調度/* Loop forever */while (1) {printf("FreeRTOS 運行失敗\n\r");}}任務標志事件
按鍵任務里
按鍵任務里置位標志
按下按鍵2,向隊列1里發送消息,每按一次發送的數據加1。
按下按鍵3,向消息隊列2里發數據,每按一次發送三組數據。
LED任務,接收消息隊列2的數據。
消息任務里
兩個標志同時置位后,翻轉LED2。
實驗現象
按下按鍵2,LED1狀態翻轉。按下按鍵3,LED1狀態翻轉。
函數:
xQueueCreate();
xQueueReceive();
xQueueSend();
總結
以上是生活随笔為你收集整理的18 freertos消息队列-任务通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一些Cocos游戏引擎开发工具
- 下一篇: Headroom.js – 快速响应用户