freeRTOS中文實用教程2--隊列


1.前言

freeRTOS中所有任務的通信和同步機制都是基於隊列來實現。

2.隊列的特點

圖 隊列的讀寫操作

  • 隊列的數據存儲

(1)隊列可以保存有限個具有確定長度的數據單元,隊列可以保存的最大單元數目稱為隊列的深度;

(2)隊列創建時需要設定隊列深度和每個單元的大小;

(3)隊列先進先出

  • 多任務存取

隊列是內核中具有獨立權限的對象,不屬於任何任務,可以有多個任務進行讀寫

  • 讀隊列阻塞

(1)任務讀取隊列數據時可以指定一個阻塞超時時間;

(2)未超過阻塞超時時間,隊列為空,任務將保持阻塞狀態;

(3)隊列中寫入數據,任務將由阻塞態轉為就緒態;或者阻塞時間超過了阻塞超時時間,任務也將由阻塞態轉為就緒態;

(4)可能會有多個任務處於阻塞態等待讀取隊列中的數據;

(5)隊列數據有效,優先級最高的任務會解除阻塞,相同優先級則等待時間最長的任務會解除阻塞

  • 寫隊列阻塞

(1)任務寫入隊列數據時可以指定一個阻塞超時時間;

(2)未超過阻塞超時時間,隊列滿,任務將保持阻塞狀態;

(3)隊列有空閑,任務將由阻塞態轉為就緒態;或者阻塞時間超過了阻塞超時時間,任務也將由阻塞態轉為就緒態;

(4)可能會有多個任務處於阻塞態等待向隊列中的寫入數據;

(5)隊列有空閑,優先級最高的任務會解除阻塞,相同優先級則等待時間最長的任務會解除阻塞

3. 使用隊列傳遞復合數據類型

 

圖 結構體用於隊列傳遞舉例

一般是通過傳遞復合數據類型的指針來實現

4.使用隊列傳遞指針

  • 如果隊列存儲的數據單元尺寸較大,那最好是利用隊列來傳遞數據的指針
  • 利用隊列傳遞指針時,一定要十分小心地做到以下兩點

(1)指針指向的內存空間的所有權必須明確

不會有任意兩個任務同時修改共享內存中的數據 .原則上,共享內存在其指針發送到隊列之前,其內容只允許被發送任務訪問;

共享內存指針從隊列中被讀出之后,其內容亦只允許被接收任務訪問 

(2)指針指向的內存空間必須有效 

如果指針指向的內存空間是動態分配的,只應該有一個任務負責對其進行內存釋放。當這段內存空間被釋放之后,就不應該有任何一個任務再訪問這段空間

 注:切忌用指針訪問任務棧上分配的空間。因為當棧幀發生改變后,棧上的數據將不再有效

5.隊列操作API

API原型 函數說明 參數說明 返回值
xQueueCreate( uxQueueLength, uxItemSize ) 用於創建一個隊列,並返回一個 xQueueHandle 句柄以便於對其創建的隊列進行引用 。當創建隊列時, FreeRTOS 從堆空間中分配內存空間。分配的空間用於存儲隊列數據結構本身以及隊列中包含的數據單元。如果內存堆中沒有足夠的空間來創建隊列,xQueueCreate()將返回 NULL

  • uxQueueLength

隊列能夠存儲的最大單元數目,即隊列深度。

  • uxItemSize

隊列中數據單元的長度,以字節為單位

NULL 表示沒有足夠的堆空間分配給隊列而導致創建失敗。
NULL 值表示隊列創建成功。此返回值應當保存下來,以作為
操作此隊列的句柄
xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueSendToBack()用於將數據發送到隊列尾
  • xQueue

目標隊列的句柄

  • pvItemToQueue

發送數據的指針

  • xTicksToWait

阻塞超時時間。如果在發送時隊列已滿,這個時間即是任務處於阻塞態等待隊列空間有效的最長等待時間

 
xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) 用於將數據發送到隊列首
 

pdPASS
返回 pdPASS 只會有一種情況,那就是數據被成功發送到隊列

errQUEUE_FULL
如 果 由 於 隊 列 已 滿 而 無 法 將 數 據 寫 入 , 則 將 返 回
errQUEUE_FULL

xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) 用於在中斷服務中實現相同的功能
   
xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) 用於在中斷服務中實現相同的功能     

xQueueReceive

xQueuePeek 

用於從隊列中接收(讀取)數據單元。接收到的單元同時會從隊列中刪除

也是從從隊列中接收數據單元,不同的是並不從隊列中刪出接收到的單元 

注:切記不要在中斷服務例程中調用 xQueueRceive()xQueuePeek()

   
xQueueReceiveFromISR
     
 uxQueueMessagesWaiting

 用於查詢隊列中當前有效數據單元個數

切記不要在中斷服務例程中調用 uxQueueMessagesWaiting()

   
 uxQueueMessagesWaitingFromISR
     

6. 執行流程舉例

send1和sender2負責寫隊列,receiver負責讀隊列:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM