2017-03-21 39 views
0

懸崖注意到版本 的TI F28377S具有兩個CPU,主和次級CPU(CLA,它只能在一個時間執行一個任務,不中斷的任務) - 它們共享消息區的RAM。當快速提供CLA將發送的約15個字節(最大32個隊列長度)的隊列時,有時幾個字節將永遠不會被髮送。我認爲CPU中斷有一些問題導致單個字節偶爾會在將它們交給緩衝區時「丟失」。棘手隊列使用

完整版本 (這是通過使用具有一個主CPU主頻爲200兆赫,並運行以相同的速度的二次獨立CLA的TI F28377S,而只能在一個時間執行一個任務。它們可以共享單向可寫變量)。

我有點難住如何做這個更復雜的任務,涉及CLA和一個隊列。一些快速背景:我有兩個主要的CLA任務,第一個(Task1)由ADC轉換結束(本身由Timer0在100 kHz觸發)觸發,第二個(Task2)由Timer0觸發(這是經過大量實驗和調整後纔得到的,因爲每當我運行Task2比ADC任務運行更頻繁時,ADC任務將永遠不會啓動 - 因此我將它們設置爲使用相同間隔,只是交錯)。 Task1完美工作,將ADC結果存儲在簡單的環形緩衝區中,並在Task1完成ISR後執行簡單的計算。第二個主要工作。

任務2用於切換某些GPIO引腳與外部設備進行通信。由於代碼的總長度大約爲100微秒,而不是延遲,所以我在每個觸發器上使用一個簡單的case結構來確定它是否應該:什麼也不做,打開代碼引腳,打開選通引腳,關閉閃光燈引腳,關閉代碼引腳。通過這種方式,每次調用任務時,都會立即完成任務,並且輸出代碼是外部設備的合適長度。該任務每次處理一個代碼,一旦完成,就嘗試從隊列中獲取另一個代碼。如果沒有,它只是繼續通過。

現在,棘手的部分。我有兩個要求:1)我可以將字節添加到隊列的末尾,比任務消耗更快(在理論和實踐中非常容易),以及2)我可以將一個字節添加到隊列的前端(而不是替換當前正在傳輸的字節,只是隊列的前面)。第一種能力是發送中短消息(2-20個字符)。第二種能力是發送一個關於任何外部中斷的單個字節 - 儘可能快,甚至在發送消息的過程中。我已經設置好了,這樣任務每500微秒發送一個字節(〜300「on」和〜200「off)。這樣,如果有一箇中斷消息進來,它將保證接收到小於1 ms發生後012毫秒的數據發送後

什麼是當前的工作是這樣的:一個函數在CPU上獲取傳入字節(一次一個)並將它們添加到CPU2CLA緩衝區並增加一個CPU2CLA長度計數器每次運行Task2時,它檢查這個隊列並從一個CLAonly緩衝區的前面抓取一個字節,增加它自己的緩衝區長度,並且標記一個字節被消耗掉了。當Task2任務後的ISR運行時,它將檢查一個字節是否被消耗,刪除CPU2CLA緩衝區中的第一個字節,目前這個雙緩衝區系統沒有添加前面的標誌,所以它沒有考慮到中斷情況。

我之前嘗試過的是使用一個Task3,它將一個字節傳遞給CPU2CLA,並使用Task3andWait從CPU運行它。儘管這種方法在理論上應該兼顧這兩個要求,但大約一半的時間內一個字節或兩個消息永遠不會被傳輸(一個字節總是被髮送)。

CLA任務不能被中斷,但CPU任務可以。這就是爲什麼我試圖讓隊列的所有修改都只發生在CLA中,所以從來沒有一個不確定的狀態可以中斷隊列修改。

+0

TL:DR。如果您「可以將字節添加到隊列末尾的速度比任務消耗的速度快」,則需要阻止輸入。如果這是需要將字節發佈到隊列前端的基本問題,那麼您必須對傳入字節進行**值判斷**:如果您的函數做了比他們應該更多的處理,那麼瓶頸。 –

+0

現在隊列只有32個字節(固定)。而我的傳入函數做了一個簡單的檢查,如果長度== max_length,退出(即丟棄字節)。 –

+0

然後在什麼前提下,將字節發佈到隊列的前端?數據有多必要?你能承受失去它嗎?如果是這樣,只需重新設置緩衝區,但無法足夠快地處理傳入數據。 –

回答

0

這聽起來像是將高優先級和正常優先級的項目分割成單獨的緩衝區,在這裏將是一個接近最優的解決方案。

它還可以確保如果在消耗任何東西之前生成高優先級項目,普通優先級項目和另一個高優先級項目,則高優先級項目將在正常優先級項目之前消耗。

(使用單個緩衝器,這種情況下,導致正常優先級的項目的第二高優先級項目之前被消耗。我懷疑是非常不希望的。)

如果在所述高的項優先級緩衝區,接下來將被消耗。否則,正常優先級緩衝區中的項目將被消耗。

兩個緩衝器具有一個生產者和單個消費者(因此,SPSC型),和在被處理的簡單先入先出的方式;因此,無鎖循環緩衝區實現(對於每個緩衝區)應該在這裏工作得很好。

(如果只有32個字節可用於兩個緩衝區,請考慮首先嚐試8:24分割。)

+0

我喜歡這個。我沒有考慮過兩個隊列,但是這完全解決了開始插入項目的問題。我會嘗試一下。 –

+0

我會補充說,我必須弄清楚如何在兩個內存「域」之間獲得正常的循環緩衝區。 (CPU和CLA對任何單個變量都有RW或R訪問權限,但在編譯之前就已經定義了,所以生產者和消費者都不可能改變長度)。 –

+0

@AdamJones:如果'next'是要消費的下一個字節的索引,並且'last'是要消耗的最後一個字節的索引(兩個模緩衝區長度),則只有生產者寫入'next',和消費者「持續」。 –