ATxmega - DMA

Janiiix3

Aktives Mitglied
28 Sep 2013
1.321
10
38
Hannover
Sprachen
ANSI C, C#
Kann es sein das der DMA Controller deutlich schneller ist als eine UART Schnittstelle?

Bin aktuell dabei den DMA auf einem 256A3BU zu nutzen. Wenn ich einen String direkt an das Register vom UART sende kommt auf dem Terminal nur die ersten beiden Buchstaben an.
Kopiere ich es von einem Array in ein anderes habe ich alles so wie es sein sollte..
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.344
61
48
Marwitz
Sprachen
BascomAVR, Assembler
Kann es sein das der DMA Controller deutlich schneller ist als eine UART Schnittstelle?
???
SRAM- und I/O-Zugriffe laufen parallel über den 8/16bit-Datenbus. Der DMA scheint quasi sowas ähnliches wie ein separater Datenbus zu sein (bzw vier davon). Der UART ist ein Serieller Bus, und somit grundsätzlich langsamer (erst recht bei langsamerer Baudrate).
Du mußt also den verwendeten DMAC an den UART anpassen.
Zwei Zeichen kommen durch, weil der Transmitter gepuffert ist - wenn Du einen String "sendest", werden nacheinander alle Zeichen ins Transmit-Register geschrieben.
Sobald dort ein Zeichen erscheint, wird es ans Transmit-Schieberegister weiterkopiert (aber nur, wenn letzteres frei ist), was den tatsächlichen Transfer auslöst (Das heißt nämlich Schieberegister, weil es seine Bits auf den Tx-Pin (*Trommelwirbel*) … schiebt).
Das zweite Zeichen landet im Transmit-Register, kann aber nicht ins Schieberegister (da das nicht leer ist), also wartet es dort bis das Schieberegister leer ist (und wird dann automatisch gesendet.
Da jetzt Zeichen "2" auch das Transmit-Register blockiert, landen die nächsten x Zeichen im Nirvana.
Irgendwann ist Zeichen "1" aus dem Schieberegister rausgepumpt, Zeichen "2" ins Schieberegister übertragen (wird rausgepumpt), das Transmit-Register wieder frei.
Das nächste Zeichen würde also wieder gesendet werden. Mach den String mal (ggf deutlich) länger;).
 
Zuletzt bearbeitet:

Janiiix3

Aktives Mitglied
28 Sep 2013
1.321
10
38
Hannover
Sprachen
ANSI C, C#
Habe den String schon deutlich länger gemacht.. Aber der DMA ist deutlich schneller.. Gibt es ne möglichkeit den warten zu lassen, bis der UART wieder frei ist?
 

Mikro23

Aktives Mitglied
2 Jan 2017
366
33
28
Großraum Hannover
Sprachen
ANSI C, Assembler
Kann es sein das der DMA Controller deutlich schneller ist als eine UART Schnittstelle?
Je nachdem, wie schnell der CPU-Takt und der UART-Takt eingestellt sind, ist der DMA so grob über den Daumen geschätzt zwischen einigen tausend- und einigen hunderttausendmal schneller.
Gibt es ne möglichkeit den warten zu lassen, bis der UART wieder frei ist?
Der UART hat ein Bit, das nennt sich DRE. Darüber kann man entweder einen Interrupt oder ein Event auslösen.
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.321
10
38
Hannover
Sprachen
ANSI C, C#
Der UART hat ein Bit, das nennt sich DRE. Darüber kann man entweder einen Interrupt oder ein Event auslösen.
Das habe ich schon gesehen. Das kann man jedoch nur als "Trigger Source" nehmen oder sehe ich das falsch?
Und im Endeffekt ist ja der DMA da, damit man kaum bis keine CPU Last hat und damit man eben nicht auf irgendwas warten muss..

Das heißt im Endeffekt. Ich müsste mir eine andere Lösung suchen..
 
Zuletzt bearbeitet:

Mikro23

Aktives Mitglied
2 Jan 2017
366
33
28
Großraum Hannover
Sprachen
ANSI C, Assembler
oder sehe ich das falsch?
Ja.

Wenn Du den UART nicht im MHz-Bereich betreibst, lohnt sich der DMA mMn nicht.
Da reicht es völlig aus, über den DRE-Interrupt jeweils ein Byte nachzuschieben, bis der Out-Buffer leer ist.

Der DMA ist dazu gut, schnell Speicherbereiche ohne CPU-Belastung zu kopieren oder z.B. 192.000 Bytes pro Sekunde vom SPI abzuholen und in den DA-Wandler zu stecken o.ä.
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.344
61
48
Marwitz
Sprachen
BascomAVR, Assembler
OT:
zwischen einigen tausend- und einigen hunderttausendmal schneller.
Ein "normales" Byte besteht aus acht Bit, zusätzlich je ein Start- und ein Stopbit wären zehn Bit, die pro Byte zu übertragen wären.
Maximale Übertragungsrate wären acht Takte pro Bit, also 80 Takte pro Byte.
Ich kenne mich mit XMegas im allgemeinen, und dem DMAC im speziellen natürlich nicht aus, aber auch dieser wird über den Systemtakt getrieben, oder?
Aus dem Bauch heraus würde ich pro Transfer mehr als einen Takt erwarten, aber über den Daumen könnte man "hundertmal bis..." angeben - wobei Jan den UART sicher nicht auf "was haste was kannste" gestellt haben wird...
 

Mikro23

Aktives Mitglied
2 Jan 2017
366
33
28
Großraum Hannover
Sprachen
ANSI C, Assembler
Ich weiß nicht mehr wie schnell die Xmegas sind, würde aber erwarten, daß von RAM zu RAM höchstens zwei Taktzyklen gebraucht werden, ein Byte lesen und ein Byte schreiben.
Von Speicher zu Peripherie müßte sogar ein Byte pro Takt möglich sein (auch bei 32 MHz), sofern das Peripheriegerät überhaupt so schnell mitkommt
Ein "normales" Byte besteht aus acht Bit, zusätzlich je ein Start- und ein Stopbit wären zehn Bit, die pro Byte zu übertragen wären.
Maximale Übertragungsrate wären acht Takte pro Bit, also 80 Takte pro Byte.
Ich bezog mich nur auf den DMA, der ist parallel. Also 16 bis 32 Megabyte pro Sekunde, im Vergleich zu UART.
.
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.321
10
38
Hannover
Sprachen
ANSI C, C#
Okay.. Also war meine Vermutung richtig, dass der DMA einfach viel zu schnell ist für den UART..
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.344
61
48
Marwitz
Sprachen
BascomAVR, Assembler
bezog mich nur auf den DMA, der ist parallel
Nein, Du hast die Geschwindigkeiten von DMA und UART verglichen. Ein Byte durch den DMAC zu jagen (oder über den Datenbus allgemein) benötigt mindestens wenige Takte (Ob nun ein, zwei oder auch drei ist egal), ein Byte ( 8Bit Daten) durch den UART zu jagen hingegen mindestens knapp hundert Takte. Also nicht mindestens Faktor "mehrere Tausend", sondern "nur" mindestens Faktor "knapp hundert"...
war meine Vermutung richtig, dass der DMA einfach viel zu schnell ist für den UART
Jain...
Genau so kannst Du auch sagen, daß die MCU selbst zu schnell für den UART ist. Auch ohne DMAC mußt Du sicherstellen, daß das Transmit-Register frei ist (DREIF)
Du wendest es nur so an...
Der DMAC bietet Dir quasi neben dem eigentlichen Datenbus einen zweiten Bus (Netz ? vier Kanäle), der entsprechend eingestellt unabhängig von Deinem Programm im Hintergrund Daten zwischen SRAM und/oder I/O-Registern hin und herschieben kann. Ähnlich dem Event-Netz muß die MCU also nicht mehr Bytes in ein Register laden und dann irgendwohin schreiben, sondern der DMAC macht das … neben der MCU... selbständig.

BTT: Kann man den DMAC (ggf mithilfe des Event-Systems) durch DREIF triggern lassen, um so zB autonom irgendeinen Puffer ausgeben zu lassen OHNE weitere MCU-Intervention / OHNE IRQs etc ?
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.321
10
38
Hannover
Sprachen
ANSI C, C#
BTT: Kann man den DMAC (ggf mithilfe des Event-Systems) durch DREIF triggern lassen, um so zB autonom irgendeinen Puffer ausgeben zu lassen OHNE weitere MCU-Intervention / OHNE IRQs etc ?
Genau das war mein Vorhaben. Das klappt. "Leider" ist nur die höhere Geschwindigkeit das Problem. Dem DMA ist es schnuppe ob der USART jetzt das Byte raus geschoben hat oder nicht. Der ballert einfach drauf los, möge kommen was will^^
Man kann es aber evtl. anders herum besser nutzen.. Sprich um Daten zu empfangen und diese dann in einen Ringspeicher zu schieben. Das müsste eigentlich gut klappen.
 

Mikro23

Aktives Mitglied
2 Jan 2017
366
33
28
Großraum Hannover
Sprachen
ANSI C, Assembler
Kann man den DMAC (ggf mithilfe des Event-Systems) durch DREIF triggern lassen, um so zB autonom irgendeinen Puffer ausgeben zu lassen OHNE weitere MCU-Intervention / OHNE IRQs etc ?
Im Prinzip ja, aber … (siehe unten)
Das klappt. "Leider" ist nur die höhere Geschwindigkeit das Problem. Dem DMA ist es schnuppe ob der USART jetzt das Byte raus geschoben hat oder nicht. Der ballert einfach drauf los, möge kommen was will^^
Nein, Du mußt den DMA-Controller natürlich so konfigurieren, daß er nur ein Byte auf einmal überträgt und die nächste Übertragung mit dem Event neu starten.

Bei langsamen Übertragungsraten finde ich das nur nicht sonderlich sinnvoll, zumal die CPU-Belastung auch nicht hoch ist, wenn man z.B. bei 9,6 kBaud so ca. alle Millisekunde mal ein Byte in den UART stopft.

OT continued
Also nicht mindestens Faktor "mehrere Tausend", sondern "nur" mindestens Faktor "knapp hundert"...
Wo habe ich mindestens geschrieben?
Je nachdem, wie schnell der CPU-Takt und der UART-Takt eingestellt sind, ist der DMA so grob über den Daumen geschätzt zwischen einigen tausend- und einigen hunderttausendmal schneller.
Es war nur meine Absicht, darzustellen wie viel schneller der DMA sein kann.

Natürlich kann er auch (wiedermal grob geschätzt ;)) „nur“ zehnmal schneller sein.

Aber wenn ich davon ausgehe, daß der DMA, bei höchster Taktfrequenz z.B. 16 Megabyte pro Sekunde überträgt, und am UART ein Akustikkoppler mit 300 Baud angeschlossen ist, der nur ca. 30 Bytes pro Sekunde abnimmt, dann ist der DMA ungefähr 500.000 (in Worten: fünf-hundert-tausend) mal schneller...
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.344
61
48
Marwitz
Sprachen
BascomAVR, Assembler
Wo habe ich mindestens geschrieben?
Nicht konkret "mindestens", sondern "zwischen" zwei Grenzwerten (was einem "von" = mindestens bis "bis" = höchstens gleichkommt):
zwischen einigen tausend- und einigen hunderttausendmal schneller.
Selbst wenn der DMAC nur einen Takt zum Transfer eines Bytes braucht, kannst Du den UART so einstellen, daß ein Byte nur 80 Takte für den Transfer eines Bytes benötigt.
Damit wäre der DMA nur noch 80 (in Worten: achtzig) mal schneller. Natürlich kannst Du den UART auch soweit runterdrehen, daß die Bytes nur noch rauströpfeln...
Du kannst aber auch zwei 20-MHz-AVR über den UART verbinden - mit 2,5 MBaud...

Um auf den Punkt zurückzukommen: Wir haben beide übereinstimmend geantwortet, daß der Transfer eines Bytes über einen parallelen Bus (Datenbus, DMA) schon allein aufgrund der Parallelität schneller ist (ich in #2, Du in#4). Beim UART(ohne S) (als speziellem seriellem Bus (Bus?)) kommt das Oversampling hinzu - im DoubleSpeed 8fach-Oversampling. Außerdem Je ein Start und ein Stop-Bit.

BTT: Im "XMEGA AU [MANUAL]" auf Seite 64 Table 5-13 "DMA trigger source offset values for USART triggers. TRGSRC offset value Group configuration Description" finden sich zwei Trigger: einmal der Recieve Complete, und einmal der Data Register empty.;)
Natürlich darf dann auch der DMAC nur immer ein Byte reinstopfen ->
daß er nur ein Byte auf einmal überträgt
Sinn kann(!) das ganze zum Beispiel machen, wenn das laufende Programm auf keinen Fall durch den UART unterbrochen werden soll, und währenddessen mehrere Bytes gesendet werden sollen.
 
Zuletzt bearbeitet:

Janiiix3

Aktives Mitglied
28 Sep 2013
1.321
10
38
Hannover
Sprachen
ANSI C, C#
Wenn ich dem DMA sage das er immer nur ein Byte senden soll, wenn der UART wieder bereit ist, müsste ich doch das Flag vom UART pollen oder? Habe beim DMA nicht gesehen das es irgendwie anders geht..
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.321
10
38
Hannover
Sprachen
ANSI C, C#
Das wäre im Endeffekt bestimmt mehr CPU Last als ohne DMA.
 
  • Like
Wertungen: LotadaC

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.344
61
48
Marwitz
Sprachen
BascomAVR, Assembler
Mal ein paar Grundlagen (wird sicher vieles klar sein, aber trotzdem):

Die AVR besitzen entsprechend ihrer Harvard-Architektur getrennte Speicher für Code und "Anwendung":
Der Program Flash nimmt das Programm (Code) auf, wobei die dort stehenden Words auch Byteweise als Daten gelesen oder geschrieben (eingeschränkt) werden können.
Im SRAM werden zur Laufzeit alle möglichen Daten (Variablen) abgelegt, außerdem befindet sich dort der Stack (für Rücksprungadressen aus Subroutine Calls und IRQs).
Dann gibts ggf noch den Eeprom.
Der Zugriff auf die gesamte Peripherie läuft über I/O-Register ab.
Allerdings erlauben nur die ersten 32 Adressen direkten bitweisen Zugriff (und selbst da nicht immer alle).
Der "Rechenkern" selbst (die ALU) ist selbst nur an 32 Rechenregister (und das Statusregister) angebunden.
Wenn also ein Statusbit gepollt werden soll, muß erstmal das entsprechende I/O-Register in ein Rechenregister geladen werden (IN/LDS/LD), dort dann eine Maskierung der restlichen Bits erfolgen (ANDI), was das SREG manipuliert; entsprechend dieser Manipulation kann dann verzweigt werden (BRxx).
Wenn ein Byte aus dem SRAM (mit konstanter Adresse) in ein I/O-Register (zB das Uart-Transmit-Register) geschrieben werden soll, muß dieses Byte erstmal aus dem SRAM in ein Rechenregister geladen werden (IN/LDS), und anschließend von dort in das I/O-Register kopiert werden (OUT/STS).
Ist die SRAM-Adresse nicht konstant (oder schlichtweg außerhalb des durch LDS adressierbaren Bereiches), muß diese Adresse erstmal in ein Pointer-Register (zwei Bytes) geladen werden, und dann indirekt von dieser Adresse das Byte geladen werden (mit LD statt LDS). Reicht auch der 16bit-Adressraum nicht, muß ein drittes Ramp-Register miteinbezogen werden.
Ähnliches gilt auch beim Schreiben in die Peripherie mit STS->ST.
Quasi identisch läuft das Kopieren von Bytes innerhalb des SRAM ab.
Erfolgt das ganze innerhalb eines Interruptes, muß sichergestellt werden, daß die 32 Rechen- und das Statusregister so hinterlassen werden, wie man sie vorgefunden hat. Also zu Beginn die verwendeten Rechenregister und das SREG auf den Stack gesichert, am Ende von dort wiederhergestellt.

Um die ALU zu entlasten arbeiten die periphären ... Module mehr oder weniger autonom. Ein Timer tackert entsprechend eingestellt seine Zählwerte durch und erzeugt ggf nebenbei 'ne PWM. Der UART pumpt ein Byte raus und/oder empfängt eins. Der ADC digitalisiert 'ne analoge Spannung usw usf.
Diese periphären Module hinterlassen Ihre Ergebnisse in ihren I/O-Registern (wo die ALU sie pollen/laden) kann, außerdem können Interrupts (des eigentlichen Programmes) angefordert werden.

Was ist jetzt das Event-Netzwerk?
Über dieses Netz kannst Du einige Peripheriemodule miteinander verbinden - triggertechnisch. Ein Timerüberlauf kann dann zB eine ADC-Conversion starten o.ä. (wobei es sowas auch schon bei älteren AVR ohne Event-Netz gab).
Ohne ALU-Intervention.
Das Event-Netz kann aber nur (bestimmte) einzelne Signale verbinden.

Und der DMAC?
Der kann Bytes kopieren - vom I/O-Space/SRAM in den I/O-Space/SRAM. Ggf getriggert, mit inkrementierenden Adressen, blockweise,...
Ohne weitere ALU-Intervention, ohne Umweg über die Rechenregister.

Die CCL?
Jeder Kanal besteht quasi aus einem konfigurierbaren Logikgatter mit mehreren Eingängen und einem Ausgang. Damit lassen sich komplexere Regeln im Event-Netz realisieren, der DMAC läßt sich auch durch das Event-Netz triggern.

@Mikro23 : Soweit korrekt zusammengefaßt?
 
Zuletzt bearbeitet:

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)