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

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

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

如何使用消息隊(duì)列進(jìn)行通信

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

引言

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

介紹

消息隊(duì)列概念

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

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

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

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

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

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

    其中:

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

    xQueueReceive(QueueHandle,&queue_buffer,time);

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

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

實(shí)例

需求分析

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

發(fā)送消息

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

void USART3_IRQHandler(void)
{
	uint8_t Res;
if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_RXNE)!=RESET)//檢測(cè)到有單個(gè)字節(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)建一個(gè)任務(wù),此任務(wù)的重要功能就是接收消息隊(duì)列中的消息。我們將接受到的消息的大小和內(nèi)容通過串口發(fā)送出來。沒有消息的時(shí)候,一直實(shí)現(xiàn)LED的閃爍。

void LEDToggleTesk(void const * argument)
{
  /* USER CODE BEGIN LEDToggleTesk */
  BaseType_t xReturn=pdTRUE;//定義一個(gè)創(chuàng)建消息返回值,默認(rèn)為pdTRUE
  UBaseType_t num_queue ;
  uint8_t Res[20];//存放我們接收到的一包數(shù)據(jù)
  uint8_t queue_buffer;
  int i=0;//接收數(shù)組下標(biāo)
  for(;;)
  {
    i=0;
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
    num_queue=uxQueueMessagesWaiting(myQueue01Handle);//獲取消息隊(duì)列中有多少數(shù)據(jù)
    while(num_queue--)
    {
      xReturn=xQueueReceive(myQueue01Handle,&queue_buffer,0);//將消息隊(duì)列中的數(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回復(fù)

Receive a frame data

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

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

    關(guān)注

    2

    文章

    431

    瀏覽量

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

    關(guān)注

    18

    文章

    1030

    瀏覽量

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

    關(guān)注

    3

    文章

    4331

    瀏覽量

    62606
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux下進(jìn)程通訊消息隊(duì)列

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

    不同VI間的隊(duì)列通信問題

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

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

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

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

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

    請(qǐng)問ESP32單核如何使用FreeRTOS測(cè)試隊(duì)列進(jìn)行任務(wù)間通信

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

    請(qǐng)問ESP32雙核如何使用隊(duì)列進(jìn)行任務(wù)間通信?

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

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

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

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

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

    什么是消息隊(duì)列?消息隊(duì)列中間件重要嗎?

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

    如何使用消息隊(duì)列進(jìn)行通信

    我們?cè)诼銠C(jī)開發(fā)中,每個(gè)函數(shù)之間進(jìn)行數(shù)據(jù)通信往往采用全局變量。而在嵌入式開發(fā)中。我們?cè)?b class='flag-5'>進(jìn)行進(jìn)程間通信的時(shí)候,往往采用消息隊(duì)列。對(duì)于操作系統(tǒng)來說,消息隊(duì)
    的頭像 發(fā)表于 01-20 16:32 ?1407次閱讀

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

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

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

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

    FreeRTOS消息隊(duì)列介紹

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

    進(jìn)程間通信的消息隊(duì)列介紹

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

    JavaWeb消息隊(duì)列使用指南

    用程序的通信方法,允許異步傳輸消息,并且具有存儲(chǔ)和轉(zhuǎn)發(fā)消息的能力。它主要解決以下問題: 異步處理 :允許系統(tǒng)組件異步處理任務(wù),提高響應(yīng)速度。 解耦系統(tǒng) :不同系統(tǒng)組件之間通過消息隊(duì)列通信,降低耦合度。 流量削峰 :在高流量情況下
    的頭像 發(fā)表于 11-25 09:27 ?147次閱讀