在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

單片機(jī)消息隊列的實現(xiàn)原理和機(jī)制

strongerHuang ? 來源: strongerHuang ? 2023-05-26 09:50 ? 次閱讀

單片機(jī)開發(fā)過程中通常會用到“消息隊列”,一般實現(xiàn)的方法有多種。 本文給大家分享一下隊列實現(xiàn)的原理和機(jī)制。

環(huán)形隊列

環(huán)形隊列是在實際編程極為有用的數(shù)據(jù)結(jié)構(gòu),它是一個首尾相連的FIFO的數(shù)據(jù)結(jié)構(gòu),采用數(shù)組的線性空間,數(shù)據(jù)組織簡單,能很快知道隊列是否滿為空,能以很快速度的來存取數(shù)據(jù)。

環(huán)形隊列通常用于通信領(lǐng)域,比如UARTUSBCAN網(wǎng)絡(luò)等。

1.環(huán)形隊列實現(xiàn)原理

內(nèi)存上沒有環(huán)形的結(jié)構(gòu),因此環(huán)形隊列實上是數(shù)組的線性空間來實現(xiàn)。 當(dāng)數(shù)據(jù)到了尾部它將轉(zhuǎn)回到0位置來處理。

因此環(huán)列隊列的邏輯:將數(shù)組元素q[0]與q[MAXN-1]連接,形成一個存放隊列的環(huán)形空間。

為了方便讀寫,還要用數(shù)組下標(biāo)來指明隊列的讀寫位置。 head/tail.其中head指向可以讀的位置,tail指向可以寫的位置。

wKgZomRwEQeAZHOsAAAztrtbyhU714.jpg

環(huán)形隊列的關(guān)鍵是判斷隊列為空,還是為滿。 當(dāng)tail追上head時,隊列為滿時; 當(dāng)head追上tail時,隊列為空。 但如何知道誰追上誰,還需要一些輔助的手段來判斷.

如何判斷環(huán)形隊列為空,為滿有兩種判斷方法:

a.附加一個標(biāo)志位tag

當(dāng)head趕上tail,隊列空,則令tag=0

當(dāng)tail趕上head,隊列滿,則令tag=1

b.限制tail趕上head,即隊尾結(jié)點與隊首結(jié)點之間至少留有一個元素的空間。

隊列空: head==tail

隊列滿: (tail+1)% MAXN ==head


2.附加標(biāo)志實現(xiàn)原理

a.采用第一個環(huán)形隊列有如下結(jié)構(gòu):

typedef struct ringq{
   int head; /* 頭部,出隊列方向*/
   int tail; /* 尾部,入隊列方向*/ 
   int tag ;
   int size ; /* 隊列總尺寸 */
   int space[RINGQ_MAX]; /* 隊列空間 */
}RINGQ;
初始化狀態(tài):
q->head = q->tail = q->tag = 0;
隊列為空:
( q->head == q->tail) && (q->tag == 0)
隊列為滿 :
 ((q->head == q->tail) && (q->tag == 1))
入隊操作,如隊列不滿,則寫入:
q->tail =  (q->tail + 1) % q->size ;
出隊操作,如果隊列不空,則從head處讀出。

下一個可讀的位置在:
q->head =  (q->head + 1) % q->size
b.完整代碼

頭文件ringq.h:
#ifndef __RINGQ_H__
#define __RINGQ_H__


#ifdef __cplusplus
extern "C" {
#endif 


#define QUEUE_MAX 20


typedef struct ringq{
   int head; /* 頭部,出隊列方向*/
   int tail; /* 尾部,入隊列方向*/ 
   int tag ; /* 為空還是為滿的標(biāo)志位*/
    int size ; /* 隊列總尺寸 */
   int space[QUEUE_MAX]; /* 隊列空間 */
}RINGQ;


/* 
  第一種設(shè)計方法:
     當(dāng)head == tail 時,tag = 0 為空,等于 = 1 為滿。
*/


extern int ringq_init(RINGQ * p_queue);


extern int ringq_free(RINGQ * p_queue);




/* 加入數(shù)據(jù)到隊列 */
extern int ringq_push(RINGQ * p_queue,int data);


/* 從隊列取數(shù)據(jù) */
extern int ringq_poll(RINGQ * p_queue,int *p_data);




#define ringq_is_empty(q) ( (q->head == q->tail) && (q->tag == 0))


#define ringq_is_full(q) ( (q->head == q->tail) && (q->tag == 1))


#define print_ringq(q) printf("ring head %d,tail %d,tag %d
", q->head,q->tail,q->tag);
#ifdef __cplusplus
}
#endif 


#endif /* __RINGQ_H__ */
源代碼 ringq.c:
#include 
#include "ringq.h"


int ringq_init(RINGQ * p_queue)
{
   p_queue->size = QUEUE_MAX ;


   p_queue->head = 0;
   p_queue->tail = 0;


   p_queue->tag = 0;


   return 0;
}


int ringq_free(RINGQ * p_queue)
{
  return 0;
}




int ringq_push(RINGQ * p_queue,int data)
{
  print_ringq(p_queue);


  if(ringq_is_full(p_queue))
   {


     printf("ringq is full
");
     return -1;
   }


   p_queue->space[p_queue->tail] = data;


   p_queue->tail = (p_queue->tail + 1) % p_queue->size ;


   /* 這個時候一定隊列滿了*/
   if(p_queue->tail == p_queue->head)
    {
       p_queue->tag = 1;
    }


    return p_queue->tag ;  
}


int ringq_poll(RINGQ * p_queue,int * p_data)
{
   print_ringq(p_queue);
  if(ringq_is_empty(p_queue))
   {


      printf("ringq is empty
");
     return -1;
   }


   *p_data = p_queue->space[p_queue->head];


   p_queue->head = (p_queue->head + 1) % p_queue->size ;


    /* 這個時候一定隊列空了*/
   if(p_queue->tail == p_queue->head)
    {
       p_queue->tag = 0;
    }    
    return p_queue->tag ;
}

看到源代碼,相信大家就明白其中原理了。其實還有不采用tag,或者其他一些標(biāo)志的方法,這里就不進(jìn)一步展開講述了,感興趣的讀者可以自行研究一下。

消息隊列

RTOS中基本都有消息隊列這個組件,也是使用最常見的組件之一。

1.消息隊列的基本概念

消息隊列是一種常用于任務(wù)間通信的數(shù)據(jù)結(jié)構(gòu),隊列可以在任務(wù)與任務(wù)間、中斷和任務(wù)間傳遞信息,實現(xiàn)了任務(wù)接收來自其他任務(wù)或中斷的不固定長度的消息。

通過消息隊列服務(wù),任務(wù)或中斷服務(wù)程序可以將一條或多條消息放入消息隊列中。同樣,一個或多個任務(wù)可以從消息隊列中獲得消息。

使用消息隊列數(shù)據(jù)結(jié)構(gòu)可以實現(xiàn)任務(wù)異步通信工作。

2.消息隊列的特性

RTOS消息隊列,常見特性:

消息支持先進(jìn)先出方式排隊,支持異步讀寫工作方式。

讀寫隊列均支持超時機(jī)制。

消息支持后進(jìn)先出方式排隊,往隊首發(fā)送消息(LIFO)。

可以允許不同長度(不超過隊列節(jié)點最大值)的任意類型消息。

一個任務(wù)能夠從任意一個消息隊列接收和發(fā)送消息。

多個任務(wù)能夠從同一個消息隊列接收和發(fā)送消息。

當(dāng)隊列使用結(jié)束后,可以通過刪除隊列函數(shù)進(jìn)行刪除。

3.消息隊列的原理

這里以 FreeRTOS 為例進(jìn)行說明。FreeRTOS 的消息隊列控制塊由多個元素組成,當(dāng)消息隊列被創(chuàng)建時,系統(tǒng)會為控制塊分配對應(yīng)的內(nèi)存空間,用于保存消息隊列的一些信息如消息的存儲位置,頭指針 pcHead、尾指針 pcTail、消息大小 uxItemSize 以及隊列長度 uxLength 等

wKgZomRwEOaAAVkKAAUULUbui9o464.png

比如創(chuàng)建消息隊列:

xQueue = xQueueCreate(QUEUE_LEN, QUEUE_SIZE);

任務(wù)或者中斷服務(wù)程序都可以給消息隊列發(fā)送消息,當(dāng)發(fā)送消息時,如果隊列未滿或者允許覆蓋入隊,F(xiàn)reeRTOS 會將消息拷貝到消息隊列隊尾,否則,會根據(jù)用戶指定的阻塞超時時間進(jìn)行阻塞,在這段時間中,如果隊列一直不允許入隊,該任務(wù)將保持阻塞狀態(tài)以等待隊列允許入隊。 當(dāng)其它任務(wù)從其等待的隊列中讀取入了數(shù)據(jù)(隊列未滿),該任務(wù)將自動由阻塞態(tài)轉(zhuǎn)移為就緒態(tài)。 當(dāng)?shù)却臅r間超過了指定的阻塞時間,即使隊列中還不允許入隊,任務(wù)也會自動從阻塞態(tài)轉(zhuǎn)移為就緒態(tài),此時發(fā)送消息的任務(wù)或者中斷程序會收到一個錯誤碼 errQUEUE_FULL。

發(fā)送緊急消息的過程與發(fā)送消息幾乎一樣,唯一的不同是,當(dāng)發(fā)送緊急消息時, 發(fā)送的位置是消息隊列隊頭而非隊尾,這樣,接收者就能夠優(yōu)先接收到緊急消息,從而及時進(jìn)行消息處理。

當(dāng)某個任務(wù)試圖讀一個隊列時,其可以指定一個阻塞超時時間。 在這段時間中,如果隊列為空,該任務(wù)將保持阻塞狀態(tài)以等待隊列數(shù)據(jù)有效。 當(dāng)其它任務(wù)或中斷服務(wù)程序往其等待的隊列中寫入了數(shù)據(jù),該任務(wù)將自動由阻塞態(tài)轉(zhuǎn)移為就緒態(tài)。 當(dāng)?shù)却臅r間超過了指定的阻塞時間,即使隊列中尚無有效數(shù)據(jù),任務(wù)也會自動從阻塞態(tài)轉(zhuǎn)移為就緒態(tài)。

當(dāng)消息隊列不再被使用時,應(yīng)該刪除它以釋放系統(tǒng)資源,一旦操作完成, 消息隊列將被永久性的刪除。

消息隊列的運(yùn)作過程具體見下圖:

wKgaomRwEMuAEr8ZAAD-lTL-UDw319.png

4.消息隊列的阻塞機(jī)制

出隊阻塞:當(dāng)且僅當(dāng)消息隊列有數(shù)據(jù)的時候,任務(wù)才能讀取到數(shù)據(jù),可以指定等待數(shù)據(jù)的阻塞時間。

入隊阻塞:當(dāng)且僅當(dāng)隊列允許入隊的時候,發(fā)送者才能成功發(fā)送消息; 隊列中無可用消息空間時,說明消息隊列已滿,此時,系統(tǒng)會根據(jù)用戶指定的阻塞超時時間將任務(wù)阻塞。

假如有多個任務(wù)阻塞在一個消息隊列中,那么這些阻塞的任務(wù)將按照任務(wù)優(yōu)先級進(jìn)行排序,優(yōu)先級高的任務(wù)將優(yōu)先獲得隊列的訪問權(quán)。

“環(huán)形隊列”和“消息隊列”的異同

通過以上分析,你會發(fā)現(xiàn)“環(huán)形隊列”和“消息隊列”之間有很多共同點:

1.他們都是一種數(shù)據(jù)結(jié)構(gòu),結(jié)構(gòu)中都包含頭、尾、標(biāo)志等信息;

2.它們都是分配一塊連續(xù)的內(nèi)存空間,且都可以分配多個隊列。

3.應(yīng)用場景類似,有大量吞吐數(shù)據(jù)的情況下,比如通信領(lǐng)域。

當(dāng)然,他們也有一些不同點:

1.“環(huán)形隊列”可以獨(dú)立使用,也可以結(jié)合操作系統(tǒng)使用。 而消息隊列依賴RTOS(有些RTOS的參數(shù)信息)。

2.“環(huán)形隊列”占用資源更小,更適合于資源較小的系統(tǒng)中。

3.“消息隊列”結(jié)合RTOS應(yīng)用更加靈活,比如延時、中斷傳輸數(shù)據(jù)等。

最后,這兩種隊列應(yīng)用都比較廣,建議抽空都研究一下。

審核編輯:湯梓紅

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

    關(guān)注

    6040

    文章

    44605

    瀏覽量

    637221
  • uart
    +關(guān)注

    關(guān)注

    22

    文章

    1243

    瀏覽量

    101585
  • RTOS
    +關(guān)注

    關(guān)注

    22

    文章

    818

    瀏覽量

    119781
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    573

    瀏覽量

    40184
  • 消息隊列
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    3011

原文標(biāo)題:單片機(jī)消息隊列的實現(xiàn)原理和機(jī)制

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    單片機(jī)的中斷處理機(jī)制詳解

    單片機(jī)多用于物聯(lián)網(wǎng)、自動控制系統(tǒng)、智能家電等領(lǐng)域,要求單片機(jī)能夠?qū)崟r響應(yīng)外部觸發(fā)的事件,中斷機(jī)制單片機(jī)響應(yīng)外部事件的重要方法。
    發(fā)表于 10-31 14:46 ?3035次閱讀
    <b class='flag-5'>單片機(jī)</b>的中斷處理<b class='flag-5'>機(jī)制</b>詳解

    如何使用ITM機(jī)制實現(xiàn)調(diào)試stm32單片機(jī)實現(xiàn)printf與scanf?

    如何使用ITM機(jī)制實現(xiàn)調(diào)試stm32單片機(jī)實現(xiàn)printf與scanf?
    發(fā)表于 12-02 06:53

    怎樣去使用基于單片機(jī)實現(xiàn)隊列功能模塊QueueForMcu呢

    基于單片機(jī)實現(xiàn)隊列功能模塊QueueForMcu有何特性?怎樣去使用基于單片機(jī)實現(xiàn)隊列功能模
    發(fā)表于 02-23 06:39

    51單片機(jī)多任務(wù)機(jī)制實現(xiàn)策略研究

    從操作系統(tǒng)實現(xiàn)多任務(wù)機(jī)制的原理入手,分析了51單片機(jī)實現(xiàn)多任務(wù)機(jī)制的基本條件,論述了5l單片機(jī)
    發(fā)表于 09-19 17:26 ?159次下載
    51<b class='flag-5'>單片機(jī)</b>多任務(wù)<b class='flag-5'>機(jī)制</b>的<b class='flag-5'>實現(xiàn)</b>策略研究

    單片機(jī)實現(xiàn)舵機(jī)轉(zhuǎn)角控制

    單片機(jī)實現(xiàn)舵機(jī)轉(zhuǎn)角控制單片機(jī)實現(xiàn)舵機(jī)轉(zhuǎn)角控制單片機(jī)實現(xiàn)舵機(jī)轉(zhuǎn)角控制
    發(fā)表于 04-28 14:57 ?24次下載

    51單片機(jī)等串口緩存隊列的C語言程序說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是51單片機(jī)等串口緩存隊列的C語言程序說明資料免費(fèi)下載。
    發(fā)表于 06-27 17:42 ?3次下載
    51<b class='flag-5'>單片機(jī)</b>等串口緩存<b class='flag-5'>隊列</b>的C語言程序說明

    單片機(jī)開發(fā)——應(yīng)用消息隊列處理事件

    單片機(jī)開發(fā)——應(yīng)用消息隊列處理事件
    發(fā)表于 11-13 13:36 ?11次下載
    <b class='flag-5'>單片機(jī)</b>開發(fā)——應(yīng)用消息<b class='flag-5'>隊列</b>處理事件

    單片機(jī)串口——隊列的使用

    背景??最近做單片機(jī)開發(fā)經(jīng)常遇見要用串口接收數(shù)據(jù)的情況,實際項目中肯定不能當(dāng)串口接收中斷一來就去處理,于是我們可以用到隊列這個數(shù)據(jù)結(jié)構(gòu)來保存上一幀數(shù)據(jù),想用的時候取出即可。開始新建隊列結(jié)構(gòu)體
    發(fā)表于 11-13 20:36 ?16次下載
    <b class='flag-5'>單片機(jī)</b>串口——<b class='flag-5'>隊列</b>的使用

    循環(huán)隊列原理及在單片機(jī)串口通訊的應(yīng)用(二)

    的使用 硬件環(huán)境 falling-star board(自設(shè)計,下期開源資料,主控STM32f103RET6) 軟件環(huán)境 keil5 cubemx cubemx配置1、 時鐘的配置,??無論什么平臺,什么單片機(jī),第一步,我想都是要搞清楚時鐘,時鐘是一
    發(fā)表于 11-23 18:21 ?8次下載
    循環(huán)<b class='flag-5'>隊列</b>原理及在<b class='flag-5'>單片機(jī)</b>串口通訊的應(yīng)用(二)

    QueueForMcu 基于單片機(jī)實現(xiàn)隊列功能模塊

    QueueForMcu基于單片機(jī)實現(xiàn)隊列功能模塊,主要用于8位、16位、32位非運(yùn)行RTOS的單片機(jī)應(yīng)用,兼容大多數(shù)單片機(jī)平臺。一、特性動
    發(fā)表于 12-31 19:35 ?1次下載
    QueueForMcu 基于<b class='flag-5'>單片機(jī)</b><b class='flag-5'>實現(xiàn)</b>的<b class='flag-5'>隊列</b>功能模塊

    ZWave中的消息隊列機(jī)制是什么

    這篇文章就來看看 ZWave 中是通過什么機(jī)制為我們提供了一個便捷的消息隊列處理機(jī)制
    的頭像 發(fā)表于 02-14 13:41 ?815次閱讀
    ZWave中的消息<b class='flag-5'>隊列</b><b class='flag-5'>機(jī)制</b>是什么

    一種基于單片機(jī)實現(xiàn)隊列功能模塊

    基于單片機(jī)實現(xiàn)隊列功能模塊,主要用于8位、16位、32位非運(yùn)行RTOS的單片機(jī)應(yīng)用,兼容大多數(shù)單片機(jī)平臺。
    的頭像 發(fā)表于 08-14 11:09 ?896次閱讀
    一種基于<b class='flag-5'>單片機(jī)</b><b class='flag-5'>實現(xiàn)</b>的<b class='flag-5'>隊列</b>功能模塊

    單片機(jī)用按鈕中斷函數(shù)

    單片機(jī)用按鈕中斷函數(shù)? 單片機(jī)中斷是一種能夠使單片機(jī)響應(yīng)外部信號的機(jī)制,這種機(jī)制允許單片機(jī)在處理
    的頭像 發(fā)表于 09-01 10:17 ?1585次閱讀

    單片機(jī)裸機(jī)實現(xiàn)隊列功能的方案

    單片機(jī)裸機(jī)實現(xiàn)隊列功能的方案
    的頭像 發(fā)表于 10-17 14:34 ?606次閱讀

    單片機(jī)的中斷機(jī)制

    單片機(jī)的中斷機(jī)制是一種重要的處理方式,它允許單片機(jī)在執(zhí)行主程序的過程中,能夠暫停當(dāng)前任務(wù),轉(zhuǎn)而處理外部或內(nèi)部緊急事件。這種機(jī)制極大地提高了系統(tǒng)的響應(yīng)速度和處理能力,使得
    的頭像 發(fā)表于 10-17 18:03 ?890次閱讀
    主站蜘蛛池模板: 在线你懂的视频| 中文字幕第7页| 国产成人精品影视| 狠狠操亚洲| 国产黄mmd在线观看免费| japanese色系tube日本护士| 五月丁香| 直接黄91麻豆网站| 美女扒开尿口给男人桶视频免费 | 天天色天天做| 免费一级特黄特色大片| 国产手机看片| 最新亚洲一区二区三区四区| 日本口工全彩无遮拦漫画大| 亚洲综合色一区二区三区小说| 天堂网bt| 免费中国一级啪啪片| 国产馆精品推荐在线观看| 亚洲丁香网| 波多野结衣久久精品| 日本在线一区| 天天精品视频在线观看资源| 欧美伦理影院| 国产tube| 久久草在线看| 性视频网址| 四虎影院4hu| 国产综合图片| 天天射天天色天天干| 成人激情视频网| 男人j进入女人j在线视频| 婷色| 久久99综合| 天天干天天拍天天操| 日本sese| 亚洲成a人v在线观看| 美女中出视频| 天天插日日插| 一区二区三区网站| 特黄特色三级在线播放| 好看的一级毛片|