FreeRTOS 操作系統學習(四) 隊列管理

                                                      FreeRTOS 操作系統學習

http://wiki.csie.ncku.edu.tw/embedded/FreeRTOS_Melot.pdf

3  隊列管理

      隊列是FreeRTOS中所有任務通信或同步之外的基本機制。理解隊列至關重要,因爲在構建一個複雜的任務通信應用時,不可避免地將用到它。它是存儲固定數據大小(“長度”)的一種方式。隊列能夠被多個不同的任務讀寫,但並不從屬於某個特定的任務。隊列通常是一個FIFO,這意味着元素按照被寫入的順序被讀取。此行爲取決於寫入方法:可以使用兩個寫入函數在此隊列的開始或結尾處進行寫入。

3.1 隊列的讀取 

       當有任務嘗試對隊列進行讀操作時,如果此時有其他任務或中斷正在對此隊列進行寫操作, 必須要等寫操作的任務完成,此時任務被阻塞(Blocked),當隊列寫操作完成後,任務狀態自動轉爲“就緒(Ready)”    。如果同時有多個任務嘗試對隊列進行寫操作,則按任務優先級依次進行。還有一種情況,當多個任務嘗試對隊列進行讀操作,且所有任務的優先級都相同,那麼隊列按照讀操作的請求的時間依次進行。任務還可以指定等待讀取隊列時的最大等待時間,大於這個時間,任務將放棄讀取,自動切換回“就緒”狀態。

     

文本5: 讀取隊列的常規方法:先讀取元素,然後將其刪除

portBASE_TYPE xQueueReceive(                                

                                                                     xQueueHandle xQueue,                                 

                                                                     const void *      pvBuffer,                                

                                                                     portTickType    xTicksToWait

                                                        ); 

      xQueue         是要讀取的隊列的標識符

      pvBuffer         是指向緩衝區的指針,讀取值將被複制到該緩衝區。該內存必須已分配並且必須足夠大以處理從隊列中                                          讀取的元素

      xTicksToWait   定義最大的等待時間。0 當值無效時,任務不等待,但是如果設置INCLUDE_vTaskSuspend且xTicksToWait等於MAX_DELAY,則任務將無限期等待。

       如果在 xTicksToWait  之前成功讀取了一個值,則返回pdPASS。 否則,xQueueReceive()返回errQUEUE_EMPTY。

       隊列中的某個元素被讀取後通常會被刪除;但是,另一個讀取函數可以實現讀取後元素不被刪除,函數如下

文本 6: 隊列讀取後元素不會被刪除

portBASE_TYPE xQueuePeek(       xQueueHandle xQueue,                                 

                                                          const void  *     pvBuffer,                                 

                                                          portTickType     xTicksToWait   

                                                     ); 

3.2  隊列寫操作

      隊列寫操作與讀類似。當一個任務嘗試寫隊列時,必須等隊列有空餘緩存:等其他任務完成隊列讀取並釋放隊列空間後,纔可進行寫操作,否則任務將被阻塞。多個任務同時讀,高優先級任務優先。當多個同優先級任務嘗試下寫隊列,先到先寫。 圖6 很好地說明了隊列的工作方式。

      文本7 提供一個常用的寫隊列的函數原型。文本8 提供 xQueueSend 執行後如果用戶希望讀取最後寫入的元素將要使用的函數先進先出(後進先出或LIFO)。

Text 7: FIFO模式寫隊列函數

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 。

文本 8: xQueueSendToBack: 與 xQueSend相似; xQueueSendToFront 用 LIFO 模式寫隊列.

portBASE_TYPE xQueueSendToBack(  xQueueHandle xQueue,                                   

                                                                const void * pvItemToQueue,                                    

                                                                portTickType xTicksToWait                                  

                                                              ); 

portBASE_TYPE xQueueSendToFront(   xQueueHandle xQueue,                                    

                                                                  const void * pvItemToQueue,                                   

                                                                  portTickType xTicksToWait                                 

                                                               ); 

3.3  創建一個隊列

     隊列長度及其中每個元素的大小是在隊列創建時就規定好的。文本9 給出創建隊列的常用函數

文本 9: 隊列創建函數

xQueueHandle xQueueCreate(   unsigned portBASE_TYPE uxQueueLength,                                                                                                                                    unsigned portBASE_TYPE uxItemSize

                                                  ); 

            uxQueueLenght    隊列元素的數量。

            uxItemSize  規定了隊列每個元素是多少個字節的大小。

     如果隊列因內存不足創建失敗xQueueCreate返回NULL;如果不是,則應保留返回值以處理新創建的隊列   

                                                      

                                                                         表6  有一個隊列和兩個任務的可能情況

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章