Bei meiner seriellen Übertragung ist die Portzugriffgeschwindigkeit
entscheidend für die Gesamtdauer, und die gilt es zu minimieren.
Momentan nutze ich eine an Qt angepasste Bibliothek, die aber offenbar
nicht vollständig implementiert ist, d.h. ich muss teilweise pollen und
warten.
Eine ältere Implementierung mit ReadFile() und SetCommTimeouts() ist
etwas schneller, aber immer noch nicht so schnell wie die Übertragung
von einem Mikrocontroller aus (ist ja klar, der schickt nach wenigen µs
eine Antwort und muss nicht auf BS und USB warten).
Die Frage ist also: kann man das irgendwie beschleunigen?
uffa schrieb:> Eine ältere Implementierung mit ReadFile() und SetCommTimeouts() ist> etwas schneller, aber immer noch nicht so schnell wie die Übertragung> von einem Mikrocontroller aus (ist ja klar, der schickt nach wenigen µs> eine Antwort und muss nicht auf BS und USB warten).>> Die Frage ist also: kann man das irgendwie beschleunigen?
das kann ich nicht galauben. Liest du jedes Byte einzeln mit Readbyte
oder mehre?
Ein PC schafft es bequem 1Mbaud zu lesen, das muss man schon sehr viel
falsch machen damit es langsamer wird.
Dein Problem ist das der USB Serial Converter versucht zu Puffern da ein
USB Packet mimum 64byte große ist. Wenn du einen FTDI verwendest schau
dir mal den DX2X Treiber an. Mit der kanst das Maximale aus einem FTDI
rausholen.
Genau "Peter II", das Problem ist, dass ständig Bytes einzeln
gelesen/geschrieben werden. Es wäre besser, die Daten zusammen per USB
zu übertragen und die RS-232 Verbindung dann per Mikrocontroller zu
erledigen.
Es werden u.A. Wandler von FTDI und Prolific genutzt, auf den
Schnittstellentyp habe ich keinen Einfluss.
Danke "xxx" für den Tipp mit dem Puffer, ich werde mal versuchen, an den
Einstellungen drehen
Hi,
man muss vor allem bei USB-seriell-Wandlern zwischen Durchsatz und
Latenz unterscheiden. Den Durchsatz mag man mit entsprechenden
Protokollen noch ganz gut hin bekommen, bei der Latenz sind USB-Lösungen
aber echten PCI-E-Seriell-Karten haushoch unterlegen.
Das Problem bei USB ist, dass es keine Hardware-Interrupts gibt und der
Host (PC) auch s.g. "interrupt transfers" immer selbst initiieren muss
(polling). Dadurch ergibt sich auf der einen Seite (je nach Treiber und
USB-Modus) eine vergleichsweise sehr hohe Round Trip Time von
Datenpaketen und auf der anderen Seite eine hohe Empfindlichkeit für
FIFO-Überläufe bei hohen Datenraten ohne Flusskontrolle.
PCI/PCI-E-Karten können dagegen Hardware-Interrupts auf der CPU beim
Empfang der Daten auslösen und stellen somit die empfangenen Daten der
Anwendung viel schneller zur Verfügung.
Irgendwie habe ich diesbezüglich Verbesserungen bei USB3 im Kopf, kann
mich aber gerade nicht genau entsinnen.
Was ich eigentlich damit sagen möchte: Es liegt nicht am Betriebssystem,
dass Deine Daten zu langsam ankommen, sondern viel eher an der
Implementierung und an der verwendeten Hardware. Ich habe hier mit
speziellen PCI-RS485/422-Karten problemlos ~10 MBit/s bei sehr geringen
Latenzen übertragen.
Gruß,
Oliver
uffa schrieb:> Genau "Peter II", das Problem ist, dass ständig Bytes einzeln> gelesen/geschrieben werden. Es wäre besser, die Daten zusammen per USB> zu übertragen und die RS-232 Verbindung dann per Mikrocontroller zu> erledigen.
wenn du sie per USB als BLock übertragen kannst warum dann nicht auch
per RS232?
Protokolle für die serielle Schnittstelle sollte man so aufbauen, daß
nicht einzelne Bytes im "ping-pong"-Verfahren übertragen werden, sondern
immer größere Datenblöcke gesendet bzw. empfangen werden. Dafür sind die
seriellen Schnittstellen üblicher PCs optimiert, das hat mit den Sende-
und EmpfangsFIFOs in der Standard-PC-UART 16550 angefangen, und ist bei
USB-Seriell-Adaptern noch ausgeprägter.
Idealerweise sollten Antworten asynchron ausgewertet werden, d.h. bei
einer blockorientierten Übertragung sollte nicht nach jedem Block auf
eine Quittung gewartet werden. Ein Beispiel dafür ist das
ZModem-Protokoll.
Natürlich ist diese letzte Eigenschaft nicht überall sinnvoll abbildbar,
aber man sollte so etwas bei der Gestaltung eines Protokolles im
Hinterkopf behalten.
http://www.ftdichip.com/Drivers/D2XX.htm
"D2XX drivers allow direct access to the USB device through a DLL.
Application software can access the USB device through a series of DLL
function calls."
In den Schnittstelleneinstellungen kann man Puffergrößen und
irgendwelche Wartezeiten reduzieren, das bringt was: in meinem Fall
25%-200%.
Ich hab mal eine Simulation geschrieben, in der Datenrate und Delays
gegeneinander abgewogen werden, und dann wurde klar dass der dDelay
schnell mal dominiert. Das bedeutet man sollte das Protokoll auf grosse
Bloecke optimieren.
Lass mal hoeren weshalb du einzelne Bytes uebertragen moechtest. Und wir
erzaehlen dann wie man das mit grossen Bloecken besser macht.
Danke auch für eure Beiträge - leider habe ich auch keinen Einfluss auf
das Protokoll. Denkbar wäre jedoch, die Daten als Block über USB zu
übertragen und dann einen Mikrocontroller einzusetzen, der durch die
Interruptfähigkeit entsprechend schnell reagieren kann.
uffa schrieb:> Danke auch für eure Beiträge - leider habe ich auch keinen Einfluss auf> das Protokoll.
kannst etwas mehr über das Protokoll sagen? Ist es wirklich so das du
jedes byte einzeln auf die Reise schicken musst und dann auf eine
Antwort wartest?
Michel schrieb:> Was packt man denn so in etwa an Bandbreite mit einem aktuellen Windows?
keine ahnung, denn ds limit ist die uart. 1Mbit ist kein Thema.
Sry aber ich hab mir das jetzt mal durchgelesen und irgendwie kapier ich
nicht um was es eigentlich geht.
>Eine ältere Implementierung mit ReadFile() und SetCommTimeouts() ist>etwas schneller, aber immer noch nicht so schnell wie die Übertragung>von einem Mikrocontroller aus
Ist da nicht immer ein uC im Spiel, oder überträgst Du von PC nach PC?
>von einem Mikrocontroller aus (ist ja klar, der schickt nach wenigen µs>eine Antwort und muss nicht auf BS und USB warten).
Und was meinst Du hiermit? Was bedeutet BS? Wer wartet hier auf USB? Der
PC mit Sicherheit nicht. Das erledigt der USB-Host.