Forum: Mikrocontroller und Digitale Elektronik STM32Fxx - Grundverständnis zu DMA


von Christian J. (Gast)


Lesenswert?

Hallo,

man kann sich noch soviel Datenblätter und App.notes durchlesen, viel 
klarer wird manches leider nicht, weil da schon zu viel Basiswissen 
vorausgesetzt wird :-(

Was ist DMA?

Klar, Direct Memory Acess. Wenn ein Display angeschlossen ist, welches 
Refresh braucht, rotiert da eine Statemachine laufend um die Daten aus 
dem Controller Speicher oder SDRAM in die Pixel zu schaufeln. Ganz von 
allein, ohne dass die CPU sich drum kümmern muss.

Aber was ist ein DMA Kanal und was ein Stream?

Aber wie sieht das zb bei einer SPI aus? Eine SPI sind grundsätzlich 2 
Register RX und TX und noch einige mehr drumherum. Früher kam ein INT, 
wenn TX leer war, damit man im INT ein neues Byte einschaufeln kann. 
Jetzt
aber soll SPI und DMA verquickt werden. Wie kann man sich das 
vorstellen?

Nehmen wir an, dass ich ständig einen Datenstruct (Temperatur und 
Druckwerte Historie) per SPI an ein Funkmodul verschicken will. Kann ich 
dann die DMA so einstellen , dass sie zb auf den Struct zeigt und dieses 
Struct-Array dann ständig auf Anforderung oder von allein wiederkehrend 
in die SPI schickt?

Und muss die CPU zb warten, wenn der DMA grad auf den struct zugreift, 
die CPU aber auch einen Speicherzugriff will? Ist es da sinnvoll beim 
STM32 DMA auf RAM1 und Variablen auf RAM2 zu legen?

Könnte da vielleicht mal jemand ein paar Worte zu verlieren? (keine
Einzeiler)

Gruss,
Christian

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Christian J. schrieb:
> Könnte da vielleicht mal jemand ein paar Worte zu verlieren? (keine
> Einzeiler)

Das ist schwer. Es lohnt sich auch nicht, das Grundprinzip, welches 
schon 1000 mal im Netz steht, nochmal in anderen Worten zu beschreiben.

https://www.mikrocontroller.net/articles/DMA

Lies es Dir durch und wenn Du weitere Fragen hast, stelle sie konkret. 
Ein paar hattest Du ja schon:

> was ist ein DMA Kanal und was ein Stream?

Ich würde den "Datenblock" im RAM als Stream bezeichnen. DMA kann den 
Stream lesen und rausschicken oder einlesen und schreiben, wie Du selbst 
schon sagtest.

> Eine SPI sind grundsätzlich 2 Register RX und TX …
> Wie kann man sich das vorstellen?

Also zwei DMA-Kanäle. Für die zwei "Streams" kannst Du einen und den 
selben Datenblock (RAM-Bereich) nehmen, wenn das im Einzelfall Sinn 
macht. Vorher steht TX drin, hinterher RX.

> Kann ich dann die DMA so einstellen …

Ja (sorry, Einzeiler^^)

> Und muss die CPU zb warten, wenn der DMA grad auf den struct zugreift,

Nein. DMA und CPU greifen abwechseld auf den Speicher zu. Das hängt im 
Detail vom Prozessor ab. Ich nutze auch den STM32.

> Früher kam ein INT, wenn TX leer war

Und nun kannst Du wählen:
* INT bei "Stream halb voll",
* INT bei "Stream komplett" oder beides.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Torsten C. schrieb:

> Also zwei DMA-Kanäle. Für die zwei "Streams" kannst Du einen und den
> selben Datenblock (RAM-Bereich) nehmen, wenn das im Einzelfall Sinn
> macht. Vorher steht TX drin, hinterher RX.

Also so?

Feld[1024 Bytes]
DMA konfigurieren
DMA starten auf SPI
durchlaufe
   Feld[x] -> SPI_TX
   SPI_RX->Feld[x]
   x = x+1;
1024 mal und stop

Das ist ja cool!

von Axel S. (a-za-z0-9)


Lesenswert?

Torsten C. schrieb:
> Christian J. schrieb:
>> Könnte da vielleicht mal jemand ein paar Worte zu verlieren? (keine
>> Einzeiler)
>
> Das ist schwer. Es lohnt sich auch nicht, das Grundprinzip, welches
> schon 1000 mal im Netz steht, nochmal in anderen Worten zu beschreiben.
>
> https://www.mikrocontroller.net/articles/DMA
>
> Lies es Dir durch und wenn Du weitere Fragen hast, stelle sie konkret.

ACK.

>> was ist ein DMA Kanal und was ein Stream?
>
> Ich würde den "Datenblock" im RAM als Stream bezeichnen.

Das kaufe ich nicht. Ein DMA-Transfer muß keineswegs RAM als Ziel oder 
als Quelle haben. Man kann auch Daten von einem IO auf einen anderen 
schaufeln. Z.B. vom SPI zum UART. o.ä.

Ein DMA-Kanal ist eine logische Einheit des DMA-Controllers, die Daten 
gemäß der programmierten Parameter (Quelle, Ziel, Zähler, Warte-/ 
Auslösebedingung) überträgt.

Der Begriff Stream ist mir in diesem Zusammenhang nicht als fester 
technischer Terminus geläufig. Aber da man DMA gerne für die Übertragung 
von Daten in einem festen zeitlichen Raster (eben streaming) 
verwendet, könnte man die übertragenen Daten so nennen.

>> Eine SPI sind grundsätzlich 2 Register RX und TX …
>> Wie kann man sich das vorstellen?
>
> Also zwei DMA-Kanäle.

Nur dann, wenn man sowohl lesen als auch schreiben will.

>> Und muss die CPU zb warten, wenn der DMA grad auf den struct zugreift,
>
> Nein. DMA und CPU greifen abwechseld auf den Speicher zu. Das hängt im
> Detail vom Prozessor ab.

Ja, hängt es. Deswegen ist dein "Nein" oben auch falsch. Genauer gesagt 
hängt es von den verfügbaren Bussen ab und ob CPU und DMA gerade auf den 
gleichen Bus zugreifen wollen (dann muß die CPU warten) oder nicht.

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Vermutlich war das richtige gemeint. Trotzdem zur Sicherheit:

Christian J. schrieb:
> durchlaufe
>    Feld[x] -> SPI_TX
>    SPI_RX->Feld[x]
>    x = x+1;
> 1024 mal und stop

Das^^ mach der DMA-Controller, das musst Du also nicht für die CPU 
programmieren. Programmieren tust Du z.B. in C nur:

> Feld[1024 Bytes]
> DMA konfigurieren
> DMA starten auf SPI

Axel S. schrieb:
> Das kaufe ich nicht. Ein DMA-Transfer muß keineswegs RAM als Ziel oder
> als Quelle haben.

Wohl war. "Stream" ist halt der "Datenstrom".

Axel S. schrieb:
> Deswegen ist dein "Nein" oben auch falsch.

Der Thread heißt "STM32Fxx - Grundverständnis zu DMA". Kennst Du 
STM32Fxx bei denen das anders ist?

von Little B. (lil-b)


Lesenswert?

Christian J. schrieb:
> Aber was ist ein DMA Kanal und was ein Stream?

wurde noch nicht gesagt: Ein Kanal ist dann die Triggerquelle, mit der 
ein einzelner DMA-Transfer veranlasst wird. Verschiedene Streams haben 
unterschiedliche Triggerquellen.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

STM: Ein oder zwei DMA Kontroller.

Danach wird es zwischen F1 DMA (bei F0/F1/F3/L0/L1/L4) und F2 DMA 
(F2/F4/F7) verwirrend. Was bei F1 ein Channel ist, ist bei F2 ein 
Request_Stream. Pro DMA koennen diese Channels (F1) oder Request 
Streams(F2) mit zueinander festgelegter Prioritaet gleichzeitig laufen. 
Bei F2 hat jeder Request Stream eine Anzahl moeglicher Datenquellen. Die 
Datenquelle waehlt man mit der Channel Nummer aus. Bei den kleineren F1 
Derivaten ist die Quelle fest, bei manchen Typen kann man mit SYSCFG 
Bits die Quelle umschalten und um die Verwirrung vollstaendig zu machen, 
kennt F091/L0 und L4 eine Kanalauswahl, die jetzt Request number heisst.

Zieh Dir mal die entsprechenden Referenzmanuals rein.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Hoppla: Ersetze Datenquelle mit Triggerquelle...

von W.S. (Gast)


Lesenswert?

Christian J. schrieb:
> Was ist DMA?
>
> Klar, Direct Memory Acess. Wenn ein Display angeschlossen ist, welches
> Refresh braucht, rotiert da eine Statemachine laufend um die Daten aus
> dem Controller Speicher oder SDRAM in die Pixel zu schaufeln....

Siehste.
Der Displaycontroller ist also ein eigenständiger Core, der neben der 
CPU als Master auf die Busse innerhalb des Controllers zugreifen kann - 
und wenn er das braucht, dann tut er es auch (das Zugreifen). Während 
dieses Zugriffs muß die CPU ggf. warten (falls sie das Gleiche grad 
vorhat).

Nun gibt es neben CPU (und ggf. Displaycontroller) je nach Chip auch 
noch andere Cores, die als Master auf die "innerbetrieblichen" Busse 
zugreifen können und einer oder mehrere davon können DMA-Cores sein.

Deren Lebenszweck ist es eigentlich immer, auf ein Triggersignal hin 
irgendwelche Daten von A nach B zu schaufeln. Wer mag, kann dies 
"Datenstrom" oder "Stream" nennen.

Ob das 8 oder 16 oder 32 Bit Daten sind und ob A und/oder B jeweils ein 
einziges Register ist oder ein Array, ob der DMA-Core nur 1x durchlaufen 
soll oder wiederholend, ob er nur einen Satz 
Schleifen-Parameter-Register hat oder mehrere geschachtelte (wie z.B. 
bei den Freescale-Cortexen) - kurzum, wie kompliziert und vigilantisch 
so ein DMA-Core aufgebaut ist (und wie schlecht dies alles dokumentiert 
ist), das ist von dem konkreten Hersteller und vom Chip abhängig.

Also, was du über die DMA-Einheit des einen Herstellers gelesen hast, 
trifft nur in den allgemeinen Grundzügen für einen anderen zu - nicht 
jedoch für die Details, in denen bekanntlich der Teufel steckt.

W.S.

von Christian J. (Gast)


Lesenswert?

Hallo,

erstmal danke für die Infos! Ich werde das mal verdauen und heute aben 
mal ausprobieren, wie ich mit den StdPeriph Libs eine einfache Aufgabe 
lösen kann, nämlich besagten Struct auf der SPI raustrommeln. Einfach 
nur am Oszi schauen, was da so ankommt.

Ich vermute mal, dass wenn man den STM32F4 voll ausreizt, alle SPI, ADC 
und den Kryptokram usw. unter Dampf setzt, dass der Stein ganz schön 
Arbeit leisten kann.

gruss,
Christian

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Wenn Du es verstehen willst, probier es auf Registerebene...

von Christian J. (Gast)


Lesenswert?

Uwe B. schrieb:
> Die
> Datenquelle waehlt man mit der Channel Nummer aus.

In der Appnote zum F4xx ist eine Tabelle drin, die den Peripherals 
jeweils Kanaele zuordnet. Glaube frei wählbar ist da nicht viel.

von Christian J. (Gast)


Lesenswert?

Uwe B. schrieb:
> Wenn Du es verstehen willst, probier es auf Registerebene...

Nope. Nicht bei einem Cortex. Bei einem LPC2368 ging das ohne weiteres. 
Es muss nur funktionieren, wie es funktioniert ist mir inzwischen egal.

von Christian J. (Gast)


Lesenswert?

PS:

Das ist heute bei den meisten Chips immer das Gleiche: Beschreibe eine 
Vielzahl von Registern und lege hundert Schalter um, damit das passiert 
was Du haben willst. Bei einem ARM11 (im A20 Core) ist das noch viekl 
extremer, der zieht sich eine ganze config.bin Datei mit tausend 
Einstellungen für alle Peripheriegeräte. Ich meine, dass mit Ende der 
LPC2xxxx Serie die zeiten vorbei sind, wo man auf Registerebene 
arbeitet, sondern einfach das standardisierte CMSIS nimmt.

von greg (Gast)


Lesenswert?

Bei Mini-Micro-ARMs (LPC800 u.Ä.) die kleine 8-Bitter ersetzen sollen, 
macht es häufig noch Sinn, direkt die Register zu beschreiben. Es ist 
auch noch alles schön überschaubar.

Wenn man dagegen ein Cortex-M4-Monster mit 1 MB Flash und geschätzten 
137 Peripherieblöcken hat... klar, vergiss es. Lohnt nur in 
Ausnahmefällen.

CMSIS hat natürlich i.A. trotzdem immer noch nichts mit Treibern für 
herstellerspezifische Peripherie zu tun.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.