ReadFile langsam? Buffer überlauf? Woran liegts?



  • Hi,

    ich lese Daten, von einem Microcontroller gesendet, über den Comport aus.

    Dazu warte ich auf die Endkennung des Datenpakets mittels WaitForSingleObject() und lese die Daten dann mit ReadFile ein. Da ich die genaue Paketgröße kenne ist das alles kein Problem.

    Falls dennoch ein Fehler eintrifft, wird per polling mittels ReadFile die Anfangskennung gesucht und dann wieder die kompletten Pakete eingelesen.

    In der Theorie finde ich hört sich das ganz gut an, jedoch passiert so ein "Fehler" relativ oft... so ungefähr 30 mal in der Minute.

    Woran liegt das? Wenn ich mir die Daten in einem Terminal anschaue sind absolut keine Fehler zu sehen!
    Ist an meinem Programm ablauf etwas falsch?

    Thread zum warten auf Event char

    waitflag = true;
    	firstrun = true;
    	DWORD dwRes;
    	DWORD dwEvtMask = NULL;
    	OVERLAPPED over = {0};
    	memset(&over, 0, sizeof(over));
    	over.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
    	/// Schleife bis der Thread beendet wird
    	while(!Terminated){
    	  try{
    		if (hComm != INVALID_HANDLE_VALUE){
    			if (!waitflag) {
    				WaitCommEvent(hComm, &dwEvtMask, &over);
    				/// warten auf Endkennung 0xFE
    				dwRes = WaitForSingleObject(over.hEvent, 500);
    				switch (dwRes){
    					case WAIT_OBJECT_0 :
    						///Event aufgetreten
    						if (dwEvtMask == EV_RXFLAG){
    							/// Daten holen
    							empfangen();
    							/// Daten ans Display weiterleiten
    							MainForm->display(readdata);
    						}
    						break;
    					case WAIT_TIMEOUT :
    						// TimeOut -> nichts tun und weiter warten
    						break;
    					default : break;
    				}
    			}
    		}
    		/// readdata kann mit strg+z angezeigt werden
    		MainForm->Edit2->Text = readdata;
    		}catch(...){}
    	}
    	shutdownCom();
    

    Daten einlesen und Fehler handling

    OVERLAPPED ovread = {0};
    	ovread.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
    	DWORD dwBytesRead = 0;
    	/// Bei erstem Lauf nach Startkennung suchen
    	if (firstrun) {
    		u8 read1[1];
    		read1[0] = 0;
    		/// Solange bis Startkennung gefunden und Thread und Comport nicht beendet werden
    		while (read1[0] != 0xFF && !Terminated && hComm != INVALID_HANDLE_VALUE) {
    			ReadFile(hComm, read1, 1 , &dwBytesRead, &ovread);
    			while(!GetOverlappedResult(hComm,&ovread,&dwBytesRead,false) && !Terminated && hComm != INVALID_HANDLE_VALUE){
    				// warten
    			}
    		}
    	}
    	/// Auslesen der Daten
    	u8 read[100];
    	ReadFile(hComm, read, bytestoread+2 , &dwBytesRead, &ovread);
    	while(!GetOverlappedResult(hComm,&ovread,&dwBytesRead,false) && !Terminated && hComm != INVALID_HANDLE_VALUE){
    		// warten
    	}
    	firstrun = false;
    	/// Startkennung noch vorhanden? Wenn nicht -> Firstrun
    	if (read[bytestoread+1]!= 0xFF) {
    		firstrun=true;
    	}
    	/// Wenn kein Firstrun -> Daten zwischenspeichern zum Anzeigen
    	if (!firstrun) {
    		readdata = "";
    		for (int i = 0;i < bytestoread+2 ;i++ ) {
    
    			readdata += (char)read[i];
    		}
    	}
    


  • hör mal auf so frickligen code zu schreiben



  • danke bringt mich weiter....

    und was bitte soll daran fricklig sein?



  • waitflag = true; 
    firstrun = true; 
    DWORD dwRes; 
    DWORD dwEvtMask = 0; 
    OVERLAPPED over = { 0 }; 
    
    memset(&over, 0, sizeof(over)); 
    over.hEvent = CreateEvent(0, false, false, 0); 
    
    while(!Terminated)
    {
    	try
    	{
    		if(hComm != INVALID_HANDLE_VALUE)
    		{
    			if(!waitflag)
    			{
    				WaitCommEvent(hComm, &dwEvtMask, &over);
    				dwRes = WaitForSingleObject(over.hEvent, 500);
    
    				switch dwRes)
    				{
    				case WAIT_OBJECT_0:
    					if(dwEvtMask == EV_RXFLAG)
    					{
                            empfangen();
                            MainForm->display(readdata);
                        }
                        break;
                    case WAIT_TIMEOUT:
                        break;
                    default:
    					break;
    				}
    			}
    		}
    
    		MainForm->Edit2->Text = readdata;
    	}
    	catch(...) { ; }
    }
    
    shutdownCom();
    
    OVERLAPPED ovread = { 0 };
    ovread.hEvent = CreateEvent(0, false, false, 0);
    DWORD dwBytesRead = 0;
    
    if(firstrun)
    {
    	u8 read1[1];
    	read1[0] = 0;
    
    	while(read1[0] != 0xFF && !Terminated && hComm != INVALID_HANDLE_VALUE)
    	{
    		ReadFile(hComm, read1, 1 , &dwBytesRead, &ovread);
    
    		while(!GetOverlappedResult(hComm, &ovread, &dwBytesRead, false) && !Terminated && hComm != INVALID_HANDLE_VALUE) { ; } 
    	} 
    } 
    
    u8 read[100];
    ReadFile(hComm, read, bytestoread + 2 , &dwBytesRead, &ovread);
    
    while(!GetOverlappedResult(hComm, &ovread, &dwBytesRead, false) && !Terminated && hComm != INVALID_HANDLE_VALUE) { ; }
    
    firstrun = false;
    
    if(read[bytestoread + 1] != 0xFF)
    	firstrun = true;
    
    if(!firstrun)
    {
    	readdata = "";
    
    	for(int i = 0; i < bytestoread + 2; i++)
    		readdata += (char)read[i];
    }
    

    👍



  • Ok dankeschön!

    Du meintest also: kommentare rauslöschen und ein bisschen mehr Platz lassen. Ich dachte du meintest dass der Code schrott ist.

    edit: öhmn nur so, ich merk grad dass der post vermuten lassen könnte dass das Problem gelöst ist, ist es aber incht :D. Das ist der selbe Code nur etwas schöner dargestellt.


Anmelden zum Antworten