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
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.
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!
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.
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 SPIAxel 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?
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.
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.
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.
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
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.
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.
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.
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.