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

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

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

RTOS中Queue的工作原理

冬至子 ? 來源:ITRelief ? 作者:Sachefgh Xu ? 2023-07-25 15:45 ? 次閱讀

Queue概述

Queue即消息隊列是通過RTOS內(nèi)核提供的一種服務(wù)。它是一種線程間同步數(shù)據(jù)的安全方法。

隊列(Queue)是與棧對應(yīng)的概念;棧是FILO結(jié)構(gòu),而隊列是FIFO結(jié)構(gòu)。FreeRTOS原生的隊列支持從高位添加新數(shù)據(jù),但CMSIS簡化刪去了這一功能,即只能從隊列底部推入數(shù)據(jù)并且對數(shù)據(jù)類型有限制,這一簡化一般不影響使用。

圖片

  • API Description:
    1.使用**osMessageQueueNew() 創(chuàng)建隊列
    該函數(shù)會涉及
    osMessageQueueAttr_t **配置結(jié)構(gòu)體;主要用于配置Control Block和名稱;一旦使用該結(jié)構(gòu)體將導(dǎo)致只能使用靜態(tài)方式創(chuàng)建隊列;一般傳入NULL即可
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);/*
創(chuàng)建新的Queue隊列
@retval    -隊列地址(Queue Identifier)
@param     msg_count -隊列可容納的消息(變量)數(shù)量
@param     msg_size  -消息(變量)占用的空間[通常用sizeof()填入]
@param     *attr     -配置結(jié)構(gòu)體對象,一般為NULL。 當(dāng)傳入NULL時,僅使用xQueueCreate()動態(tài)創(chuàng)建對應(yīng)大小、數(shù)量的隊列;
*/

2.使用**osMessageQueueDelete() **刪除隊列

該函數(shù)能釋放隊列占用的空間并清除其中內(nèi)容和任務(wù)規(guī)劃。隊列刪除后可通過**osMessageQueueNew() **重新創(chuàng)建。

osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);/*刪除隊列
@retval     -osOK: the message queue object has been deleted.
            -osErrorParameter: parameter mq_id is NULL or invalid.
            -osErrorResource: the message queue is in an invalid state.
            -osErrorISR: osMessageQueueDelete cannot be called from interrupt service routines.
*/

3.獲取隊列配置信息

uint32_t osMessageQueueGetCapacity (osMessageQueueId_t  mq_id );
/*獲取隊列可容納的消息(變量)數(shù)量; []
*/
uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t  mq_id );
/* 獲取消息(變量)占用的空間 [單位byte]
*/
uint32_t osMessageQueueGetSpace (osMessageQueueId_t  mq_id );/*
  查詢隊列中空位(未填入變量)的數(shù)量
*/
uint32_t osMessageQueueGetCount (osMessageQueueId_t  mq_id );/*
  查詢隊列中已寫入的消息(變量)數(shù)量
*/

4.※ 讀取(取出)/寫入隊列

關(guān)于阻塞超時時間:

①讀取(取出)阻塞超時:當(dāng)任務(wù)讀一個消息隊列時,可通過osMessageQueueGet()設(shè)置阻塞超時時間。在這段時間中,如果隊列為空(無變量),該任務(wù)將保持BLOCK狀態(tài)以等待隊列數(shù)據(jù)有效。在此期間當(dāng)任務(wù)檢測到其等待的隊列中寫入了數(shù)據(jù)時,將自動由BLOCK態(tài)轉(zhuǎn)移為READY態(tài)。當(dāng)?shù)却臅r間超過了指定的阻塞時間,即使隊列中尚無數(shù)據(jù),任務(wù)也會自動從阻塞態(tài)轉(zhuǎn)移為READY態(tài)。此時程序會返回osErrorTimeout錯誤。若沒有設(shè)置阻塞超時且參數(shù)正確,返回osErrorResource錯誤**。**

由于隊列可以被多個任務(wù)讀取,所以對單個隊列而言,也可能有多個任務(wù)處于BLOCK
狀態(tài)以等待隊列數(shù)據(jù)有效。這種情況下,一旦隊列數(shù)據(jù)有效,所有等待任務(wù)中優(yōu)先級最高的任務(wù)被執(zhí)行。而如果所有等待任務(wù)的優(yōu)先級相同,那么被解除阻塞的任務(wù)將是等待最久的任務(wù)。

②寫入阻塞超時: 同讀隊列一樣,任務(wù)也可以在寫隊列時指定一個阻塞超時時間。這個時間是當(dāng)被寫隊列已滿時,任務(wù)進(jìn)入BLOCK態(tài)以等待隊列空間有效的最長時間。當(dāng)?shù)却臅r間超過了指定的阻塞時間,即使隊列中尚無數(shù)據(jù),任務(wù)也會自動從BLOCK態(tài)轉(zhuǎn)移為READY態(tài)。此時程序會返回osErrorTimeout錯誤。若沒有設(shè)置阻塞超時且參數(shù)正確,返回osErrorResource錯誤。由于隊列可以被多個任務(wù)寫入,所以對單個隊列而言,也可能有多個任務(wù)處于BLOCK
狀態(tài)以等待隊列空間有效。這種情況下,一旦隊列空間有效,所有等待任務(wù)中優(yōu)先級最高的任務(wù)被執(zhí)行。而如果所有等待任務(wù)的優(yōu)先級相同,那么被解除阻塞的任務(wù)將是等待最久的任務(wù)。

阻塞超時時間(timeout 變量)有三種配置:

==  0U     //不設(shè)置阻塞超時時間,若出現(xiàn)上述隊列異常函數(shù)將直接報錯返回
 ==  osWaitForever  //任務(wù)將一直阻塞直到空隊列被寫入/滿隊列被取出數(shù)據(jù)
 ==  Ticks   //設(shè)置具體等待時間,單位為RTOS心跳數(shù)(Ticks)

①用 osMessageQueueGet() 取出數(shù)據(jù)**【※可在中斷中使用】**

osStatus_t osMessageQueueGet ( osMessageQueueId_t  mq_id,
void *  msg_ptr,       //儲存讀取結(jié)果的變量地址
uint8_t *  msg_prio,  // ==NULL
uint32_t  timeout    //阻塞超時時間
);

①用 osMessageQueuePut() 寫入**【※可在中斷中使用】**

osStatus_t osMessageQueuePut ( osMessageQueueId_t  mq_id,
const void *  msg_ptr,     //儲存寫入內(nèi)容的變量地址
uint8_t  msg_prio,        //==0U
uint32_t  timeout         //阻塞超時時間
);

讀出/寫入的返回狀態(tài)值:

-osOK: 取出/寫入成功
-osErrorTimeout: the message could not be retrieved from/put into the queue in the given time (timed-wait semantics).
-osErrorResource: nothing to get from the queue or no space to push.
-osErrorParameter: parameter mq_id is NULL or invalid, non-zero timeout specified in an ISR.

5.清空隊列

osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id);/*
@retval:      -osOK: the message queue has been rest.
              -osErrorParameter: parameter mq_id is NULL or invalid.
              -osErrorResource: the message queue is in an invalid state.
              -osErrorISR: osMessageQueueReset cannot be called from interrupt service routines.
*/
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • CMSIS
    +關(guān)注

    關(guān)注

    0

    文章

    39

    瀏覽量

    11856
  • RTOS
    +關(guān)注

    關(guān)注

    21

    文章

    809

    瀏覽量

    119362
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    483

    瀏覽量

    61918
  • Queue
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    7251
  • FIFO存儲
    +關(guān)注

    關(guān)注

    0

    文章

    103

    瀏覽量

    5955
收藏 人收藏

    評論

    相關(guān)推薦

    感光太陽能燈工作原理。#工作原理大揭秘

    太陽工作原理DIY
    jf_24750660
    發(fā)布于 :2022年11月07日 22:26:04

    RTOS的定時功能

    RTOS
    橙群微電子
    發(fā)布于 :2023年02月27日 09:42:16

    【MiCOKit試用體驗】慶科MiCO系統(tǒng)篇(4)MiCO RTOS消息隊列

    對象的最大數(shù)量(2)OSStatus mico_rtos_push_to_queue(mico_queue_t* queue, void* message, uint32_t tim
    發(fā)表于 10-24 17:03

    Queue Management、Queue Proxy Regions和Queue Peek Region幾個寄存器的主要區(qū)別是什么?

    Queue Management、Queue Proxy Regions和Queue Peek Region幾個寄存器的主要區(qū)別是什么? 我看到手冊上介紹的 Queue N Regis
    發(fā)表于 06-19 04:28

    消息隊列Queue相關(guān)資料推薦

    消息隊列QueueAPItx_queue_createtx_queue_deletex_queue_flushtx_queue_front_sendtx_queue_receivetx_queue_send_notifyAPItx_queue_createtx_queue_deletetx_queue_flushtx_qu
    發(fā)表于 02-22 06:53

    RT-Thread的data_queue是什么?怎樣去使用

    1. data_queue 是什么data_queue 直接翻譯過來是 數(shù)據(jù)隊列。這個名字和 消息隊列 很像。那么他們有什么區(qū)別呢?消息隊列:消息隊列能夠接收來自線程或中斷服務(wù)例程不固定
    發(fā)表于 04-15 15:56

    請問使用httpd_queue_work的目的是什么?

    您好,我正在查看 http 服務(wù)器組件并找到了這個函數(shù):httpd_queue_work。追溯源碼發(fā)現(xiàn),它只是要求http服務(wù)器線程立即調(diào)用工作回調(diào)。回調(diào)不會在獨立線程調(diào)用。我想知道使用這個功能
    發(fā)表于 03-02 08:28

    Linux之work_queue_share教程

    Linux之work_queue_share教程,很好的Linux資料,快來學(xué)習(xí)吧
    發(fā)表于 04-15 17:49 ?13次下載

    Linux之work_queue_custom教程

    Linux之work_queue_custom教程,很好的Linux自學(xué)資料,快來學(xué)習(xí)吧。
    發(fā)表于 04-15 17:49 ?8次下載

    Linux之work_queue_delay_work教程

    Linux之work_queue_delay_work教程,很好的Linux自學(xué)資料,快來學(xué)習(xí)吧。
    發(fā)表于 04-15 17:54 ?12次下載

    ThreadX(九)------消息隊列Queue

    消息隊列QueueAPItx_queue_createtx_queue_deletex_queue_flushtx_queue_front_sendtx_queue_receivetx_queue_send_notifyAPItx_queue_createtx_queue_deletetx_queue_flushtx_qu
    發(fā)表于 12-28 19:35 ?2次下載
    ThreadX(九)------消息隊列<b class='flag-5'>Queue</b>

    隊列Queue的常用方法有哪些

    FIFO(先入先出)隊列Queue,LIFO(后入先出)隊列LifoQueue,和優(yōu)先級隊列PriorityQueue。
    的頭像 發(fā)表于 08-19 10:24 ?5613次閱讀
    隊列<b class='flag-5'>Queue</b>的常用方法有哪些

    什么是queue?

    queue 容器,又稱隊列容器,是簡單地裝飾deque容器而成為另外的一種容器。
    的頭像 發(fā)表于 02-27 15:43 ?1498次閱讀

    電源電容工作原理 電源設(shè)計的電容選用規(guī)則

    電源電容工作原理 電源設(shè)計的電容選用規(guī)則? 電源的電容器是電路設(shè)計不可缺少的元件之一。它在電源的
    的頭像 發(fā)表于 11-29 11:35 ?894次閱讀

    基于RTOS的應(yīng)用進(jìn)程的典型線程

    RTOS的關(guān)鍵因素是最小的中斷延遲和最小的線程切換延遲。RTOS的價值在于它的響應(yīng)速度或可預(yù)測性,而不是它在給定時間段內(nèi)可以執(zhí)行的工作量。
    發(fā)表于 03-05 09:32 ?498次閱讀
    基于<b class='flag-5'>RTOS</b>的應(yīng)用進(jìn)程<b class='flag-5'>中</b>的典型線程