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
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.
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?
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
>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 :-)
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
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)
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.
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
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.