Serielle Schnittstelle mit Overlapped I/O auslesen
-
Hallo !
Ich habe mal wieder ein Verständnis-Problem, vielleicht kann mir ja jemand auf die Sprünge helfen.
Ich habe eine serielle Schnittstelle mit Overlapped-Flag geöffnet.
Jetzt möchte ich nacheinander mit 2 Funktionen zugreifen.1. Funktion sendet und empfängt Daten in ASCII
--> etwa so (sinngemäß)func_1 { bool WeiterWarten; char c; OVERLAPPED OV; memset (&ov, 0, sizeof(ov)); ov.hEvent = CreateEvent (NULL, false, false, NULL); WriteFile (hPort, Data, strlen(Data), &nBytes, &ov) WeiterWarten = true; do { bRet = WaitCommEvent (hPort, &dwEventMask, &ov); dwWait = WaitForSingleObject(ov.hEvent,INFINITE); if (dwWait == WAIT_OBJECT_0) { if (dwEventMask & EV_RXCHAR) { do { if (ReadFile (hPort, &c, 1, &nBytes, &ov)) { if (c == 0x0D) { WeiterWarten = false; break; } } } while ((nBytes > 0) && WeiterWarten); } } } while (WeiterWarten); CloseHandle (OV.hEvent); }Funktion 2 soll nur Daten binär lesen
func_2 { bool WeiterWarten; char c; OVERLAPPED OV; memset (&ov, 0, sizeof(ov)); ov.hEvent = CreateEvent (NULL, false, false, NULL); // Zuerst die Daten auslesen, die in func_1 noch nicht // gelesen wurden, aber schon im Buffer waren... if (ReadFile (hPort, Data, 100, &nBytes, &ov)) { if (nBytes > 0) { ... } } // Jetzt auf weitere Daten warten WeiterWarten = true; do { bRet = WaitCommEvent (hPort, &dwEventMask, &ov); dwWait = WaitForSingleObject(ov.hEvent,INFINITE); if (dwWait == WAIT_OBJECT_0) { if (dwEventMask & EV_RXCHAR) { do { if (ReadFile (hPort, &Data, 1, &nBytes, &ov)) { } } while ((nBytes > 0) && WeiterWarten); } } } while (WeiterWarten); CloseHandle (OV.hEvent); }So. Es ist möglich, dass im Empfangspuffer noch Daten sind, wenn Funktion 1 verlassen wird. Ich erwarte nicht, deshalb nochmals ein Event zu bekommen und möchte deshalb die im Puffer vorhandenen Daten erstmal ohne Event in Func_2 auslesen.
Das geht so aber nicht, nBytes ist dort immer 0. Das bestätigt mir auch Sysinternals Portmon. Nach dem CR sind aber mit Sicherheit noch Daten bei der seriellen Schnittstelle angekommen (Analyzer!).
Also ich kann mit denken, dass man das Ganze so nicht machen darf. Aber was darf ich? Muss ich die Daten komplett auslesen nach einem Event bis ReadFile nBytes=0 liefert? Werden nicht gelesene Daten mit dem CloseHandle(OV.hEvent) verworfen?
Das würde doch aber bedeuten, dass ich selber noch mal eine Pufferverwaltung durchführen muss, aus denen sich dann 2 Funktionen bedienen können. Kann ich die Verwaltung des Empgangspuffers nicht Windows überlassen? Ich will ja nix machen, was Windows viel besser kann...
Danke für jede Antwort
TomK
-
Ich Rate immer dazu es nicht selber zu machen, oder sich zumindest laufende Beispiele anzuschauen:
http://www.codeproject.com/system/serial.asp
-
Es ist möglich, dass im Empfangspuffer noch Daten sind, wenn Funktion 1 verlassen wird
Nein.
Sauber ist das erst, wenn nur ein einziger Thread liest. Dann wird immer mit dem aktuellen Zustand der ser. Schnittstelle gearbeitet und entsprechend darauf reagiert.
Von da kann man die Daten zu beliebig anderen Threads via PostThreadMessage o.ä. senden.Schreiben kann man von vielen anderen Funktion aus.
Wenn auch das geordnet ablaufen soll, so legt man das Schreiben auch in einen extra Thread und pollt nach dem Ende der Übertragung, damit man weiß, wenn man neue Daten senden kann. Oder richtet eine Queue ein.... 1. Funktion sendet und empfängt Daten in ASCII ...
Dann wird die Funktion und das Fenster aber blockiert sein, wenn keine Daten kommen. Das Empfangen geht in einem Thread besser.
Blackbird
-
Hallo Blackbird, dann geht meine Vermutung schon in die richtige Richtung. Ich habe zwar noch nicht ganz kapiert, wieso das Ganze so ist, aber im Prinzip ist das auch ok. Danke für die Hinweise.
Und Danke für den Link, Jochen!
Gruß
TomK