0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何使用消息隊列進行通信

汽車電子技術(shù) ? 來源:物聯(lián)網(wǎng)知識 ? 作者: 跋扈洋 ? 2023-01-20 11:42 ? 次閱讀

引言

我們在裸機開發(fā)中,每個函數(shù)之間進行數(shù)據(jù)通信往往采用全局變量。而在嵌入式開發(fā)中。我們在進行進程間通信的時候,往往采用消息隊列。對于操作系統(tǒng)來說,消息隊列是非常重要的一個數(shù)據(jù)結(jié)構(gòu)。本文將介紹一下,如何使用消息隊列進行通信。

介紹

消息隊列概念

隊列又稱消息隊列,是一種常用于任務(wù)間通信的數(shù)據(jù)結(jié)構(gòu),隊列可以在任務(wù)與任務(wù)間、中斷和任務(wù)間傳遞信息,實現(xiàn)了任務(wù)接收來自其他任務(wù)或中斷的不固定長度的消息,任務(wù)能夠從隊列里面讀取消息,當隊列中的消息是空時,讀取消息的任務(wù)將被阻塞,用戶還可以指定阻塞的任務(wù)時間 xTicksToWait,在這段時間中,如果隊列為空,該任務(wù)將保持阻塞狀態(tài)以等待隊列數(shù)據(jù)有效。當隊列中有新消息時,被阻塞的任務(wù)會被喚醒并處理新消息;當?shù)却臅r間超過了指定的阻塞時間,即使隊列中尚無有效數(shù)據(jù),任務(wù)也會自動從阻塞態(tài)轉(zhuǎn)為就緒態(tài)。消息隊列是一種異步的通信方式。

FreeRTOS中的消息隊列函數(shù)

  1. 設(shè)定消息隊列的格式:osMessageQDef(myQueue, len, size);
  • myQueue是消息隊列的名稱。
  • len是消息隊列的長度(有幾個消息)
  • size是每個消息的大小,也就是每個元素的格式
  1. 創(chuàng)建消息:osMessageCreate(osMessageQ(myQueue01), NULL);

    創(chuàng)建消息的函數(shù),實際上是調(diào)用了FreeRTOS的osMessageCreate()函數(shù),只不過HAL庫進行了封裝。

  2. 向消息隊列發(fā)送消息

    我們這里來介紹在中斷中發(fā)送消息。使用函數(shù)xQueueSendFromISR(QueueHandle,&Res,time);

    其中:

  • QueueHandle:消息隊列的句柄
  • &Res:要發(fā)送的數(shù)據(jù)的地址
  • time:阻塞時間,就是如果消息隊列滿的時候,任務(wù)應(yīng)該阻塞多久
  1. 接收消息隊列中的消息

    xQueueReceive(QueueHandle,&queue_buffer,time);

  • QueueHandle:消息隊列的句柄
  • &queue_buffer:接收的消息要存放在的地址
  • time:阻塞時間,就是如果消息隊列空的時候,任務(wù)應(yīng)該阻塞多久
  1. 查詢消息隊列中消息的數(shù)量

    uxQueueMessagesWaiting(myQueue01Handle),可以返回消息隊列(句柄為myQueue01Handle)中消息的數(shù)量,返回值為整數(shù)。

實例

需求分析

此樣例我們使用PC充當上位機,上位機發(fā)送數(shù)據(jù)后,在串口中斷函數(shù)中將接收到的PC數(shù)據(jù)發(fā)送在消息隊列myQueue01Handle中,之后在一個接收線程中接收這個消息的內(nèi)容,并通過串口將接受到的消息的大小和內(nèi)容輸出出來。

發(fā)送消息

當上位機PC下發(fā)數(shù)據(jù)后,串口中斷函數(shù)將接收到的數(shù)據(jù)發(fā)送在消息隊列中。

void USART3_IRQHandler(void)
{
	uint8_t Res;
if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_RXNE)!=RESET)//檢測到有單個字節(jié)的中斷
{
	HAL_UART_Receive(&huart3,&Res,1,0Xffff); 
	xQueueSendFromISR(myQueue01Handle,&Res,0)//發(fā)送消息
}
else if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)!=RESET)//空閑中斷(代表這一幀數(shù)據(jù)傳輸完了)
{
	printf(" Receive a frame data.");
	__HAL_UART_CLEAR_IDLEFLAG(&huart3)
}

接收消息

我們創(chuàng)建一個任務(wù),此任務(wù)的重要功能就是接收消息隊列中的消息。我們將接受到的消息的大小和內(nèi)容通過串口發(fā)送出來。沒有消息的時候,一直實現(xiàn)LED的閃爍。

void LEDToggleTesk(void const * argument)
{
  /* USER CODE BEGIN LEDToggleTesk */
  BaseType_t xReturn=pdTRUE;//定義一個創(chuàng)建消息返回值,默認為pdTRUE
  UBaseType_t num_queue ;
  uint8_t Res[20];//存放我們接收到的一包數(shù)據(jù)
  uint8_t queue_buffer;
  int i=0;//接收數(shù)組下標
  for(;;)
  {
    i=0;
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
    num_queue=uxQueueMessagesWaiting(myQueue01Handle);//獲取消息隊列中有多少數(shù)據(jù)
    while(num_queue--)
    {
      xReturn=xQueueReceive(myQueue01Handle,&queue_buffer,0);//將消息隊列中的數(shù)據(jù)放在queue_buffer中
      if(xReturn)
      Res[i++]=queue_buffer;  
    }
    if(i!=0)
    printf(" count %d,LEDTask Receive %s",i,Res);//輸出接收消息的大小和內(nèi)容
    osDelay(500);
  }
}

現(xiàn)象

PC端發(fā)送123456789,MCU回復

Receive a frame data

count 8,LEDTask Receive 12345678微信截圖_20230105161930.png

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)通信
    +關(guān)注

    關(guān)注

    2

    文章

    426

    瀏覽量

    33709
  • 嵌入式開發(fā)
    +關(guān)注

    關(guān)注

    18

    文章

    1012

    瀏覽量

    47431
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4260

    瀏覽量

    62231
收藏 人收藏

    評論

    相關(guān)推薦

    Linux下進程通訊消息隊列

    進行通信。 消息隊列與 FIFO 很相似,都是一個隊列結(jié)構(gòu),都可以有多個進程往隊列里面寫信息,多個進程從
    的頭像 發(fā)表于 08-19 19:56 ?1756次閱讀
    Linux下進程通訊消息<b class='flag-5'>隊列</b>

    不同VI間的隊列通信問題

    使用生產(chǎn)者消費者循環(huán)做多VI間的數(shù)據(jù)通信,VI1中處理的數(shù)據(jù)進入VI2的隊列中,請問VI2的隊列如何在VI1中引用?點隊列引用右鍵創(chuàng)建常量么?
    發(fā)表于 12-25 14:32

    dsp與labview進行串口實時通信,每次接受的數(shù)據(jù)存在數(shù)組里還是存在隊列里呢?

    dsp與labview進行串口實時通信,每次接受的數(shù)據(jù)存在數(shù)組里還是存在隊列里呢?
    發(fā)表于 03-26 18:07

    使用隊列進行多串口通信的數(shù)據(jù)儲存有什么好方法?

    兩個串口通信,現(xiàn)需要將通訊獲得的數(shù)據(jù)存進EXCEL同一SHEET里面,想嘗試使用隊列但無法解決存進EXCEL的同一行,想問問有無更好的解決發(fā)放,現(xiàn)在兩個通信程序皆可正常運行,僅數(shù)據(jù)儲存模塊不知怎么解決。
    發(fā)表于 05-03 14:40

    為什么要使用消息隊列?消息隊列的優(yōu)缺點

    由于項目需要,在嵌入式操作系統(tǒng)的中間件設(shè)計中,采用了消息隊列來作為各個模塊之間的通信方式,同時允許用戶層的不同用戶來訪問中間件的各個模塊。 現(xiàn)在列出下面三個問題來加深對消息隊列的理解,以便后續(xù)的架構(gòu)
    發(fā)表于 12-22 06:28

    請問ESP32單核如何使用FreeRTOS測試隊列進行任務(wù)間通信?

    請問ESP32單核如何使用FreeRTOS測試隊列進行任務(wù)間通信?
    發(fā)表于 01-14 07:12

    請問ESP32雙核如何使用隊列進行任務(wù)間通信?

    隊列是什么?ESP32雙核如何使用隊列進行任務(wù)間通信
    發(fā)表于 01-14 07:24

    FreeRTOS隊列創(chuàng)建任務(wù)間通信的基本應(yīng)用程序

    應(yīng)用程序 : 此代碼是 FreeRTOS 隊列創(chuàng)建任務(wù)間通信的基本應(yīng)用程序 。 BSP 版本: M480系列 BSP CMSIS V3.04.000 硬件: NuMaker-PFM-M487
    發(fā)表于 08-22 07:12

    FreeRTOS隊列創(chuàng)建任務(wù)間通信的基本應(yīng)用程序

    應(yīng)用程序 : 此代碼是 FreeRTOS 隊列創(chuàng)建任務(wù)間通信的基本應(yīng)用程序 。 BSP 版本: M480系列 BSP CMSIS V3.04.000 硬件: NuMaker-PFM-M487
    發(fā)表于 08-30 07:56

    什么是消息隊列?消息隊列中間件重要嗎?

    應(yīng)用解耦:消息隊列減少了服務(wù)之間的耦合性,不同的服務(wù)可以通過消息隊列進行通信,而不用關(guān)心彼此的實現(xiàn)細節(jié)。
    的頭像 發(fā)表于 11-07 14:55 ?1339次閱讀

    如何使用消息隊列進行通信

    我們在裸機開發(fā)中,每個函數(shù)之間進行數(shù)據(jù)通信往往采用全局變量。而在嵌入式開發(fā)中。我們在進行進程間通信的時候,往往采用消息隊列。對于操作系統(tǒng)來說,消息
    的頭像 發(fā)表于 01-20 16:32 ?1346次閱讀

    嵌入式環(huán)形隊列和消息隊列的實現(xiàn)

    嵌入式環(huán)形隊列和消息隊列是實現(xiàn)數(shù)據(jù)緩存和通信的常見數(shù)據(jù)結(jié)構(gòu),廣泛應(yīng)用于嵌入式系統(tǒng)中的通信協(xié)議和領(lǐng)域。
    的頭像 發(fā)表于 04-14 11:52 ?1440次閱讀

    嵌入式環(huán)形隊列和消息隊列是如何去實現(xiàn)的?

    嵌入式環(huán)形隊列和消息隊列是實現(xiàn)數(shù)據(jù)緩存和通信的常見數(shù)據(jù)結(jié)構(gòu),廣泛應(yīng)用于嵌入式系統(tǒng)中的通信協(xié)議和領(lǐng)域。
    發(fā)表于 05-20 14:55 ?1054次閱讀

    FreeRTOS消息隊列介紹

    隊列是為了任務(wù)與任務(wù)、任務(wù)與中斷之間的通信而準備的,可以在任務(wù)與任務(wù)、任務(wù)與中斷之間傳遞消息,隊列中可以存儲有限的、大小固定的數(shù)據(jù)項目。任務(wù)與任務(wù)、任務(wù)與中斷之間要交流的數(shù)據(jù)保存在隊列
    的頭像 發(fā)表于 07-06 16:58 ?745次閱讀
    FreeRTOS消息<b class='flag-5'>隊列</b>介紹

    進程間通信的消息隊列介紹

    消息隊列是一種非常常見的進程間通信方式。
    的頭像 發(fā)表于 04-08 17:27 ?265次閱讀