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