我最近正在使用mbed(LPC1768)做一個項目,使用DAC輸出各種波形。我閱讀了數據手冊的各個部分,並討論了許多外設如何使用DMA。這似乎很有用,但是在進一步閱讀後,我發現DMA使用的數據總線與cpu相同(我認為這是正常的)。這是否意味著在DAC獲取數據時,CPU無法與任何存儲器交互?另外,由於DAC沒有緩衝區(據我所知),因此必須經常進行DMA,DMA的意義何在?如果CPU無法執行內存事務,它可以做什麼?
我最近正在使用mbed(LPC1768)做一個項目,使用DAC輸出各種波形。我閱讀了數據手冊的各個部分,並討論了許多外設如何使用DMA。這似乎很有用,但是在進一步閱讀後,我發現DMA使用的數據總線與cpu相同(我認為這是正常的)。這是否意味著在DAC獲取數據時,CPU無法與任何存儲器交互?另外,由於DAC沒有緩衝區(據我所知),因此必須經常進行DMA,DMA的意義何在?如果CPU無法執行內存事務,它可以做什麼?
總而言之,就是DMA允許CPU有效地以其原始速度運行,而外圍設備可以有效地以其原始速度運行。該示例中的大多數數字都是虛構的。
讓我們比較兩個選項以定期從ADC收集數據:
讓我們將1000個樣本從ADC傳輸到RAM。
使用選項1:每個樣品都有
我們假設該中斷功能為76條指令,假設單個週期執行(最佳情況),則整個例程的長度為100條指令。這意味著選項1將花費100,000個CPU時間週期來執行。
選項2:將DMA配置為收集1000個ADC樣本。假定ADC具有來自計時器的硬件觸發。
冒充整個中斷(帶有進入和退出開銷)是100個單週期指令。使用DMA,您只需花費100個週期即可保存相同的1000個樣本。
現在,每次DMA訪問總線時,是的,CPU和DMA之間可能會發生爭執。甚至可能迫使CPU等待DMA完成。但是,等待DMA完成要比將CPU鎖定來維修ADC短得多。如果CPU核心時鐘為2x總線時鐘,則CPU可能會浪費幾個核心週期來等待DMA完成。這意味著您的傳輸有效執行時間在1000個週期(假設CPU從不等待)到9000個週期之間。仍然比100,000個週期更好。
我發現的 LPC1768數據表具有以下引號(強調我的意思):
AHB多層板上的八通道通用DMA控制器(GPDMA) 可與SSP,I2S總線,UART,模數和 數模轉換器外設,定時器匹配信號,以及 內存到內存的傳輸。
分離式APB總線可實現高吞吐量,而CPU和DMA之間的停頓很少
第6頁的框圖顯示了AHB矩陣之間具有多個通道的SRAM,以下引用對此表示支持:
LPC17xx總共包含64 kB片上靜態RAM存儲器。這包括主要 32 kB SRAM,可通過高速總線上的CPU和DMA控制器訪問,以及two 每個SRAM塊額外提供16 kB的空間位於上的獨立從端口AHB上的 多層矩陣。 這種架構允許CPU和DMA訪問分佈在三個獨立的RAM上 可以同時訪問
以下引用進一步證實了這一點:
GPDMA支持外設到內存,內存到外設, 外設到外設以及內存到內存的事務。
因此,您可以從單獨的SRAM塊之一或其他外圍設備將數據流傳輸到DAC,同時將主SRAM用於其他功能。
這種外圍外設DMA在內存接口非常簡單的較小部件中很常見(與現代Intel處理器相比)。
如果在給定的周期內處理器和DMA控制器需要訪問相同的總線,則一個或另一個必須等待。但是,許多系統包含帶有單獨總線的多個內存區域以及一個總線“橋”,該橋將允許CPU訪問一個存儲器,而DMA控制器訪問另一個存儲器。
此外,許多CPU可能不需要在每個週期訪問存儲設備。如果CPU通常只需要在三個週期中的兩個週期內訪問內存,則低優先級DMA設備可能能夠利用內存總線空閒時的周期。
即使在每個DMA週期都會導致CPU停頓一個週期的情況下,但是,如果數據到達的速度足夠慢以至於CPU應該能夠在兩次DMA之間做其他事情,則DMA可能仍然非常有用。傳入數據項,但速度足夠快,因此需要將每個項目的開銷降至最低。例如,如果SPI端口以每16個CPU週期以1字節的速率向設備饋送數據,則為每次傳輸中斷CPU可能會導致它花費幾乎全部時間進入和退出中斷服務程序,而沒有做任何實際的工作。但是,使用DMA,即使每次DMA傳輸導致CPU停滯兩個週期,開銷也可以減少到13%。
最後,某些CPU允許在CPU睡眠時執行DMA。使用 基於中斷的傳輸將要求系統完全喚醒 對於傳輸的每個數據單位。但是,使用DMA可能 睡眠控制器向存儲控制器提供兩個時鐘 一個字節進入的時間,但讓其他所有對象保持睡眠狀態,從而減少了 功耗。
作為程序員,DMA是用於向支持它的外圍設備傳輸數據的一種選擇。對於通過串行外圍設備(如SPI或UART)移動大型緩衝區或從ADC收集大量樣本的經典示例,您可以通過以下三種方法來移動數據:
輪詢方法。在這裡等待寄存器標誌,以允許您移入/移出下一個字節。問題是您在等待CPU的同時阻止了CPU的所有執行。或者,如果您必須在操作系統中共享CPU時間,則傳輸將大大減慢。
中斷方法。在這裡,您編寫一個中斷服務例程(ISR),該例程在每次字節傳輸時都執行,並在ISR中編寫代碼以管理傳輸。這會提高CPU的效率,因為CPU僅在需要時才會為您的ISR提供服務。除ISR外,它在所有其他時間都是免費使用的。從傳輸速度來看,ISR也是進行傳輸的較快選擇之一。
DMA。您可以使用源/目標指針,傳輸次數和關閉狀態來配置DMA。它會佔用總線週期和CPU時間來完成傳輸,同時CPU可以自由地做其他事情。您可以配置標誌或中斷以指示傳輸完成的時間。通常觸摸速度比ISR快,並且通常是最快的傳輸選項。
作為一名程序員,我更喜歡DMA,因為它最容易編碼,並且本質上是進行傳輸的最快技術。通常,您只需要為源/目標指針和要進行的傳輸數量配置幾個寄存器。與IDMA代碼相比,我在ISR代碼上花費的時間要多得多,因為ISR代碼需要關鍵的設計技能,並且必須進行編碼,測試,驗證等。DMA代碼要小得多,而我必須自己編寫代碼相對來說是微不足道的,並且討價還價中我獲得了最大的傳輸速度。
根據我的經驗,最近使用Atmel SAM3 / 4處理器,DMA的運行速度比我自己製作的高效ISR快。我有一個應用程序,每5毫秒從SPI讀取一堆字節。後台任務中發生了很多浮點數學運算,因此我希望CPU對於這些任務盡可能地自由。最初的實現是ISR,然後我轉到DMA進行比較,並嘗試在兩次採樣之間購買更多的CPU時間。傳輸速度的增益略有提高,但只有一點點提高。在o-scope上幾乎無法測量。
這是因為在我所看到的最新微處理器上,ISR和DMA幾乎以相同的方式運行-它們按照所需的CPU週期進行操作,而DMA與CPU進行的操作基本上與我在其中進行的編碼相同有效的ISR。
在極少數情況下,我看到外設具有自己的RAM區域,而DMA僅可訪問這些區域。這是在以太網MAC或USB上。
最有可能在這裡使用DMA,這樣DAC可以具有一些常規定時,可以通過以某個已知間隔更改模擬輸出來生成波形。
是的,如果它是共享總線,那麼...您必須共享。
cpu並不總是使用總線,因此與dma引擎共享有時是個好主意。當然,這意味著要優先考慮優先事項,有時只是誰先到達優先權(例如,在資源前面有一條命令fifo,然後按照請求到達的順序發出請求,是的,這不一定是確定性的)。在這種情況下,您可能希望dma優先於cpu,以便對時間敏感的事物(如DAC或ADC)具有確定的時序。取決於他們選擇如何實施。
人們有時會錯誤地認為dma是免費的。它是否仍會消耗總線時間,如果與cpu共享(它最終會在與cpu可以與之通信的資源進行通信時共享),則cpu和/或dma會被推遲,因此cpu仍然必須等待一些時間。有時,在某些實現中(可能不是您的微控制器),CPU會完全延遲,直到DMA完成為止,CPU會持續一段時間。只是取決於實現。它的自由之處在於,不必為某些事件而不斷地中斷cpu或輪詢或屏住呼吸來饋送數據。創建到dma的下一個緩衝區可能會花費一些時間。它確實必須注意dma傳輸是否完成並進行處理,但是與其說每個字節現在是多個字節,不如說是數據塊。
沒有一個普遍的答案。“這取決於” ...取決於您所使用的特定物品的特定設計。即使在一個芯片/板/系統設計中,也可能有多個dma引擎,沒有理由假設它們都以相同的方式工作。對於每個實例,您都必須弄清楚,但是不幸的是,他們經常沒有記錄或記錄得足夠好。因此,如果您擔心的話,可能必須創建一些實驗。
到目前為止,答案是關於CPU可以發揮作用的“速度”以及DMA如何從中受益。但是,還有另一個考慮因素,即power。
如果CPU希望在慢速鏈接上發送數據包,則在使用輪詢或中斷的情況下,大部分時間它都必須處於喚醒狀態,但是主CPU可能在DMA時處於睡眠狀態正在完成。
諸如STM32H7系列之類的某些處理器具有很多RAM選項和大量緊密耦合的RAM。擁有獨立的RAM組可以使DMA錘擊大量RAM,而處理器則在不需要高速緩存且不受DMA錘擊的緊密耦合內存中處理數據。要移動數據,可以使用MDMA。我使用其中之一建造了FMCW雷達裝置。 ADC從兩個輸入獲得IQ數據到一個SRAM中。然後,我縮放數據並在dtcm ram中執行浮點256 bin複數fft。然後使用MDMA將結果FIFO放入AXI ram中的2d數組。
我在fifo上取第二個fft 64 bin作為速度矢量。然後,我對複雜數據進行大小處理,並使用12.5 MHz的SPI將檢測到的結果數據128 & 64浮點值發送到另一個H7。我在4毫秒內完成了所有這些操作。ADC的採樣率為84 kHz,使用過採樣後,我的分辨率約為18位。
對於僅在MHz範圍內運行且沒有外部RAM的通用處理器來說還不錯。
該設備的大型緩存還改善了dtcm以外的計算性能,