2013-01-21 105 views
2

我試圖用queue來緩存來自我的UART ISR的字符到後臺任務。我想隊列的長度是512字節。這是不可能的,因爲size參數的類型是unsigned portBASE_TYPE,對於xmega256a3是單字節(char)。是否有一個隊列的最大尺寸與portBASE_TYPE浮動的原因?而不是uint16_t?令人沮喪的FreeRTOS xQueueCreate()限制

我很好奇,如果別人有同樣的限制,以及他們已經做了什麼,如果有的話。

+0

我不熟悉FreeRTOS的細節。在將其視爲一般情況時,是否可以分配一個緩衝區來收集字符並將指針指向該緩衝區的隊列? – NeonGlow

+0

在這種情況下,是否會有原子訪問問題或其他假設使BASE_TYPE成爲首選? – XTL

回答

3

出於效率原因,對於大多數變量使用portBASE_TYPE是很自然的。 AVR是8位體系結構,因此處理8位隊列算法的效率將高於16位。對於某些應用來說,這種效率可能很關鍵

使用uint16_t不作在32位架構的意義,你會注意到,portBASE_TYPE的ARM內核是一個32位的值,因此在選擇uint16_t作爲隊列長度的默認類型將上是人工的限制這些核心。

這裏有一些選擇:

  • 重構你的任務從隊列中更經常讀。除非其他任務竊取了太多處理時間,否則應該可以降低ISR隊列長度並緩存讀線程中的數據。
  • 用不同的portBASE_TYPE重新編譯FreeRTOS。我沒有嘗試過,但是我沒有看到爲什麼這樣做不起作用的原因,除非FreeRTOS中有一些彙編代碼需要8位portBASE_TYPE。我看了一眼,沒有看到彙編代碼需要8位類型的明顯跡象。
  • 使用您自己的排隊庫,可以根據需要存儲儘可能多的數據。使用其他FreeRTOS基元(如信號量)向您的任務發出數據已添加到您的隊列的信號。它不會阻塞隊列讀取,而會阻塞信號量。在信號燈被髮信號後,您可以使用自己的排隊庫來讀取排隊的數據。
4

理查德·巴里(FreeRTOS的作者)發佈的FreeRTOS的郵件列表如下回應:

這僅僅是對8位架構的情況。已經提到過幾次(您可以在FreeRTOS網站上搜索支持檔案),但由於大多數新項目使用的是32位體系結構,因此這種情況並沒有多年。簡單的做法是改變portmacro.h中的portBASE_TYPE的定義,但它會使你的代碼變得更大,效率更低。另外,許多FreeRTOS演示使用隊列來傳遞字符進出中斷,以提​​供任務和中斷通信的簡單示例,但除非吞吐量非常低(例如命令控制檯),否則它不是編寫生產代碼的推薦方式。使用循環緩衝區,最好使用DMA,效率更高。