Was bringt DMA in Embedded-CPUs?


17

Ich habe kürzlich ein Projekt mit dem mbed (LPC1768) durchgeführt, bei dem der DAC zur Ausgabe verschiedener Wellen verwendet wurde. Ich habe Teile des Datenblattes gelesen und es wurde darüber gesprochen, wie es DMA für viele Peripheriegeräte gab. Dies schien nützlich zu sein, aber bei weiterer Lektüre stellte ich fest, dass der DMA denselben Datenbus wie die CPU verwendete (was ich für normal halte). Bedeutet dies, dass die CPU mit keinem der Speicher interagieren kann, während der DAC Daten abruft? Auch, da der DAC keinen Puffer hatte (soweit ich das beurteilen konnte) und daher sehr oft DMA muss, was ist der Sinn von DMA? Wenn die CPU keine Speichertransaktionen ausführen kann, kann sie dann etwas tun?


8
Ich schlage vor, Sie schauen sich die Funktionen Ihrer CPU an und prüfen, ob sie etwas anderes als den Zugriff auf den Arbeitsspeicher leisten kann. Ich habe von einigen CPUs gehört, die Dinge wie Entscheidungen oder Berechnungen
ausführen können

Sollte die CPU Zeit damit verbringen, Daten an einen E / A-Port zu übertragen oder die Aufgabe an ein dediziertes Gerät zu delegieren?
StainlessSteelRat

Ja, die CPU kann andere Aufgaben ausführen, aber in einem eingebetteten System verbringt sie wahrscheinlich viel Zeit mit der Kommunikation mit Peripheriegeräten, insbesondere mit E / A-Anschlüssen. Wäre es nicht sinnvoller, einen zusätzlichen Datenbus nur für DMA zu haben? Oder ist das normalerweise nicht nötig? Die Situation, in der Sie einen zusätzlichen Bus benötigen, ist, wenn Sie versuchen, die Grenzen Ihrer Hardware zu überschreiten. Ich gehe davon aus, dass Sie trotzdem DMA verwenden möchten.
BeB00

1
Einfaches Beispiel: Sie möchten viele Informationen über eine serielle Schnittstelle drucken. Sie können entweder warten, bis jedes Byte gesendet wurde (langsam), es in einen Puffer kopieren und dann Interrupts in der CPU verwenden, um jedes Byte zu senden, wenn der Port bereit ist (viel Kontextumschaltung = langsam), oder es nach kopieren einen Puffer und lassen Sie den DMA-Controller die Daten ausschalten, während die CPU andere Aufgaben ausführt (dies kann schneller sein).
Tom Carpenter

2
Wir haben einmal ein EDN-Cover gesehen, auf dem ein Mann mit einem riesigen, drei Fuß langen Schuh und der Überschrift "Wenn es ein Schuh ist, tragen Sie ihn" abgebildet ist. Der springende Punkt war: Wenn ein Teil zehn Dinge erledigt, die Sie nicht brauchen, und eine Sache, die Sie brauchen, und der Preis, der Platzbedarf und das Strombudget passen, dann sollten Sie es einfach nutzen und Ihre Zeit nicht damit verschwenden, nach etwas zu suchen mit weniger Funktionen.
Solomon Slow

Antworten:


17

Das von mir gefundene LPC1768-Datenblatt enthält die folgenden Anführungszeichen (Hervorhebung von mir):

Acht-Kanal-Allzweck-DMA-Controller (GPDMA) auf der AHB-Multilayer-Matrix, der mit SSP-, I2S-Bus-, UART-, Analog-Digital- und Digital-Analog-Wandler-Peripheriegeräten, Timer-Übereinstimmungssignalen und für Memory-to-Signale verwendet werden kann -Speichertransfers.

Der geteilte APB-Bus ermöglicht einen hohen Durchsatz mit wenigen Unterbrechungen zwischen der CPU und dem DMA

Das Blockdiagramm auf Seite 6 zeigt SRAM mit mehreren Kanälen zwischen der AHB-Matrix und das folgende Zitat belegt dies:

Der LPC17xx enthält insgesamt 64 kB On-Chip-RAM-Speicher. Dazu gehören der 32-kB-SRAM, auf den die CPU und der DMA-Controller über einen Hochgeschwindigkeitsbus zugreifen können, und zwei zusätzliche 16-kB-SRAM-Blöcke, die sich an einem separaten Slave-Port der AHB-Mehrschichtmatrix befinden. Durch diese Architektur können CPU- und DMA-Zugriffe auf drei separate RAMs verteilt werden, auf die gleichzeitig zugegriffen werden kann

Und dies wird durch folgendes Zitat untermauert:

Der GPDMA ermöglicht Transaktionen von Peripheriegerät zu Speicher, von Speicher zu Peripheriegerät, von Peripheriegerät zu Peripheriegerät und von Speicher zu Speicher.

Daher können Sie Daten von einem der separaten SRAM-Blöcke oder von einem anderen Peripheriegerät zu Ihrem DAC streamen, während Sie den Haupt-SRAM für andere Funktionen verwenden.

Diese Art von Peripherie-Peripherie-DMA ist in kleineren Teilen üblich, in denen die Speicherschnittstelle recht einfach ist (im Vergleich zu einem modernen Intel-Prozessor).


Ahh, danke, ich wusste nicht, dass das möglich ist, ich bin ein bisschen neu bei DMA. Bedeutet das, dass die CPU auf Peripheriegeräte zugreifen kann, während der DAC auf den separaten SRAM zugreift?
BeB00

1
Ja - genau dafür ist die AHB-Matrix gedacht. Es ermöglicht verschiedenen Controllern (CPU, DMA, bestimmten Peripheriegeräten wie Ethernet und USB) gleichzeitig auf verschiedene Dinge zuzugreifen. Aus diesem Grund verfügt der SRAM über mehrere "Ports".
David

Ja, der AHB in diesen billigen kleinen Lebewesen liefert verrückte Speicherbandbreiten aufgrund der parallelen Speicherbänke: Sie können Ethernet, USB2 und alles mit maximalem Durchsatz betreiben und die CPU merkt es nicht einmal ...
peufeu

Außerdem kann der Daumencode 2 Anweisungen in ein 32-Bit-Wort setzen, sodass die CPU möglicherweise nicht so oft auf den Bus zugreifen muss, wenn sie Berechnungen durchführt oder Operationen ausführt, die hauptsächlich Register betreffen ... Auf der anderen Seite können die M3 und M4 Mache mehrere Speicherzugriffe pro Takt (Befehl und Daten), weil du mehrere Busse hast.
Peufeu

30

Das Lange und Kurze ist, dass DMA es der CPU ermöglicht, sich effektiv mit ihrer nativen Geschwindigkeit zu verhalten, während sich die Peripheriegeräte effektiv mit ihrer nativen Geschwindigkeit verhalten können. Die meisten Zahlen im Beispiel sind erfunden.

Vergleichen wir zwei Optionen, um regelmäßig Daten von einem ADC zu erfassen:

  1. Sie können den ADC als Teil eines Interrupts einstellen (periodisch oder auf andere Weise).
  2. Sie können einen Puffer erstellen und den DMA anweisen, ADC-Messwerte in den Puffer zu übertragen.

Lassen Sie uns 1000 Samples vom ADC in den RAM übertragen.

Verwendung von Option 1: Für jede Probe gibt es

  • Es werden 12 Zyklen für die Eingabe des Interrupts benötigt
  • adc (s) lesen
  • im ram lagern
  • Es werden 12 Zyklen mit dem Verlassen des Interrupts verbracht

Nehmen wir an, diese Interrupt-Funktion besteht aus 76 Befehlen, die gesamte Routine besteht aus 100 Befehlen, vorausgesetzt, die Ausführung erfolgt in einem Zyklus (bester Fall). Das bedeutet, dass Option 1 100.000 CPU-Zyklen benötigt.

Option 2: DMA ist so konfiguriert, dass 1000 ADC-Proben erfasst werden. Nehmen wir an, der ADC hat einen Hardware-Trigger von einem Timer-Zähler.

  • ADC und DMA übertragen 1000 Abtastdaten in den RAM
  • DMA unterbricht Ihre CPU nach 1000 Samples
  • Es werden 12 Zyklen für die Eingabe des Interrupts benötigt
  • Code passiert (sagen wir, es sagt dem DMA, dass er den RAM überschreiben soll)
  • Es werden 12 Zyklen mit dem Verlassen des Interrupts verbracht

Das Vorgeben des gesamten Interrupts (mit Eintritts- und Austrittsaufwand) besteht aus 100 Einzelzyklusanweisungen. Mit DMA verbringen Sie nur 100 Zyklen, um die gleichen 1000 Proben zu speichern.

Nun, jedes Mal, wenn der DMA auf den Bus zugreift, kann es zu einem Konflikt zwischen CPU und DMA kommen. Möglicherweise muss die CPU sogar warten, bis der DMA abgeschlossen ist. Das Warten auf den Abschluss des DMA ist jedoch viel kürzer als das Sperren der CPU für die Wartung des ADC. Wenn der CPU-Kerntakt 2x Bustakt ist, verschwendet die CPU möglicherweise einige Kernzyklen, bis der DMA abgeschlossen ist. Dies bedeutet, dass Ihre effektive Ausführungszeit für die Übertragung zwischen 1000 (vorausgesetzt, die CPU wartet nie) und 9000 Zyklen liegt. Immer noch viel besser als die 100.000 Zyklen.


2
Es ist wichtig zu beachten, dass RAM nicht der einzige Ort ist, an dem die CPU Daten speichern kann. In der Regel lädt die CPU die Daten aus dem RAM in Register, bevor sie bearbeitet werden.
Aron

Yah, absolut richtig. Mein Beispiel ist nur eine grobe Skizze.
pgvoorhees

Viele Mikrocontroller haben auch einen Mehrschichtbus, so dass gleichzeitige Operationen möglich sind. ZB: adc-> ram und flash-> gleichzeitig registrieren. Außerdem sind viele Anweisungen länger als 1 Uhr, sodass für den DMA genügend Zeit bleibt.
Jeroen3

9

Wenn der Prozessor und ein DMA-Controller in einem bestimmten Zyklus auf denselben Bus zugreifen müssten, müsste der eine oder andere warten. Viele Systeme enthalten jedoch mehrere Speicherbereiche mit getrennten Bussen sowie eine "Busbrücke", über die die CPU auf einen Speicher zugreifen kann, während der DMA-Controller auf einen anderen zugreift.

Außerdem müssen viele CPUs möglicherweise nicht in jedem Zyklus auf ein Speichergerät zugreifen. Wenn eine CPU normalerweise nur in zwei von drei Zyklen auf den Speicher zugreifen muss, kann ein DMA-Gerät mit niedriger Priorität möglicherweise Zyklen ausnutzen, wenn der Speicherbus ansonsten inaktiv wäre.

Sogar in Fällen, in denen jeder DMA-Zyklus dazu führen würde, dass die CPU für einen Zyklus angehalten wird, kann DMA dennoch sehr hilfreich sein, wenn Daten mit einer Geschwindigkeit ankommen, die langsam genug ist, dass die CPU in der Lage sein sollte, andere Dinge zwischen eingehenden Datenelementen zu tun , aber schnell genug, dass der Overhead pro Artikel minimiert werden muss. Wenn ein SPI-Port beispielsweise alle 16 CPU-Zyklen Daten mit einer Rate von einem Byte an ein Gerät überträgt, würde eine Unterbrechung der CPU für jede Übertragung wahrscheinlich fast die gesamte Zeit für die Eingabe und Rückkehr aus der Interrupt-Serviceroutine aufwenden und keine irgendwelche eigentliche Arbeit zu tun. Bei Verwendung von DMA kann der Overhead jedoch auf 13% reduziert werden, selbst wenn bei jeder DMA-Übertragung die CPU zwei Zyklen lang blockiert.

Schließlich erlauben einige CPUs die Durchführung von DMA, während die CPU schläft. Die Verwendung einer Interrupt-basierten Übertragung würde erfordern, dass das System für jede übertragene Dateneinheit vollständig aufwacht. Bei Verwendung von DMA kann der Schlaf-Controller dem Speicher-Controller jedoch jedes Mal, wenn ein Byte eingeht, ein paar Takte zuführen, aber alles andere schlafen lassen, wodurch der Stromverbrauch verringert wird.


1
Die Cortex-M-Teile wie der LPC1768 haben einen eigenen Speicherpfad vom Flash zum Befehlsdecoder, sodass Register-zu-Register-Operationen bedeuten können, dass die CPU zwischen den Zeitpunkten, zu denen sie Zugriff auf den Datenspeicher benötigt, mehrere Befehle ausführen kann.
Chris Stratton

5

Als Programmierer ist DMA eine Option zum Übertragen von Daten zu und von Peripheriegeräten, die diese unterstützen. Für das klassische Beispiel des Verschiebens eines großen Puffers durch ein serielles Peripheriegerät wie SPI oder UART oder des Sammelns mehrerer Samples von einem ADC stehen drei Methoden zum Verschieben dieser Daten zur Verfügung:

  1. Polling-Methode. Hier warten Sie auf die Register-Flags, damit Sie das nächste Byte ein- und ausschieben können. Das Problem ist, dass Sie die gesamte Ausführung der CPU aufhalten, während Sie darauf warten. Wenn Sie die CPU-Zeit in einem Betriebssystem gemeinsam nutzen müssen, wird Ihre Übertragung drastisch verlangsamt.

  2. Unterbrechungsmethode. Hier schreiben Sie eine Interrupt-Service-Routine (ISR), die bei jeder Byte-Übertragung ausgeführt wird, und schreiben den Code in die ISR, die die Übertragung verwaltet. Dies ist CPU-effizienter, da die CPU Ihren ISR nur bei Bedarf bedient. Es kann zu allen anderen Zeiten außer im ISR kostenlos verwendet werden. ISR ist auch eine der schnelleren Optionen für die Übertragung in Bezug auf die Übertragungsgeschwindigkeit.

  3. DMA. Sie konfigurieren den DMA mit Quell- / Zielzeigern, Anzahl der Übertragungen und los geht's. Es wird Buszyklen und CPU-Zeit stehlen, um die Übertragung durchzuführen, und die CPU ist in der Zwischenzeit frei, andere Dinge zu tun. Sie können ein Flag oder einen Interrupt konfigurieren, um anzuzeigen, wann die Übertragung abgeschlossen ist. Es ist normalerweise eine Berührung schneller als ISR und ist normalerweise Ihre schnellste Übertragungsoption.

Als Programmierer bevorzuge ich DMA, weil es am einfachsten zu codieren ist und im Grunde die schnellste Technik ist, um die Übertragung durchzuführen. Normalerweise müssen Sie nur ein paar Register für die Quell- / Zielzeiger und die Anzahl der durchzuführenden Übertragungen konfigurieren. Ich arbeite viel mehr Stunden mit ISR-Code als mit DMA-beschleunigtem Code, da ISR-Code wichtige Entwurfsfähigkeiten erfordert und codiert, getestet, verifiziert usw. werden muss. Der DMA-Code ist viel kleiner und der Code muss von mir selbst geschrieben werden ist relativ trivial, und ich bekomme maximale Übertragungsgeschwindigkeit in den Handel.

Meiner Erfahrung nach arbeitet DMA in letzter Zeit mit Atmel SAM3 / 4-Prozessoren schneller als ein effizienter ISR, den ich selbst erstellt habe. Ich hatte eine Anwendung, die alle 5 ms einen Stapel von Bytes von SPI einliest. In Hintergrundaufgaben wurde viel Gleitkomma-Mathematik ausgeführt, daher wollte ich, dass die CPU für diese Aufgaben so frei wie möglich ist. Die anfängliche Implementierung war ISR, und ich wechselte dann zu DMA, um zu vergleichen und zu versuchen, zwischen den Beispielen etwas mehr CPU-Zeit zu kaufen. Die Übertragungsgeschwindigkeit wurde geringfügig verbessert, jedoch nur geringfügig. Es war am O-Scope kaum messbar.

Das liegt daran, dass bei den neuesten Mikroprozessoren, die ich gesehen habe, ISR und DMA fast auf die gleiche Weise arbeiten - sie benötigen die erforderlichen CPU-Zyklen und der DMA führt im Wesentlichen die gleichen Vorgänge mit der CPU aus, die ich in einem effizienten ISR codiert hätte .

In seltenen Fällen habe ich Peripheriegeräte gesehen, deren eigener RAM-Bereich NUR für DMA zugänglich war. Dies war auf Ethernet-MACs oder USBs.


3

Hier wird höchstwahrscheinlich DMA verwendet, damit der DAC ein gewisses Zeitintervall hat und eine Wellenform erzeugt, indem der Analogausgang in einem bekannten Intervall geändert wird.

Ja, wenn es sich um einen geteilten Bus handelt, müssen Sie diesen teilen.

Die CPU benutzt nicht immer den Bus, daher ist es manchmal eine gute Idee, sie mit einer DMA-Engine zu teilen. Und das bedeutet natürlich, dass Prioritäten involviert werden, manchmal ist es nur derjenige, der zuerst da war (zum Beispiel haben Sie ein Befehl-FIFO vor der Ressource und FIFO-Anfragen in der Reihenfolge, in der sie ankommen, ja, das wäre nicht unbedingt deterministisch ). In einem solchen Fall möchten Sie möglicherweise, dass das DMA Vorrang vor der CPU hat, damit zeitkritische Dinge wie DACs oder ADCs ein deterministisches Timing haben. Kommt darauf an, wie sie es umgesetzt haben.

Leute haben manchmal diese oft falsche Annahme, dass DMA kostenlos ist. Es ist nicht so, dass es immer noch Buszeit verbraucht. Wenn es mit der CPU geteilt wird (was es schließlich ist, wenn es mit einer Ressource spricht, mit der die CPU sprechen kann), dann wird die CPU und / oder der DMA ausgeschaltet, so dass die CPU immer noch etwas warten muss Zeit, in einigen Implementierungen (wahrscheinlich nicht Ihr Mikrocontroller) ist die CPU vollständig ausgeschaltet, bis die DMA abgeschlossen ist, CPU wird für die Dauer gestoppt. Kommt halt auf die Umsetzung an. Der freie Teil davon ist, dass die CPU nicht ständig unterbrochen oder abgefragt oder angehalten werden muss, damit ein Ereignis Daten einspeist. Es kann einige Zeit dauern, bis der nächste Puffer für die DMA erstellt ist. Es muss darauf achten, dass die DMA-Übertragung abgeschlossen ist und damit umgeht, aber anstatt zu sagen, dass jedes Byte jetzt mehrere Bytes sind, einige Datenblöcke.

Es gibt keine universelle Antwort. "Es kommt darauf an" ... auf das spezifische Design des von Ihnen verwendeten Gegenstands. Selbst innerhalb eines Chip / Board / System-Designs können mehrere DMA-Engines vorhanden sein, und es gibt keinen Grund anzunehmen, dass sie alle auf die gleiche Weise funktionieren. Für jeden Fall muss man es herausfinden, und leider dokumentieren sie es oft nicht oder nicht gut genug. Daher müssen Sie möglicherweise einige Experimente erstellen, wenn Sie Bedenken haben.


note embedded hat nichts damit zu tun. Der Punkt von DMA ist, Leistung zu erzielen, indem möglicherweise Arbeit für die CPU geleistet wird, damit sie keinen Code haben muss, und die normalerweise nicht verwendeten Buszyklen auszunutzen und dort zu arbeiten. Auch für Dinge wie in Ihrer Frage, Daten zum richtigen Zeitpunkt zu füttern, idealerweise ohne CPU-Overhead. Diese Vorteile sind sinnvoll eingebettet oder nicht.
old_timer

1

Die bisherigen Antworten sprechen von der „Geschwindigkeit“, mit der die CPU arbeiten kann, und wie DMA davon profitiert. Es gibt jedoch noch eine andere Überlegung, die Macht .

Wenn die CPU ein Datenpaket auf einer langsamen Verbindung senden möchte, muss sie die meiste Zeit wach sein, wenn Abfragen oder Interrupts verwendet werden. Die Haupt-CPU kann sich jedoch möglicherweise in einem Ruhezustand befinden, während DMA ausgeführt wird .


0

Einige Prozessoren wie die STM32H7-Serie bieten viele RAM-Optionen und jede Menge eng gekoppelten RAM. Wenn separate RAM-Bänke vorhanden sind, kann DMA eine Menge RAM verarbeiten, während der Prozessor Daten im eng gekoppelten RAM verarbeitet, der kein Caching erfordert und nicht von DMA verarbeitet wird. Zum Verschieben von Daten können Sie MDMA verwenden. Ich habe ein FMCW-Radargerät mit einem dieser Geräte gebaut. Die ADCs erhalten IQ-Daten von zwei Eingängen in einen SRAM. Ich skaliere dann die Daten und führe den Gleitkomma-256-bin-Komplex fft in dtcm-RAM aus. Dann FIFO das Ergebnis in ein 2D-Array in AXI-RAM mit MDMA.

Ich nehme ein zweites FFT 64 Bin über das FIFO für den Geschwindigkeitsvektor. Ich mache dann die Größe der komplexen Daten und sende die resultierenden 128- und 64-Gleitkommawerte mit SPI bei 12,5 MHz zur Erkennung an einen anderen H7. Ich mache das alles in 4 ms.

Die Abtastrate des ADCs beträgt 84 kHz und mit Oversampling erhalte ich eine Auflösung von ca. 18 Bit.

Nicht schlecht für einen Allzweckprozessor, der nur im MHz-Bereich und ohne externen RAM läuft.

Auch die großen Caches, die dieses Gerät für Berechnungen außerhalb des dtcm-Bereichs bietet, tragen zur Leistungsverbesserung bei.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.