Hallo!
Ich habe ein kleines Verständnisproblem bei Verwendung der DMA eines
MSP430.
Mein Ziel ist es die am UART einkommenden Daten mit der DMA
"wegzuschaufeln", dass mein Prozessor die Daten parallel dazu abarbeiten
kann. Das Triggern der DMA auf das RX-Flag ist ja kein Problem. Mein
Problem ist, dass ich nicht weiß wieviel Bytes über den UART reinkommen.
Es können mal nur 3 sein, mal 256, ...
Momentan fehlt mir das Implementierungskonzept. Es geht los, welche
DMA-Mode der richtige ist. Bin der Meinung "Repeated single transfer".
Da ich nicht weiß, wieviel Bytes kommen, müsste ich die Size auf "1"
setzen...
Aber woher weiß ich dann, wieviel Bytes über den UART empfangen und von
der DMA in den Puffer im RAM transferiert wurden?
Vielen Dank schon mal, für die aufklärenden Antworten.
Viele Grüße
MSP-Neuling
Ich kenne jetzt den DMA-Controller der MSP430 nicht, weil ich ihn noch
nie benötigt habe, aber sollte der nicht über ein bei jeder Aktivität
inkrementiertes Adressregister verfügen? Das solltest Du auslesen
können, um herauszufinden, wo das letzte Byte hingeschrieben wurde.
Hast Du auf Deinem MSP so viel zu tun, daß eine normale
Interrupt-Routine, die den RX-Interrupt auswertet und das empfangene
Byte in einen Puffer packt, nicht ausreicht?
Rufus Τ. Firefly schrieb:> Ich kenne jetzt den DMA-Controller der MSP430 nicht, weil ich ihn noch> nie benötigt habe, aber sollte der nicht über ein bei jeder Aktivität> inkrementiertes Adressregister verfügen? Das solltest Du auslesen> können, um herauszufinden, wo das letzte Byte hingeschrieben wurde.
Ja, hat er. D.h. ich muss mir die Anzahl an Bytes anhand der Start- und
Stoppadresse ausrechnen?
Aber das zusammenspiel zwischen diesen Destination Addresse und
Sizeregister habe ich auch noch nicht verstanden.
Wenn ich im Sizeregister die Größe meines Puffers angeben muss, dann
frage ich mich, was passiert, wenn mein Schreibzeiger der DMA z.B. auf
dem 250ten Element steht und nun kommt ein Datenstrom mit 40 Bytes
rein!?
Dann würde ich ja 34 Bytes verlieren bzw. wenn der Zeiger wieder auf die
Startadresse umgebogen wird, würde ja meine Berechnung nicht stimmen....
Rufus Τ. Firefly schrieb:> Ich kenne jetzt den DMA-Controller der MSP430 nicht, weil ich ihn noch> nie benötigt habe, aber sollte der nicht über ein bei jeder Aktivität> inkrementiertes Adressregister verfügen? Das solltest Du auslesen> können, um herauszufinden, wo das letzte Byte hingeschrieben wurde.>> Hast Du auf Deinem MSP so viel zu tun, daß eine normale> Interrupt-Routine, die den RX-Interrupt auswertet und das empfangene> Byte in einen Puffer packt, nicht ausreicht?
Leider ja. Die Daten kommen mit 1MBaud rein... und der MSP ist nur mit
8MHz getakt. Wird also, was die UART-Kommunikation betrifft im
Grenzbereich betrieben. Zum Übertragen von einem Byte (also 11 Bit mit
Start und Stopp & Parity) werden nur 11µs benötigt. Erschwert wird das
ganze dadurch, dass Timer laufen, deren Interrupt absolute Priorität
hat...
Wenn Du vorher nicht weißt, wie viele Bytes Du über die UART bekommst
bringt Dir der DMA nichts.
Sinnvoll könnte man ihn einsetzen, wenn bei Deinem Protokoll z.B. das
erste Byte festlegen würde, wie viele noch folgen. Dann könntest Du nach
dem ersten Byte einen DMA aufsetzen, der Dich benachrichtigt, wenn alle
Bytes empfangen wurden.
Dafür müsste man aber das Protokoll der Daten kennen.
MSP-Neuling schrieb:> Wenn ich im Sizeregister die Größe meines Puffers angeben muss, dann> frage ich mich, was passiert, wenn mein Schreibzeiger der DMA z.B. auf> dem 250ten Element steht und nun kommt ein Datenstrom mit 40 Bytes> rein!?
Woher weißt Du denn, wann der Datenstrom beendet ist?
Gib doch mal etwas mehr Infos bezüglich Deines Protokolls, sonst wird
das nichts...
Ampfing schrieb:> Sinnvoll könnte man ihn einsetzen, wenn bei Deinem Protokoll z.B. das> erste Byte festlegen würde, wie viele noch folgen. Dann könntest Du nach> dem ersten Byte einen DMA aufsetzen, der Dich benachrichtigt, wenn alle> Bytes empfangen wurden.
Von diesem Problem komme ich ja her. Das Auswerten des empfangen Bytes
(Aufruf einer Statemachine) und paramterieren der DMA dauert zu lange
(länger als 11µs), dann gehen mir wieder Bytes im RX Puffer verloren ...
Ampfing schrieb:> Woher weißt Du denn, wann der Datenstrom beendet ist?> Gib doch mal etwas mehr Infos bezüglich Deines Protokolls, sonst wird> das nichts...
Das sind Zeitschlitze in denen die Teilnehmer senden dürfen, wie und was
sie wollen.
MSP-Neuling schrieb:> Von diesem Problem komme ich ja her. Das Auswerten des empfangen Bytes> (Aufruf einer Statemachine) und paramterieren der DMA dauert zu lange> (länger als 11µs), dann gehen mir wieder Bytes im RX Puffer verloren ...
Und wie bitte willst Du die Daten - wenn sie z.B. per DMA übertragen
wurden - auswerten, wenn Du nichtmal Zeit hast ein Byte auszuwerten und
nen DMA aufzusetzen?
MSP-Neuling schrieb:> Das sind Zeitschlitze in denen die Teilnehmer senden dürfen, wie und was> sie wollen.
Dann könnte es z.B. so gehen: Zu Beginn des Zeitschlitzes setzt Du den
DMA mit der maximal zulässigen Bytezahl auf (mit Destination-Address ==
Anfang des Puffers). Am Ende des Zeitschlitzes rechnest Du Dir aus, wie
viele Bytes zu bekommen hast und verarbeitest diese.
Allerdings brauchst Du dann für jeden Teilnehmer einen extra Puffer mit
der maximal zulässigen Datengröße, da Du ja bei Beginn nicht weißt, wie
viele Daten Du bekommst.
MSP-Neuling schrieb:> Wenn ich im Sizeregister die Größe meines Puffers angeben muss, dann> frage ich mich, was passiert, wenn mein Schreibzeiger der DMA z.B. auf> dem 250ten Element steht und nun kommt ein Datenstrom mit 40 Bytes> rein!?
Genau das darf nicht passieren - deswegen pro Teilnehmer ein extra
Puffer!
Ampfing schrieb:> Und wie bitte willst Du die Daten - wenn sie z.B. per DMA übertragen> wurden - auswerten, wenn Du nichtmal Zeit hast ein Byte auszuwerten und> nen DMA aufzusetzen?
Wie meinst du das? Wenn die DMA die Daten vom RX-Puffer entgegennimmt,
kann doch die CPU in der Zwischenzeit diese Daten und die
Timerinterrupts abarbeiten ...
Ampfing schrieb:> Dann könnte es z.B. so gehen: Zu Beginn des Zeitschlitzes setzt Du den> DMA mit der maximal zulässigen Bytezahl auf (mit Destination-Address ==> Anfang des Puffers). Am Ende des Zeitschlitzes rechnest Du Dir aus, wie> viele Bytes zu bekommen hast und verarbeitest diese.
Also soll ich die DMA über die Zeitschlitze managen?
Ampfing schrieb:> Genau das darf nicht passieren - deswegen pro Teilnehmer ein extra> Puffer!
Ähm. 24 * 256 Bytes, dass wären 6 kByte RAM nur für die Puffer! Hab nur
4 KB in Summe!
MSP-Neuling schrieb:> Wenn die DMA die Daten vom RX-Puffer entgegennimmt,> kann doch die CPU in der Zwischenzeit diese Daten
Und woher weiß die CPU, ob die Daten gültig sind?
MSP-Neuling schrieb:> Also soll ich die DMA über die Zeitschlitze managen?
Wäre eine Möglichkeit.
Andere Möglichkeit: Du setzt den DMA immer mit Deiner Puffergröße auf.
Wenn der DMA-Interrupt kommt setzt Du ihn neu auf und lässt ihn wieder
den Puffer füllen. Dann musst Du aber sicherstellen, dass Du die Daten
verarbeiten kannst, bevor diese überschrieben werden! Und dann bist Du
wieder bei meiner oben gestellten Frage (nach der Gültigkeit der
Daten)...
Wie lang dauert Deine Datenverarbeitung?
MSP-Neuling schrieb:> Ähm. 24 * 256 Bytes, dass wären 6 kByte RAM nur für die Puffer! Hab nur> 4 KB in Summe!
Dann nimm z.B. zwei Puffer, die Du abwechselnd schreibst. Musst Dir dann
eben merken, welcher Teilnehmer welchen Puffer gefüllt hat.
MSP-Neuling schrieb:> Und wo soll man deiner Meinung nach ansetzen und was wie optimieren?
Z.B. erstmal darstellen, was Dein bisheriges Design ist und wo es an
Probleme stößt.
MSP-Neuling schrieb:> Wenn die DMA die Daten vom RX-Puffer entgegennimmt,> kann doch die CPU in der Zwischenzeit diese Daten und die> Timerinterrupts abarbeiten ...
Ich glaube du stellst dir den DMA da falsch vor. Während einer DMA
Transaktion ist die CPU deaktiviert, weil immer nur einer auf den RAM
zugreifen kann. Bei Single Transfers geht DMA schneller als Interrupt,
das ist richtig, aber da musst du vorher genau wissen, wieviele Daten
kommen, sonst müsstest du dir auch wieder nach jeden DMA Single Transfer
einen Interrupt geben lassen.
Im Block Transfer Modus ist die CPU komplett angehalten, bis alle Daten
übertragen sind. Im Burst Block Modus werden immer 4 Byte/Worte
übertragen und dann kann die CPU 2 MCLK Zyklen machen usw.
Es kann nicht gleichzeitig ein DMA Transfer stattfinden und die CPU
normal arbeiten. Ich glaube, das ist dein Denkfehler hierbei.
Ich glaube das ist einfach generell ein Problem, weil es auch für mich
immer so dargestellt wurde als könnte die CPU nebenbei andere Dinge tun.
Von einigen Leute hört man sogar Dinge wie "die DMA nutzt die freien
Zyklen der CPU zu Übertragung". Ab wann ist es eigentlich sinnvoll die
DMA zu verwenden bzw. bringt es Vorteil, wenn man durch Interrupts immer
wieder ein mal die selbe Adresse auszuließt und in einen festen Bereich
schreibt anstatt sie direkt zu kopieren? (Selbe Adresse mit
unterschiedlichem Inhalte natürlich^^)
AMD DMA schrieb:> die DMA nutzt die freien> Zyklen der CPU zu Übertragung
Aber wann hat eine CPU denn bitte "freie Zyklen" ? Irgendwas macht sie
doch immer - und wenn sie sich in einer Schleife einfach nur im Kreis
dreht.
Dennis schrieb:> Aber wann hat eine CPU denn bitte "freie Zyklen" ? Irgendwas macht sie> doch immer - und wenn sie sich in einer Schleife einfach nur im Kreis> dreht.
Das DMA nimmt sich diese Zyklen, egal ob die CPU grad auch will. Ein
anderer Begriff für diese Methode nennt sich "cycle stealing".
Vielleicht wirds dann klarer.
Hat auch zur Folge, dass taktgenaues Timing von Portzugriffen und
aktives DMA nicht gut harmonieren.
Vielleicht hat ja mal einer Lust den Artikel dahingehen klarer zu
gestalten. Ich denke hier greift wieder das Problem dass die Ersteller
einfach zu viel Ahnung haben und Dinge als logisch voraussetzen die dann
hier immer wieder die gleichen Fragestellungen aufwerfen.