FreeRTOS 操作系統學習
http://wiki.csie.ncku.edu.tw/embedded/FreeRTOS_Melot.pdf
3 隊列管理
隊列是FreeRTOS中所有任務通信或同步之外的基本機制。理解隊列至關重要,因爲在構建一個複雜的任務通信應用時,不可避免地將用到它。它是存儲固定數據大小(“長度”)的一種方式。隊列能夠被多個不同的任務讀寫,但並不從屬於某個特定的任務。隊列通常是一個FIFO,這意味着元素按照被寫入的順序被讀取。此行爲取決於寫入方法:可以使用兩個寫入函數在此隊列的開始或結尾處進行寫入。
3.1 隊列的讀取
當有任務嘗試對隊列進行讀操作時,如果此時有其他任務或中斷正在對此隊列進行寫操作, 必須要等寫操作的任務完成,此時任務被阻塞(Blocked),當隊列寫操作完成後,任務狀態自動轉爲“就緒(Ready)” 。如果同時有多個任務嘗試對隊列進行寫操作,則按任務優先級依次進行。還有一種情況,當多個任務嘗試對隊列進行讀操作,且所有任務的優先級都相同,那麼隊列按照讀操作的請求的時間依次進行。任務還可以指定等待讀取隊列時的最大等待時間,大於這個時間,任務將放棄讀取,自動切換回“就緒”狀態。
portBASE_TYPE xQueueReceive( xQueueHandle xQueue, const void * pvBuffer, portTickType xTicksToWait ); |
xQueue 是要讀取的隊列的標識符
pvBuffer 是指向緩衝區的指針,讀取值將被複制到該緩衝區。該內存必須已分配並且必須足夠大以處理從隊列中 讀取的元素
xTicksToWait 定義最大的等待時間。0 當值無效時,任務不等待,但是如果設置INCLUDE_vTaskSuspend且xTicksToWait等於MAX_DELAY,則任務將無限期等待。
如果在 xTicksToWait 之前成功讀取了一個值,則返回pdPASS。 否則,xQueueReceive()返回errQUEUE_EMPTY。
隊列中的某個元素被讀取後通常會被刪除;但是,另一個讀取函數可以實現讀取後元素不被刪除,函數如下
portBASE_TYPE xQueuePeek( xQueueHandle xQueue, const void * pvBuffer, portTickType xTicksToWait ); |
3.2 隊列寫操作
隊列寫操作與讀類似。當一個任務嘗試寫隊列時,必須等隊列有空餘緩存:等其他任務完成隊列讀取並釋放隊列空間後,纔可進行寫操作,否則任務將被阻塞。多個任務同時讀,高優先級任務優先。當多個同優先級任務嘗試下寫隊列,先到先寫。 圖6 很好地說明了隊列的工作方式。
文本7 提供一個常用的寫隊列的函數原型。文本8 提供 xQueueSend 執行後如果用戶希望讀取最後寫入的元素將要使用的函數先進先出(後進先出或LIFO)。
portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait ); |
xQueue 需要些的隊列. 該值通過隊列的創建函數返回
pvItemToQueue 是指向要(按值)複製到隊列中的元素的指針
xTicksToWait 允許等待的最大時間。 0 表示當隊列滿後不等待直接放棄寫操作。如果在FreeRTOSConfig.h 將 INCLUDE_vTaskSuspend 值定義爲1 (本節8.1),並且xTicksToWait等MAX_DELAY, 任務將會一直阻塞並保持等待。
寫成功後 XqueueSend 函數將返回 pdPASS,若寫操作超時,則返回 errQUEUE_FULL 。
portBASE_TYPE xQueueSendToBack( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait ); portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait ); |
3.3 創建一個隊列
隊列長度及其中每個元素的大小是在隊列創建時就規定好的。文本9 給出創建隊列的常用函數
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ); |
uxQueueLenght 隊列元素的數量。
uxItemSize 規定了隊列每個元素是多少個字節的大小。
如果隊列因內存不足創建失敗xQueueCreate返回NULL;如果不是,則應保留返回值以處理新創建的隊列
表6 有一個隊列和兩個任務的可能情況