ATxmega - DMA

Dieses Thema im Forum "Software" wurde erstellt von Janiiix3, 31. August 2018.

  1. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.278
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    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..
     
  2. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.982
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    ???
    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;).
     
    #2 LotadaC, 31. August 2018
    Zuletzt bearbeitet: 31. August 2018
  3. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.278
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    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?
     
  4. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    264
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    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.
    Der UART hat ein Bit, das nennt sich DRE. Darüber kann man entweder einen Interrupt oder ein Event auslösen.
     
  5. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.278
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    C
    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..
     
    #5 Janiiix3, 31. August 2018
    Zuletzt bearbeitet: 31. August 2018
  6. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    264
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    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.ä.
     
  7. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.982
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    OT:
    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...
     
  8. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    264
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    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
    Ich bezog mich nur auf den DMA, der ist parallel. Also 16 bis 32 Megabyte pro Sekunde, im Vergleich zu UART.
    .
     
  9. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.278
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Okay.. Also war meine Vermutung richtig, dass der DMA einfach viel zu schnell ist für den UART..
     
  10. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.982
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    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"...
    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 ?
     
  11. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.278
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    C
    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.
     
  12. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    264
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Im Prinzip ja, aber … (siehe unten)
    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
    Wo habe ich mindestens geschrieben?
    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...
     
  13. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.982
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Nicht konkret "mindestens", sondern "zwischen" zwei Grenzwerten (was einem "von" = mindestens bis "bis" = höchstens gleichkommt):
    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 ->
    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.
     
    #13 LotadaC, 1. September 2018
    Zuletzt bearbeitet: 1. September 2018
  14. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.278
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    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..
     
  15. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.278
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Das wäre im Endeffekt bestimmt mehr CPU Last als ohne DMA.
     
    LotadaC gefällt das.
  16. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.982
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    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?
     
    #16 LotadaC, 2. September 2018
    Zuletzt bearbeitet: 2. September 2018
  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden