日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

FreeRTOS實時操作系統隊列基礎_操作系統

作者:zhzht19861011 ? 更新時間: 2022-06-10 編程語言

前言

本文介紹隊列的基本知識,詳細源碼分析見FreeRTOS進階之隊列示例分析

1.FreeRTOS隊列

隊列是主要的任務間通訊方式??梢栽谌蝿张c任務間、中斷和任務間傳送信息。大多數情況下,隊列用于具有線程保護的FIFO(先進先出)緩沖區:新數據放在隊列的后面。當然,數據也可以放在隊列的前面,在下一篇講隊列API函數時,會涉及到數據的存放位置。

圖1-1:讀寫隊列

圖1-1所示的隊列中,最多能保存5個項目,并且假設隊列永遠不會滿。任務A使用API函數xQueueSendToBack()向隊列發送數據,每次發送一個數據,新入隊的數據置于上一次入隊數據的后面。任務B使用API函數xQueueReceive()將數據從隊列取出,先入隊的數據先出隊。

2.使用模型:最簡單、最靈活

通常情況下,魚和熊掌是不可兼得的,但FreeRTOS的隊列用戶模型管理卻兼顧簡單和靈活。發送到隊列的消息是通過拷貝實現的,這意味著隊列存儲的數據是原數據,而不是原數據的引用。FreeRTOS隊列具有以下特性:

C變量(整形、簡單結構體等等)中的簡單信息可以直接傳送到隊列。這樣就不需要為信息分配緩存也不需要再進行什么拷貝工作。同樣的,信息可以直接從隊列讀取到C變量中。用直接拷貝的方法入隊,可以允許任務立即覆寫已經入隊的變量或者緩存,實際上隊列中已經保存了這些變量或緩沖區攜帶的信息。因為變量中的數據內容是以拷貝的方式入隊的,所以變量自身是允許重復使用的。發送信息的任務和接收信息的任務并不需要就哪個任務擁有信息、哪個任務釋放信息(當信息不再使用時)而達成一致。

隊列是通過拷貝傳遞數據的,但這并不妨礙隊列通過引用來傳遞數據。當信息的大小到達一個臨界點后,逐字節拷貝整個信息是不實際的,可以定義一個指針隊列,只拷貝指向消息的指針來代替整個信息拷貝。FreeRTOS+UDP IP棧例程正是使用這種方法向FreeRTOS協議棧傳遞大量網絡數據的。

隊列內存區域分配由內核完成。

變長消息可以通過定義保存一個結構體變量的隊列實現,結構體一個成員指向要入隊的緩存,另一個成員保存緩存數據的大小。

單個隊列可以接收不同類型信息,并且信息可以來自不同的位置。通過定義保存一個結構體變量的隊列來實現,結構體的一個成員保存信息類型,另一個成員保存信息數據(或者指向信息數據的指針)。數據如何解讀取決于信息類型。管理FreeRTOS+UDP IP棧的任務正是使用單個隊列接收ARP定時器時間通知、以太網硬件傳送來的數據包、從應用層傳送來的數據包、網絡關閉事件等等。

天生適用于那些內存保護(MPU)場合。一個具有內存區域保護的任務可以向另一個具有內存區域保護的任務傳遞數據,因為調用隊列發送函數會引起RTOS提升微控制器特權級別。只有RTOS(具有所有特權)才可以訪問隊列存儲區域。

在中斷函數中使用獨立的API。將RTOS任務API和中斷服務例程API分來實現意味著可以避免執行時的上下文調用檢查開銷,還意味著在大多數情況下,與其它RTOS產品相比,用戶創建中斷服務例程會更簡單。

API函數很簡單。

3.隊列阻塞

API函數允許指定阻塞時間。

每當任務企圖從一個空的隊列讀取數據時,任務會進入阻塞狀態(這樣任務不會消耗任何CPU時間并且另一個任務可以運行)直到隊列中出現有效數據或者阻塞時間到期。

每當任務企圖向一個滿的隊列寫數據時,任務會進入阻塞狀態,直到隊列中出現有效空間或者阻塞時間到期。

如果多個任務阻塞在一個隊列上,那么最高優先級別的任務會第一個解除阻塞。

注:中斷程序中必須使用“FromISR”結尾的API函數!

總結一下隊列的基本用法:

定義一個隊列句柄變量,用于保存創建的隊列:xQueueHandle xQueue1;

使用API函數xQueueCreate()創建一個隊列。

如果希望使用先進先出隊列,使用API函數xQueueSend()或xQueueSendToBack()向隊列投遞隊列項。如果希望使用后進先出隊列,使用API函數xQueueSendToFront()向隊列投遞隊列項。如果在中斷服務程序中,切記使用它們的帶中斷保護版本。

使用API函數xQueueReceive()從隊列讀取隊列項,如果在中斷服務程序中,切記使用它們的帶中斷保護版本。

原文鏈接:https://freertos.blog.csdn.net/article/details/50736067

欄目分類
最近更新