---
# System prepended metadata

title: FreeRTOS Queue

---

# FreeRTOS Queue
在 FreeRTOS 中，task 之間的溝通是透過把資料傳送到 queue 和讀取 queue 中資料實現的

## Queue

Queue的概念大概如下圖，下圖表達task與task之間傳遞資料的方式，當今天不用task A傳東西給task B了，改用task C傳給task B，其中Queue不屬於任何一個任務，僅用於傳遞消息和數據，故這樣的改動對使用Queue來傳遞資料的架構是非常方便的。

![](https://i.imgur.com/kv0elrY.png)

## Basic Feature

### Access by Multiple Tasks
同一個隊列可以被多個任務（或者在 ISR 中）訪問；==可以有多個任務對同一個 Queue 寫入，也可以多個任務進行讀==；實際中，多個任務同時寫一個 Queue 是比較常見的，多個讀者是比較少見的

### Blocking on Queue Reads
當一個任務想去讀一個 Queue 的時候，可以選擇指定阻塞時間；這個時間指的是，當這個 Queue 為空的時候，這個任務保持阻塞在讀這個 Queue 的時間；因為一個任務執行的時候，很多情況是，獲得到來自另一個任務（或者中斷）的數據後，才得以執行，在這之前，最好是保持在阻塞狀態，這樣可以免得調度器在調度沒用的任務

![](https://i.imgur.com/a2JxZFL.png)

一個任務阻塞在讀 Queue 上，等待數據，當另外的任務或者 ISR 給這個 Queue 餵了數據後，這個被阻塞的任務將會從阻塞鍊錶中移除，被加入到 Ready 任務鍊錶；或者當指定的阻塞時間到，要讀的 Queue 還是為空，那麼也會解除阻塞，進入 Ready 鍊錶

![](https://i.imgur.com/zSxRxuc.png)

Queue 支持多個讀者，所以，如果多個任務都在讀一個已經空了的 Queue，那麼他們都將進入阻塞狀態

![](https://i.imgur.com/XjopX7k.png)

==出現多個讀者情況的時候，如果當 Queue 有數據的時候，只有一個最高優先級的任務可以解除阻塞，進入 Ready== ；如果這幾個任務的優先級一樣，**那麼等待數據並處於阻塞的時間最長的那個任務將被解除阻塞**
![](https://i.imgur.com/99NVZ9S.png)

:::info
翻譯蒟蒻：
這種多讀者讀Queue的情況特別像等餐廳的情況，外面每個客人都拿著號碼牌，每個客人都坐在各自的椅子上，這時候走出來一個服務生，他叫優先序最高的客人的號碼，客人站起來拿了服務生給的菜單。那如果服務生一直沒出來給菜單呢?客人當然不會乖乖等，每個客人都會固定幾分鐘就站起來看一下，到底服務生要給菜單了沒
* 多個客人代表多個讀者，想要讀取服務生給的菜單
* 服務生是ISR/中斷的角色，號碼牌代表每個客人的優先序，服務生以此判別該先給誰菜單
* 客人坐著表示阻塞態，站起來表示ready狀態，固定幾分鐘站起來看一下此為阻塞時間
:::

### Blocking on Queue Writes
對於寫來說，和讀一樣的，當一個任務企圖去寫一個 Queue 的時候，可以選擇指定阻塞時間；這個時間指的是，當這個 Queue 為滿的時候，這個任務保持阻塞在寫這個 Queue 的時間

一個任務阻塞在寫 Queue 上，等待數據，當另外的任務或者 ISR 讀走了 Queue 數據導致這個 Queue 不在是滿的狀態，這個被阻塞的任務將會從阻塞鍊錶中移除，被加入到 Ready 任務鍊錶；或者當指定的阻塞時間到，要寫的 Queue 還是為滿，那麼也會解除阻塞，進入 Ready 鍊錶；

Queue 支持多個寫者，所以，==如果多個任務都在寫一個已經滿了的 Queue，那麼他們都將進入阻塞狀態==，出現這種情況的時候，一旦 Queue 有數據被讀走，阻塞在寫上的幾個任務只有一個最高優先級的任務可以解除阻塞，進入 Ready；如果這幾個任務的優先級一樣，那麼等待數據並處於阻塞的時間最長的那個任務將被解除阻塞

