Forum: PC-Programmierung Win API - ReadFile liest nichts von COM


von Fabian S. (jacky2k)


Lesenswert?

Hallo,
ich versuche grade verzweifelt etwas vom COM Port zu lesen. Problem 
dabei ist, dass das nicht blockend sein darf, sprich er soll einfach den 
Kram den er im Puffer hat zurück geben und fertig. Momentan gibt die 
ReadFile Funktion nen Fehler zurück, GetLastError() sagt dann jedoch 
ERROR_IO_PENDING, also alles OK. Nur steht in der Variable wo die Anzahl 
der gelesenen Bytes drin steht 0 drin.
Hier mein zusammengefasstes Programm:
1
  this->HCom=CreateFileA(Port.toStdString().c_str(), GENERIC_READ | GENERIC_WRITE , 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
2
  if(this->HCom==INVALID_HANDLE_VALUE)
3
    return CREATEFILE;
4
  if(!SetupComm(this->HCom, 4096, 4096))
5
    return SETUPCOMM;
6
  if(!PurgeComm(this->HCom, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR))
7
    return PURGECOMM;
8
  if(!GetCommState(this->HCom, &DCBstruct))
9
    return GETCOMMSTATE;
10
  QString CommDCBStr=Port+": baud="+Baud+" parity=N data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off";
11
  if(!BuildCommDCBA(CommDCBStr.toStdString().c_str(), &this->DCBstruct))
12
    return BUILDCOMMDCB;
13
  //this->DCBstruct.fDtrControl=0x02;
14
  if(!SetCommState(this->HCom, &this->DCBstruct))
15
    return SETCOMMSTATE;
Und dann noch das lesen:
1
int ComPort::read(char *Data, int toRead)
2
{
3
  DWORD Readed=0;
4
  overlappedRead.Offset=0;
5
  overlappedRead.OffsetHigh=0;
6
  overlappedRead.Pointer=NULL;
7
  overlappedRead.hEvent=0;
8
  ReadFile(this->HCom, Data, toRead, &Readed, &overlappedRead);
9
  if(GetLastError()==ERROR_IO_PENDING)
10
  {
11
    return Readed;
12
  }
13
  return -1;
14
}

von Fabian S. (jacky2k)


Lesenswert?

Ich habs nun mit Timeouts gelöst:
1
  COMMTIMEOUTS timeouts;
2
  if(!GetCommTimeouts(this->HCom, &timeouts))
3
    return SETCOMMTIMEOUTS;
4
  timeouts.ReadIntervalTimeout=0;
5
  timeouts.ReadTotalTimeoutMultiplier=0;
6
  timeouts.ReadTotalTimeoutConstant=1;
7
  timeouts.WriteTotalTimeoutMultiplier=0;
8
  timeouts.WriteTotalTimeoutConstant=0;
9
  SetCommTimeouts(this->HCom, &timeouts);

von Reinhard R. (reinhardr)


Lesenswert?

Hi,

alternativ kannst du auch mit der Funktion "ClearCommError" ein 
"COMSTAT" struct erhalten, welches in der Membervariable "cbInQue" die 
Anzahl der Zeichen im Eingangspuffer enthält. Wenn du dann beim 
Lesevorgang nicht mehr Zeichen einließt wird die Funktion vollständig 
aus dem Puffer bedient und wartet nicht auf weitere Zeichen oder 
Timeouts.
Ich habe das bei einem Gerät, dass immer 24byte große Frames verschickt, 
so gemacht dass ich immer nur ganzzahlige Vielfache von 24byte einlese. 
Dadurch werden keine unvollständigen Frames eingelesen, die man nachher 
wieder getrennt behandeln müsste.

Reinhard

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.