USB ist eine feine Sache, wenn da nicht die Sache mit der blockweisen Übertragung wäre. Ich habe eine alte Schaltung von RS232 mit einem FT232 auf USB umgerüstet. Allerdings habe ich jetzt das Problem, dass nur noch ziemlich 1kByte/s übertragen werden, obwohl die Baudrate bei 115,2kbaud liegt. Anscheinend wird pro USB Frame nur 1 Byte übertragen. Um das zu umgehen muss man immer ganze Datenblöcke auf einmal an den COM Port übergeben. Hier ist aber mein Problem: Die Daten werden zur Laufzeit des Programms erstellt, und es handelt sich dabei meist um Befehle. Manchmal wird minutenlang nichts gesendet, dann wieder mal mehrere 100kByte auf einmal. Daher meine Idee zwischen den Senderoutine und dem Programm einen Puffer einzubauen, der die Daten ansammelt bis z.b. 100Bytes im Puffer sind und diese dann auf einmal überträgt. Allerdings kann es dann passieren, das einige Daten minutenlang nicht gesendet werden, wenn die 100Bytes noch nicht voll sind. Daher wäre eine Zeitbeschränkung sinnvoll. Also wenn z.B. 100ms lang nichts gesendet wurde, wird der Puffer übertragen. Auf einem uC würde ich dazu einen Timer Interrupt verwenden, wie macht man sowas auf einem PC in C++ ?
Timer sind OS-Abhängig vondaher nichts direkt verwendbares: Das ganze läßt sich ähnlich wie mit Timer-Interrupt machen. Ein Zähler, der regelmässig hochgezählt wird und von der Sende-Routine wieder auf 0 gesetzt wird. Automatisches Senden bei einem bestimmten Zählerwert. Oder wenn du manuell sendest, killst du den aktuellen Timer und startest ihn neu. Unter welchen System soll das ganze denn laufen.
Ich möchte das ganze mit Visual C++ schreiben. Es gibt doch irgendeine Möglichkeit eine Funktion einzubauen, die in festen Zeitabständen augerufen wird, ähnlich einem Timer Interrupt auf einem uC ? Zumindest meine ich sowas mal irgendwo gesehen zu haben.
Wenn es eine GUI-Anwendung ist, dann kannst Du den Windows-Nachrichtentimer verwenden, der Deiner Fensterprozedur zyklisch eine Nachricht schickt. Wenn es keine GUI-Anwendung ist oder aber der serielle Code in einem Hintergrundthread läuft, dann kann der Sendethread mit WaitForSingleObject auf ein Eventhandle warten. Dieses Event wird bei jedem Eintragen eines Zeichens in den Sendepuffer gesetzt (geschieht mit SetEvent), der Sendethread "wacht auf", kann den Füllstand des Puffers überprüfen und gegebenenfalls absenden. Als Wartezeit für WaitForSingleObject wird Dein gewünschtes Timeout angegeben, WaitForSingleObject kehrt mit WAIT_TIMEOUT zurück, wenn das Event nicht signalisiert wurde. Wurde das Event signalisiert, ist der Rückgabewert WAIT_OBJECT_0.
Die Idee mit den Nachrichten war genau die richtige. Ich lasse mir jetzt alle 100ms eine Nachricht schicken. So spare ich mir die ganze Thread Geschichte und kann meinen aus einem C Programm übernommenen Code unverändert weiterverwenden.
Deinen Puffer gibt es schon im Treiber! es gibt eine einstellbare Wartezeit und eine Puffergroesse von 62 Byte. Ein Puffer wird rausgesendet wenn entweder die Wartezeit überschritten wird oder die Puffergroesse. Standardwartezeit ist 16ms. Wenn du nicht mit blöcken arbeitest sondern jedes Byte einzeln per Handshake abholst kanst du noch glücklich sein wenn 1Kbyte /s erreicht wird. siehe Applikation Note...
Wo kan man die Wartezeit für den Sendepuffer und dessen Größe einstellen ?
Einstellbar ist die Wartezeit im Gerätemanager unter Latency Time. (ftdi) SetupComm und SetCommTimeouts arbeiten eine Ebene höher.(serielle Schnittstelle) Die Ebene von der wir hier sprechen ist die Paketierung der Daten in ein USB Paket.
SetCommTimeouts bezieht sich doch auf die Zeit die für ein Sendevorgang benötigt werden darf, ehe die Übertragung abebrochen wird, oder ?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.