日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

18 freertos消息队列-任务通信

發布時間:2024/3/24 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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消息队列-任务通信的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。