Autor |
Beitrag |
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 25.03.11 16:22
Hallo,
wir haben hier ein Problem mit dem Ansprechen des COM Ports. Es hatte alles schon funktioniert, aber als ich es jetzt testen wollte, klappte es nicht mehr wie früher. Wenn ich WaitForMultipleObjects benutze, wird das Event nicht ausgelöst.
Der Quelltext sieht so aus: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93:
| procedure ReceiveBytes(ComHandle: THandle; Overlapped: TOverlapped); var BufSize, BytesRead, Dummy: DWORD; ComStat: TComStat; begin if ClearCommError(ComHandle, Dummy, @ComStat) then begin BufSize := ComStat.cbInQue; SetLength(FLastReceived, BufSize); if ReadFile(ComHandle, FLastReceived[1], BufSize, BytesRead, @Overlapped) and (BytesRead > 0) then SendMessage(FTargetHandle, WM_DATARECEIVED, WParam(FLastReceived), 0); end; end;
var Overlapped: TOverlapped; EventMask, Dummy, SignalState: DWORD; EventHandles: array[0..1] of THandle; DCB: TDCB; TimeOut: TCommTimeouts; begin SetThreadName;
if FComHandle <> INVALID_HANDLE_VALUE then begin DCB.DCBlength := SizeOf(DCB); DCB.BaudRate := 9600; DCB.Flags := 1; DCB.wReserved := 18; DCB.XonLim := 256; DCB.XoffLim := 256; DCB.ByteSize := 8; DCB.Parity := NoParity; DCB.StopBits := 0; DCB.XonChar := #17; DCB.XoffChar := #19; DCB.ErrorChar := #0; DCB.EofChar := #0; DCB.EvtChar := #0; DCB.wReserved1 := 37563; if SetCommState(FComHandle, DCB) then begin GetCommTimeOuts(FComHandle, TimeOut);
TimeOut.ReadIntervalTimeOut := MaxInt; TimeOut.ReadTotalTimeoutMultiplier := 0; TimeOut.ReadTotalTimeoutConstant := 0;
TimeOut.WriteTotalTimeoutMultiplier := 100; TimeOut.WriteTotalTimeoutConstant := 1000; if SetCommTimeouts(FComHandle, TimeOut) then begin if SetCommMask(FComHandle, EV_RXCHAR) then begin FillChar(Overlapped, SizeOf(Overlapped), 0); Overlapped.hEvent := CreateEvent( nil, True, True, nil );
Overlapped.Internal := 0; Overlapped.InternalHigh := 0; Overlapped.Offset := 0; Overlapped.OffsetHigh := 0;
EventHandles[0] := FStopWaitingEvent; EventHandles[1] := Overlapped.hEvent; repeat WaitCommEvent(FComHandle, EventMask, @Overlapped); SignalState := WaitForMultipleObjects(2, @EventHandles, False, INFINITE); if (SignalState = WAIT_OBJECT_0 + 1) and GetOverlappedResult(FComHandle, Overlapped, Dummy, False) then ReceiveBytes(FComHandle, Overlapped); until SignalState <> (WAIT_OBJECT_0 + 1); SetCommMask(FComHandle, 0); PurgeComm(FComHandle, PURGE_TXCLEAR or PURGE_RXCLEAR); CloseHandle(Overlapped.hEvent); end; end; end; FileClose(FComHandle); end; end; | Das Programm hängt in der markierten Zeile, das heißt das Event wird nicht ausgelöst.
Ich habe auch schon versucht nach WaitCommEvent bei Rückgabewert False mit GetLastError auf ERROR_IO_PENDING zu prüfen um direkt GetOverlappedResult zu benutzen, aber ohne Erfolg. Ich bekomme dann keine Daten, wenn ich nicht warte oder hänge dort, wenn ich warte.
Weitere Versuche:
TComPort hat das selbe Problem, eine andere Komponente, die kein WaitXXX nutzt, funktioniert.
Hat jemand eine Ahnung woran das liegen kann?
Vielen Dank,
schönen Gruß,
Sebastian
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 25.03.11 21:44
Warum WaitForMultipleObjects(2...);
|
|
jaenicke 
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 25.03.11 22:08
Das eine Event ist das zum Abbruch des Threads, das zweite ist das Event des COM-Ports. Und die 2 gibt an, dass es sich um zwei Events handelt.
Das Abbruchevent funktioniert auch problemlos, d.h. wenn ich das Programm beende und daher mit SetEvent das Event auf Signaled setze, wird der Thread auch sauber beendet.
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 25.03.11 22:27
Wäre eine Variable (>0) nicht besser, die man dann mit "if SignalState =" auswertet?
|
|
jaenicke 
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 25.03.11 23:04
Ich weiß gerade nicht genau worauf du hinaus willst, aber der Punkt ist ja nicht die Auswertung von SignalState sondern, dass das Event gar nicht ausgelöst wird.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Sa 26.03.11 00:49
EventMask ist nicht initialisiert
(Warum sagt der Compiler das nicht?)
Wenn es das nicht war, ein paar Fragen die ich schon getippt hatte als es mir aufgefallen ist:
Was hast du gemacht, damit es nicht mehr geht, sprich, wie war es vorher?
Sicher, dass das Event-Handle iO ist?
Was passiert mit WaitForSingleObject?
Was bezweckst du mit dem .ReadIntervalTimeout-Wert? (Huch, das sieht mir grad am kritischsten aus)
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
jaenicke 
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 26.03.11 01:00
Martok hat folgendes geschrieben : | EventMask ist nicht initialisiert
(Warum sagt der Compiler das nicht?) |
Das ist ein Out-Parameter.
Martok hat folgendes geschrieben : | Was hast du gemacht, damit es nicht mehr geht, sprich, wie war es vorher? |
Nichts, das ist ja das Problem. Insbesondere funktioniert eben auch die TComPort-Komponente selbst nicht, deshalb ist die Frage eher welche Einflüsse / Treibereinstellungen / ... das verursachen könnten.
Martok hat folgendes geschrieben : | Sicher, dass das Event-Handle iO ist? |
Zumindest deutet nichts darauf hin, dass es das nicht wäre. Das ist immer so ein Wert um die 300 oder so, das sollte passen. Warum sollte CreateEvent auch nicht funktionieren, so viel passiert da ja nicht.
Martok hat folgendes geschrieben : | Was passiert mit WaitForSingleObject? |
Ich warte, dass entweder abgebrochen wird oder ein Event vom COM-Port kommt. Das prüfe ich dann mit dem SignalState.
Martok hat folgendes geschrieben : | Was bezweckst du mit dem .ReadIntervalTimeout-Wert? (Huch, das sieht mir grad am kritischsten aus) |
Ich will ja unendlich warten, wenn nicht abgebrochen wird. Deshalb ist es auch so wichtig auf beide Events zu warten.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Sa 26.03.11 01:36
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
|