mikrocontroller.net

Forum: PC-Programmierung Datenverlust bei ReadFile()


Autor: Sam (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sam (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sam (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Reinhard Kern (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sam (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.