Forum: PC-Programmierung Datenverlust bei ReadFile()


von Sam (Gast)


Lesenswert?

Hallo,

ich lese Daten von einem USB-HID-Gerät mit Hilfe von ReadFile() am PC 
ein. Das Ganze funktioniert OVERLAPPED mit einem eigenen Reader-Thread.

Solange ich die Applikation in Ruhe lesen lasse, funktioniert alles ohne 
Fehler. Wenn ich aber anfange das Hauptfenster der Applikation zu 
verschieben, oder auf andere Fenster klicke, gehen Daten-Pakete verloren 
(ca. 0,4%). Also nicht sehr viele, aber zu viele :).

Die Daten werden definitiv vom USB-Gerät versand. Das habe ich bereits 
überprüft. Der Reader-Thread gibt mir auch keine Fehlermeldung zurück 
und ich weiss im Moment nicht mehr wo ich suchen soll.

Vielleicht hat jemand etwas ähnliches schon gehabt bzw. hat einen 
Such-Ansatz für mich.

Ich arbeite auf PC-Seite mit der Visual C++ Express Edition und 
programmiere alles mit der WIN32 API.

In froher Erwartung schon mal vielen Dank für Eure Hilfe.

Gruß Sam

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Zwei Möglichkeiten die ich sehe: Puffergröße zu klein, und read Thread 
hat zu geringe Priorität oder deine auslesen geschieht zu ineffizient 
(einzelne bytes anstelle eines ganzen "Blocks").
Bei einem HID ist es denk ich wie bei einer Tastatur: Wenn die Daten 
nicht rechtzeitig abgeholt werden wird halt weggeworfen.

von Sam (Gast)


Lesenswert?

Erstmal Danke für Deine Hinweise.

Ich habe jetzt festgestellt, dass nur, wenn das Hauptfenster den Fokus 
verliert, Pakete durchfallen.

Das Lesen erfolgt immer Report-weise. Ist ein Report angekommen, prüfe 
ich ob das nächste ReadFile() mit TIMEOUT endet. Sollte das der Fall 
sein, dann schreibe ich das erste Datenpaket auf einen Heap, von wo aus 
es abgeholt werden kann. Hat das zweite ReadFile() etwas empfangen, dann 
warte ich bis a) irgendwann eines der folgenden  ReadFile() mit TIMEOUT 
endet oder b) MAX_PACKETS empfangen wurden, bevor ich auf den Heap 
schreibe.

Die Puffergröße und die Thread-Priorität habe ich bisher noch nicht 
untersucht - das werde ich jetzt mal machen.

Gruß Sam

von Sam (Gast)


Lesenswert?

Hat leider nichts gebracht.

Der mit SetupComm() eingestellte Empfangspuffer ist jetzt so groß, dass 
alle gesendeten Bytes auf einmal reingehen (sollten). Mit 
SetPriorityClass(HIGH_PRIORITY_CLASS) und
SetThreadPriority( THREAD_PRIORITY_TIME_CRITICAL) bin ich jetzt auch am 
Maximum. Und trotzdem gehen Daten verloren.

Das Ganze passiert nur, wenn ich 'wie wild' andere Fenster in den 
Vordergrund bringe. Das klingt mir nach einem Problem, wie bereits hier 
angesprochen (Echtzeitfähigkeit von Windows und/oder Grafikkarte!):

Beitrag "RS232 nicht Echtzeitfähig??"

Aber: Auch wenn die Grafikkarte dazwischen funkt müssten doch trotzdem 
alle Daten vorhanden sein, da der Zwischenspeicher der seriellen 
Schnittstelle (wie oben erwähnt) groß genug für alle Daten ist. Oder 
etwa nicht?

Die Frage bleibt: wo liegt der Fehler?

Gruß Sam

von Reinhard Kern (Gast)


Lesenswert?

Sam schrieb:
> Aber: Auch wenn die Grafikkarte dazwischen funkt müssten doch trotzdem
> alle Daten vorhanden sein, da der Zwischenspeicher der seriellen
> Schnittstelle (wie oben erwähnt) groß genug für alle Daten ist. Oder
> etwa nicht?

Windows ist ja weder echtzeitfähig noch unendlich schnell - die Daten 
können ja bereits beim Einlesen durch den Windows-Treiber verlorengehen, 
z.B. wenn er nicht oft genug aufgerufen bzw. bedient wird. Dann kann der 
Zwischenspeicher so gross sein wie er will, massgebend ist höchstens die 
Fifo-Länge der Schnittstelle selbst (sofern überhaupt ein Fifo drin 
ist).

Wenn das so ist, kommt man natürlich an das Problem nicht ohne weiteres 
heran, weil man dazu Windows-Treiber analysieren und ev. ändern müsste. 
Ein möglicher Ansatz wäre, Handshake einzuführen, falls das 
angeschlossene Gerät das ermöglicht. Tastaturen und Mäuse arbeiten 
arbeiten meines Wissens immer mit Handshake.

Gruss Reinhard

von Sam (Gast)


Lesenswert?

Hallo Reinhard,

die ganze Geschichte läuft ja letztendlich über USB und da gibt es 
natürlich ein Handshake. Erst wenn der Host die angeforderten Daten 
erhalten hat, sendet er ein ACK. Deshalb ist es für mich keine Frage, 
dass der Host die Daten erhält und dann auch irgendwo in einem Buffer 
ablegt.

Das zeigen ja auch meine Tests. Alles läuft reibungslos, solange ich 
nicht Windows mit irgend welchen anderen Aufgaben beschäftige.

Gruß Sam

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
Noch kein Account? Hier anmelden.