Hallo zusamen,
ich stehe total auf dem Schlauch, ich versuche mit Visual Studio 2012
C++ einen, oder auch mehrere, Com Ports zu lesen. Ich habe mir dazu nach
bestem Wissen aus dem Internet etwas zusammen gesucht. Nur leider habe
ich ganz komische Effekte:
Manchmal scheint es so als ob Readfile() dem Eingang sagt wo er die
nächsten Daten hin schreiben soll, wenn ich durchsteppe dann steht das
nächste Byte sofort im Eingangsbuffer, manchmal aber eben auch erst nach
dem nächsten Readfile(). Und manchmal gehen einfach Bytes verloren.
Ich blicke das echt nicht. Kann das daran liegen dass der
Entwicklungsrechner eine VM ist? Mit Putty zu Putty funktioniert es
problemlos.
Der folgende Code läuft als Thread.
Danke schonmal worweg.
1
intSerial::StartComm(void)
2
{
3
4
OVERLAPPEDoEv,ovRd;
5
charinbuff[INPUTBUFFERSIZE];
6
intbuffptr=0;
7
BOOLstillread=TRUE;
8
BOOLrc=0;
9
intCommTimeoutCnt=0;
10
11
DWORDErr;
12
DWORDEventMask;
13
14
inti;
15
16
oEv.hEvent=CreateEvent(
17
NULL,// default security attributes
18
TRUE,// manual-reset event
19
FALSE,// not signaled
20
NULL// no name
21
);
22
23
// Initialize the rest of the OVERLAPPED structure to zero.
24
oEv.Internal=0;
25
oEv.InternalHigh=0;
26
oEv.Offset=0;
27
oEv.OffsetHigh=0;
28
29
assert(oEv.hEvent);
30
31
ovRd.hEvent=CreateEvent(
32
NULL,// default security attributes
33
FALSE,// not manual-reset event
34
FALSE,// not signaled
35
NULL// no name
36
);
37
38
// Initialize the rest of the OVERLAPPED structure to zero.
39
ovRd.Internal=0;
40
ovRd.InternalHigh=0;
41
ovRd.Offset=0;
42
ovRd.OffsetHigh=0;
43
44
assert(ovRd.hEvent);
45
46
//Verwende folgendes Event: warte auf irgendein Char
47
SetCommMask(hPort,EV_RXCHAR);
48
49
while(1)
50
{
51
52
rc=::WaitCommEvent(hPort,&EventMask,&oEv);
53
54
if(!rc)Err=::GetLastError();
55
56
// Gucken ob "pending", wenn ja auf Beendigung warten:
// Gucken ob "pending", wenn ja auf Beendigung warten:
6
if(Err==ERROR_IO_PENDING)
7
{
8
9
CommTimeoutCnt=0;
Was geschieht hier, wenn rc gültig ist?
Genau: Deine komplette Fehlerbehandlungsroutine wird durchlaufen, wenn
Err /zufälligerweise/ vom letzten Aufruf her noch den Wert
ERROR_IO_PENDING enthält -- obwohl rc doch gültig war.
Da Du weiter unten auch den Fall auswertest, daß rc gültig ist,
solltest Du dem if-Statement hier ein paar geschweifte Klammern
spendieren, so daß die Bestimmung und Auswertung von Err nur erfolgt,
wenn rc ungültig ist.
Danach kommt ein else anstelle der zweiten Auswertung von rc, und
Dein Programm bekommt die Chance, sich anders zu verhalten.
Das abschließende else und der letzte Aufruf von GetLastError dürfte
dann auch klar als Unfug erkennbar sein.
Danke, ist natürlich klar.
Aber das Grundproblem liegt vermutlich woanders: ich hab jetzt erst
verstanden was overlapped bedeutet.
Also habe ich das jetzt umgebaut. Muss man denn eigentlich auf einen
neuen Char warten? Denn wenn ich ReadFile() aufrufe kann ich mit
WaitForSingleObject ja auch darauf warten, oder spricht da was gegen?
Der folgende Code funzt jedenfalls:
1
//Overlapped
2
intSerial::StartComm(void)
3
{
4
5
OVERLAPPEDovRd;
6
charinbuff[INPUTBUFFERSIZE];
7
intbuffptr=0;
8
intCommTimeoutCnt=0;
9
DWORDbytes_transferred=0;
10
DWORDwait_result=0;
11
12
DWORDErr;
13
DWORDEventMask;
14
15
inti=0;
16
17
ovRd.hEvent=CreateEvent(
18
NULL,// default security attributes
19
FALSE,// not manual-reset event
20
FALSE,// not signaled
21
NULL// no name
22
);
23
24
// Initialize the rest of the OVERLAPPED structure to zero.
25
ovRd.Internal=0;
26
ovRd.InternalHigh=0;
27
ovRd.Offset=0;
28
ovRd.OffsetHigh=0;
29
30
assert(ovRd.hEvent);
31
32
//Verwende folgendes Event: warte auf irgendein Char