# 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;如果這幾個任務的優先級一樣,那麼等待數據並處於阻塞的時間最長的那個任務將被解除阻塞
{"metaMigratedAt":"2023-06-18T02:00:13.285Z","metaMigratedFrom":"Content","title":"FreeRTOS Queue","breaks":true,"contributors":"[{\"id\":\"cf3e4a44-322f-4620-80ec-b2a2091da3c4\",\"add\":3998,\"del\":2241}]"}
Expand menu