Daten lesen vom Com-Port via Events macht Probleme
-
Hi,
ich versuche anhand des Beispiels MTTTY von MS ein Programm zu schreiben, welches mit seinen Threads Schreib und Lesezugriffe auf dem Com-Port regelt.
Da ich mit Qt arbeite, verwende ich Qthreads.
Ich bin mir nicht sicher ob ich meine read-funktion richtig implementiert habe. Wäre sehr nett, wenn es jemand überfliegen könnte.
Hier ist mein Einstiegspunkt für den Lese-Thread.
Wenn ich meinen Thread irgendwann beenden will, setze ich von ausserhalb die Variable threadDone auf true.
In jedem Durchlauf wird die read Funktion meiner serial-Klasse aufgerufen.void threads::readProc() { threadDone = false; while(!threadDone){ serialPtr->read(); msleep(50); //wegen busy waiting... } wait(); }Die Read-Funktion meiner serial-klasse.
bool qserial::read() { if(portIsOpen){ //flag wird erst nach Connect auf true gesetzt, damit nicht vorher hier reingegangen wird. (Threads werden schon früher erzeugt) if(osReader.hEvent == NULL || osStatus.hEvent == NULL) return false; //die Event-Objekte erzeuge ich im Ctor meiner serial-Klasse if(!fWaitingOnRead){ //get the size of data in the com buffer LPCOMSTAT lpcs; lpcs = (LPCOMSTAT) new BYTE[sizeof(_COMSTAT)]; if(ClearCommError(hComm,&dwErrors,lpcs)){ dwBytesToRead = lpcs->cbInQue; // manchmal zeigt der mir einfach zu wenige Bytes an, obwohl mehr im Com-Buffer sein sollten. Bin ich zu schnell?? readBuf->resize(dwBytesToRead); //readBuf ist ein QbyteArray, reserviere hier platz readBuf->fill(0x0); // init mit 0 } if(!ReadFile(hComm,(LPVOID)readBuf->operator const void *(),dwBytesToRead,&dwRead,&osReader)){ if(!(GetLastError() != ERROR_IO_PENDING)) fWaitingOnRead = true; }else{ //do sth. with data if(dwRead){ QMutex mutex; mutex.lock(); readJob->push_back(readBuf->data()); //Daten kommen manchmal unvollständig an readBuf->clear(); mutex.unlock(); emit dataIN(); } } // } // } delete [] lpcs; } SetCommMask(hComm,dwStoredFlags); if(!(fWaitingOnStat)){ if(!WaitCommEvent(hComm,&dwCommEvent,&osStatus)){ if(!(GetLastError() != ERROR_IO_PENDING)) fWaitingOnStat = true; } //handle status here... } if(fWaitingOnRead && fWaitingOnStat){ HANDLE hArray[READ_HANDLES]; hArray[0] = osReader.hEvent; //read hArray[1] = osStatus.hEvent; // stat dwRes = WaitForMultipleObjects(READ_HANDLES,hArray,false,READ_WAIT_TIMEOUT); switch(dwRes){ //read case WAIT_OBJECT_0: if(GetOverlappedResult(hComm,&osReader,&dwRead,false)){ if(dwRead != MAX_READ_BUFFER) int xy = 0; // read timed out. if(dwRead){ QMutex mutex; mutex.lock(); readJob->push_back(readBuf->data()); //falls es zum pending kommt, erwarte ich die daten hier. readBuf->clear(); mutex.unlock(); emit dataIN(); } } fWaitingOnRead = false; break; //status case WAIT_OBJECT_0 + 1: if(GetOverlappedResult(hComm,&osStatus,&dwOvRes,false)) //handle status here... fWaitingOnStat = false; break; case WAIT_TIMEOUT: int x; //nur um breakpoint setzen zu können x=0; break; default: break; } } } return true; }Bin mir nicht sicher ob meine Implementierung so richtig ist.
Ich setze mit meinem Programm über das Com-Port (an das Gerät) einen Befehl ab z.B. 0x12. Daraufhin antwortet das Gerät und ich will diese Antwort mit meinem Reader-Thread abfangen.Jedesmal wenn ich beim debuggen, meinen Befehl absetze bekomme ich von ClearCommError unterschiedliche Anzahl von Bytes die im Com-Puffer auf mich warten.
Wenn es z.B. 2048 Bytes an Daten sein sollte, kommen 5 Bytes an un die restlichen 2043 Bytes werden erst beim nächsten Schleifen-Durchlauf (Thread) gelesen.
Das MTTTY Beispiel scheint richtig zu laufen, meine Implementierung macht mir noch ProblemeWas kann ich hier besser machen?
-
keiner da?

-
Aktuell habe ich folgendes Problem.
Beim ersten mal klappt mein ReadFile.
Daten kommen an. WEnn ich ein zweites mal Daten anfordere verhält sich Readfile merkwürdig.Es enthält immernoch die Daten von vorhin im Input-Buffer und hängt die neued Daten einfach ran.
Wie kann ich das verhindern?
Muss ich explizit die Daten nach dem Lesen löschen???, damit sie nicht mehr auftauchen.