www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ist ein Ringpuffer bei UART wichtig?


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich verwende die UART Library von Peter Fleury, die arbeitet ja 
bekanntlich mit Ringpuffer für senden und empfangen. Ist vor allem der 
Sendepuffer unbedingt erforderlich? Ich möchte meine serielle 
Übertragungsgeschwindigkeit maximieren und der Ringpuffer bremst etwas

Autor: Uart (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommt darauf an, was dir wichtig ist.

Wenn dein µC außer senden, senden, senden nichts anderes zu tun hat, 
nimm keinen Buffer für max. Performance.

Wenn dein µC aber andere Aufgaben hat, und das Senden sozusagen 
nebenbei, im Hintergrund, mit minimaler CPU-Last laufen soll, nimm einen 
Buffer.

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan schrieb:
> Ist vor allem der
> Sendepuffer unbedingt erforderlich? Ich möchte meine serielle
> Übertragungsgeschwindigkeit maximieren und der Ringpuffer bremst etwas

Hallo,
warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären?

Autor: Entwickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Übertragungsgeschwindigkeit maximieren

Deine Baudrate soll also > 1MBd sein?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uart schrieb:
> Kommt darauf an, was dir wichtig ist.
>
> Wenn dein µC außer senden, senden, senden nichts anderes zu tun hat,
> nimm keinen Buffer für max. Performance.
>
> Wenn dein µC aber andere Aufgaben hat, und das Senden sozusagen
> nebenbei, im Hintergrund, mit minimaler CPU-Last laufen soll, nimm einen
> Buffer.

interessante Erklärung, danke
wenn ich dem Controller sag er soll senden, dann macht der in der Tat 
sonst nichts mehr außer die Daten so schnell wie möglich raus zu 
schippern

U.R. Schmitt schrieb:
> warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären?

der Controller muss den "Füllstand" der Puffer aktuell halten und das 
kostet etwas Zeit

Entwickler schrieb:
> Deine Baudrate soll also > 1MBd sein?

Ich hab nen recht langsamen Quarz zwecks Stomverbrauch aber ich möcht 
mich so stark wie möglich an die maximal mögliche Geschwindigkeit 
annähern

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(Baudrate 460800)

Autor: Entwickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich hab nen recht langsamen Quarz zwecks Stomverbrauch

Und wie hoch ist Deine Datenrate? 10kB/s?

Nimm einen schnelleren Quarz und lege den Prozessor in Arbeitspausen 
schlafen; Mittagsschlaf ist auch immer gut :-)

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Moment ist sie bei knapp 5 kByte/s

aber ich hab noch eine Bremse drin die ich (noch) nicht beheben kann.
dann werd ich vermutlich 10+ kByte/s haben

aber dann begrenzt mir der Ringpuffer schön langsam. Der Puffer halbiert 
in etwa meine max. Sendegeschwindigkeit

es sollten 20kByte/s möglich sein denk ich

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan schrieb:
> U.R. Schmitt schrieb:
>> warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären?
>
> der Controller muss den "Füllstand" der Puffer aktuell halten und das
> kostet etwas Zeit

Bitte was???
Das einzige was bei einem Ringpuffer passiert ist, daß wenn ein Byte 
gesendet wurde per Interrupt eine kleine Funktion angesprungen wird, die 
nachschaut ob noch ein Byte da ist, das gesendet werden soll und danach 
den Lesezeiger im Ringpuffer verschiebt, bzw. wenn der schon am Ende des 
Puffers ist ihn wieder an den Anfang stellt. Das sollte selbst mit 
nichtoptimiertem C nicht viel mehr als 30 Assemblerbefehle dauern, mit 
Assembler sollte man es unter 20 hinkriegen.

Beim Empfang ist es noch einfacher. Sobald ein Byte empfangen wurde, 
wird es (wieder via Interruptfunktion) an die Stelle des Schreibzeigers 
gesetzt und der eins erhöht, bzw. wieder an den Anfang gesetzt.
Was jetzt noch fehlt ist die Overflow Prüfung, das ist ein einfacher 
Vergleich der beiden Zeiger auf Gleichheit.

Damit kommst Du auf jeden Fall mit Lesen oder Schreiben auf einen 
Durchsatz über 100000 Byte pro Sekunde plus zusätzliche Zeit für ein 
Hauptprogramm.
(bei angenommen 8 Millionen Assemblerbefehle pro Sekunde)

Autor: Entwickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Betrieb ohne Puffer ist dann sinnvoll, wenn die Daten kontinuierlich 
ermittelt und ausgegeben werden sollen. Du erhälst alle 50µs einen neuen 
Wert und gibst ihn direkt aus. Dann klappt das mit 20kB/s.

Werden aber in 50µs 10 Werte erzeugt, ausgegeben und dann neue 
ermittelt, bremst die Warterei auf die UART Deinen Programmfluß.

Man kann einen Puffer geschickt programmieren, dass er 20-30 Zyklen 
braucht. Bei 3,6864MHz würde der Interrupt unter 10µs ablaufen. Das ist 
allemal geschickter, als 25µs auf einen freien Sendepuffer zu warten.
Um die Interrupts zu reduzieren, kann man das komplette Ende von Tx 
abwarten und dann gleich zwei Bytes auf einmal schreiben.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan schrieb:
> Ich hab nen recht langsamen Quarz zwecks Stomverbrauch aber ich möcht
> mich so stark wie möglich an die maximal mögliche Geschwindigkeit
> annähern

Im Worst-Case hast Du 80 Zyklen pro Byte frei, da kann bequem ein 
Interrutphandler den FIFO auslesen und die Bytes Startbit an Stopbit 
rausrotzen.

Ich kenne die Fleury-Lib nicht, aber in der Codesammlung findest Du 
meine FIFO, die ist ziemlich optimiert.

Wenns Dich dann immer noch ausbremst, dann hast Du zu viele andere 
Interrupts, die die CPU stressen, vielleicht ne SW-PWM.
Dann geh eben mit dem Quarz hoch, der MAX232 zieht ja schon mehr, als 
der AVR.


Peter

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
U.R. Schmitt schrieb:
> Stefan schrieb:
>> U.R. Schmitt schrieb:
>>> warum bremst der? Das verstehe ich jetzt nicht, kannst Du das erklären?
>>
>> der Controller muss den "Füllstand" der Puffer aktuell halten und das
>> kostet etwas Zeit
>
> Bitte was???
> Das einzige was bei einem Ringpuffer passiert ist, daß wenn ein Byte
> gesendet wurde per Interrupt eine kleine Funktion angesprungen wird, die
> nachschaut ob noch ein Byte da ist,

Da Atmel auch mitgedacht hat, ist in der UART ein kleiner Buffer 
eingebaut (1 Zeichen). Den Interrupt bekommt man bereits, wenn man 
wieder ein Zeichen in den Buffer nachstopfen kann, d.h. noch während ein 
anderes Zeichen gerade über die Drähte rausgeklopft wird, lädt die ISR 
die UART schon wieder mit dem nächsten Zeichen nach.

-> das Senden geht auch mit Ringbuffer nahtlos und ohne Zeitverzug 
solange man die Interrupts nicht mutwillig extrem lange abgeschaltet 
lässt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.