何為消息隊列
消息隊列是用於任務與任務,中斷與任務之間通信的數據結構,具有不定長,異步的特點。消息隊列支持先進先出方式,先進入消息隊列的消息先傳給任務,同時也支持后進先出方式,即往隊首發送消息。
一個消息隊列 = 控制塊 + 單個消息空間大小 * 隊列長度。
消息隊列一旦創建無法更改消息空間大小及隊列長度,每個消息空間可以存放不大於空間容量的任意數據類型。
隊列收發機制
任務或中斷向消息隊列發送消息時,隊列未滿或者允許覆蓋,消息將拷貝到隊列隊尾,否則進入阻塞等待入隊,當等待時間超過指定阻塞時間還不允許入隊,任務從阻塞態轉為就緒態,向消息發送方返回一個錯誤碼 errQUEUE_FULL。
發送緊急消息時,消息位於隊列隊首,接收者優先接受緊急消息。
任務或中斷讀消息隊列時,隊列有消息則直接讀取,隊列無消息則進入阻塞態等待消息,在阻塞期間有消息任務由阻塞轉為就緒態,當超過阻塞時間仍無消息,任務直接進入就緒態且返回一個錯誤碼。
消息隊列對於所有任務是可見的,為了保護任務對隊列的讀寫完整性,需要建立阻塞機制。中斷不允許阻塞。如圖所示:
隊列控制塊
隊列控制塊主要包含存儲位置,頭指針,尾指針,消息大小,隊列長度。
消息隊列相關函數
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize )
- 功能:消息隊列創建函數
- uxQueueLength 隊列長度
- uxItemSize 單個消息空間大小
- 返回值: 隊列句柄,創建成功返回創建的隊列的句柄,失敗返回NULL
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize,const uint8_t ucQueueType )
- 功能:用於消息隊列內存分配
- uxQueueLength 隊列長度
- uxItemSize 單個消息空間大小
- ucQueueType 消息隊列類型
隊列類型 | 說明 |
---|---|
queueQUEUE_TYPE_BASE | 隊列 |
queueQUEUE_TYPE_SET | 隊列集合 |
queueQUEUE_TYPE_MUTEX | 互斥量 |
queueQUEUE_TYPE_COUNTING_SEMAPHORE | 計數信號量 |
queueQUEUE_TYPE_BINARY_SEMAPHORE | 二進制信號量 |
queueQUEUE_TYPE_RECURSIVE_MUTEX | 遞歸互斥量 |
- 返回值: 隊列句柄,創建成功返回創建的隊列的句柄,失敗返回NULL
- 說明:xQueueCreate函數是xQueueGenericCreate函數的宏定義
static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue )
- 功能:消息隊列初始化
- uxQueueLength 隊列長度
- uxItemSize 單個消息空間大小
- pucQueueStorage 存儲消息起始地址
- ucQueueType 消息隊列類型
- pxNewQueue 消息隊列控制塊
- 返回值:無
- 說明:prvInitialiseNewQueue函數用於消息隊列初始化,被xQueueGenericCreate函數調用
void vQueueDelete( QueueHandle_t xQueue )
- 功能:刪除消息隊列
- xQueue 消息隊列
- 返回值:無
BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait)
- 功能:向隊列隊尾發送一個隊列消息
- xQueue 消息隊列
- pvItemToQueue隊列消息指針
- xTicksToWait 等待隊列空閑的最大超時時間
- 返回值:發送成功返回 pdTRUE,發送失敗返回errQUEUE_FULL
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken)
- 功能:在中斷中向隊列隊尾發送一個隊列消息
- xQueue 消息隊列
- pvItemToQueuedui 隊列消息指針
- pxHigherPriorityTaskWoken 入隊導致某個比當前任務優先級高的的任務,將pxHigherPriorityTaskWoken賦值pdTRUE,在中斷推出前進行一次上下文切換
- 返回值:發送成功返回 pdTRUE,發送失敗返回errQUEUE_FULL
BaseType_t xQueueSendToFront( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait )
- 功能:向隊列隊首發送一個隊列消息
- xQueue 消息隊列
- pvItemToQueue隊列消息指針
- xTicksToWait 等待隊列空閑的最大超時時間
- 返回值:發送成功返回 pdTRUE,發送失敗返回errQUEUE_FULL
BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken)
- 功能:在中斷中向隊列隊首發送一個隊列消息
- xQueue 消息隊列
- pvItemToQueuedui 隊列消息指針
- pxHigherPriorityTaskWoken 入隊導致某個比當前任務優先級高的的任務,將pxHigherPriorityTaskWoken賦值pdTRUE,在中斷推出前進行一次上下文切換
- 返回值:發送成功返回 pdTRUE,發送失敗返回errQUEUE_FULL
BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait)
- 功能:從隊列中讀取消息后將消息從該隊列刪除
- xQueue 消息隊列
- pvBuffer 接受消息指針
- xTicksToWait 讀取時發生阻塞最大超時時間
- 返回值:讀取成功返回 pdTRUE,讀取失敗返回 pdFALSE
BaseType_t xQueuePeek(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait)
- 功能:從隊列中讀取消息后不刪除
- xQueue 消息隊列
- pvBuffer 接受消息指針
- xTicksToWait 讀取時發生阻塞最大超時時間
- 返回值:讀取成功返回 pdTRUE,讀取失敗返回 pdFALSE
BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken)
- 功能:在中斷中從隊列中讀取消息后將消息從該隊列刪除
- xQueue 消息隊列
- pvBuffer 接受消息指針
- pxHigherPriorityTaskWoken 讀取消息時隊列已滿產生阻塞
- 返回值:讀取成功返回 pdTRUE,讀取失敗返回 pdFALSE
BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue, void *pvBuffer)
- 功能:在中斷中從隊列中讀取消息后不刪除
- xQueue 消息隊列
- pvBuffer 接受消息指針
- 返回值:讀取成功返回 pdTRUE,讀取失敗返回 pdFALSE
消息隊列注意點
1.使用消息隊列發送接收函數的時候需要先創建消息隊列
2.消息隊列讀取采用先進先出的模式,先讀取先存儲在隊列中的數據
3.消息接收的緩存內存應不小於單個消息空間的大小