Problem mit serieller Schnittstelle (overlapped) - CloseHandle returned nicht!



  • Andromeda schrieb:

    _matze schrieb:

    Noch eine Ergänzung: wenn dieser Zustand eintritt, lässt sich der Prozess auch nicht mehr mit dem Taskmanager abschießen. Totaler Deadlock. Sobald ich das USB-Kabel ziehe, beendet er sich dann aber.

    Versuch doch mal den USB-RS232-Treiber (ich glaube er heisst usbser.sys) zu disablen (über den Device Manager), wenn es mal wieder zu einem CloseHandle-Hänger gekommen ist. Vielleicht funktioniert es dann wieder. Falls ja, könntest du daraus einen Workaround basteln. 🙂

    Wird schwierig, da der Kunde meist nur eine E-Mail mit Logfiles und dem Inhalt "gestern in der Spätschicht wieder passiert" schickt. Bis ich davon erfahre, ist das System längst wieder neugestartet. Aber sollte sich die Gelegenheit ergeben, versuch ich's mal. Schon mal danke für deine Hilfe soweit. 🙂



  • Mox schrieb:

    Was ist denn in Deinem Wandler für ein Chip verbaut? Hast Du zu Deinem Wandler mal den Treiber aktualisiert? Was verwendest Du für eine Strippe und wie lang ist diese? Ist das die 1€-Klasse bei 5m Länge, oder ist das was anständiges?

    Das ist ein FTDI-Chip. Die Treiber sind die gleichen wie auf allen Systemen, aber du hast Recht. Ich könnte mal schauen, ob es eine neue Version gibt. Ich glaube, wir kaufen schon halbwegs anständige USB-Kabel.



  • _matze schrieb:

    Schon mal danke für deine Hilfe soweit. 🙂

    Gern geschehen. 🙂

    Wenn du möchtest, dann poste bitte mal die Initialisierungssequenz, mit der du die RS232 "scharf" schaltest. Vielleicht lässt sich daran irgendeine Merkwürdigkeit erkennen.



  • Andromeda schrieb:

    _matze schrieb:

    Schon mal danke für deine Hilfe soweit. 🙂

    Gern geschehen. 🙂

    Wenn du möchtest, dann poste bitte mal die Initialisierungssequenz, mit der du die RS232 "scharf" schaltest. Vielleicht lässt sich daran irgendeine Merkwürdigkeit erkennen.

    Die ist ziemlich wüst (und unfertig, wie das ganze Projekt), aber gut. ^^ Vielleicht findet sich ja was.

    int CSerialPort::Connect() {
    	if (m_hCom != INVALID_HANDLE_VALUE && m_hCom != nullptr) {
    		Disconnect();
    	}
    
    	int portNumber = 0;
    	for (int i = 0; i < 2; ++i) {
    		FindSerialPort(
    			m_Parameters.Baudrate,
    			m_Parameters.StopBits,
    			m_Parameters.Parity,
    			m_Parameters.ByteSize,
    			m_Parameters.SearchSettings[i].cmd,
    			m_Parameters.SearchSettings[i].cmdLen,
    			m_Parameters.SearchSettings[i].expectedAnswer,
    			m_Parameters.SearchSettings[i].answerOffset,
    			m_Parameters.SearchSettings[i].answerLen,
    			&m_Parameters.PortNumber,
    			m_Parameters.SearchSettings[i].dlgHeadline,
    			m_Parameters.SearchSettings[i].tryCount);
    		if ((m_Parameters.PortNumber > 0) || (m_Parameters.SearchSettings[i + 1].cmdLen == 0)) {
    			//port found or no second set available
    			break;
    		}
    	}
    
    	m_hCom = CreateFile(PortNumberToDeviceString(m_Parameters.PortNumber), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
    
    	DCB dcb = { 0, };
    	dcb.DCBlength = sizeof(dcb);
    	BOOL b;
    	b = GetCommState(m_hCom, &dcb);
    	dcb.BaudRate = m_Parameters.Baudrate;
    	dcb.ByteSize = BYTE(m_Parameters.ByteSize);
    	dcb.StopBits = BYTE(m_Parameters.StopBits);
    	dcb.Parity = BYTE(m_Parameters.Parity);
    	dcb.XonLim = 0;
    	dcb.XoffLim = 0;
    	dcb.fParity = TRUE;
    	dcb.fAbortOnError = FALSE;//Any Error -> ERROR_IO_ABORTED, ClearCommError
    	b = SetCommState(m_hCom, &dcb); ////CHKRESRTN(!b, "SetCommState failed with code %d", FC_COMPortGeneral);
    	COMMTIMEOUTS timeouts;
    	timeouts.ReadIntervalTimeout = 1;//MAXDWORD; 
    	timeouts.ReadTotalTimeoutMultiplier = 0;
    	timeouts.ReadTotalTimeoutConstant = 0;
    	timeouts.WriteTotalTimeoutMultiplier = 0;
    	timeouts.WriteTotalTimeoutConstant = 0;
    	b = SetCommTimeouts(m_hCom, &timeouts);	////CHKRESRTN(!b, "SetCommTimeouts failed with code %d", FC_COMPortGeneral);
    	b = SetupComm(m_hCom, MAX_READ_BUFFER, MAX_WRITE_BUFFER); ////CHKRESRTN(!b, "SetupComm failed with code %d", FC_COMPortGeneral);
    	b = EscapeCommFunction(m_hCom, SETDTR); ////CHKRESRTN(!b, "EscapeCommFunction failed with code %d", FC_COMPortGeneral);
    	b = SetCommMask(m_hCom, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY); //CHKRESRTN(!b, "SetCommMask failed with code %d", FC_COMPortGeneral);
    	hEvExit = CreateEvent(NULL, TRUE, FALSE, NULL);
    	Log(LogLevel_All, "start thread CheckCommEventsThread");
    	hStatusThread = (HANDLE)_beginthreadex(0, 0, CheckCommEventsThread, this, 0, 0);
    
    	return 0;
    }
    


  • Was mir noch einfällt: rufst du irgendwo diese Funktion auf: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363180(v=vs.85).aspx ?

    Das sollte man tun, wenn ein Übertragungsfehler aufgetreten ist.



  • _matze schrieb:

    Das ist ein FTDI-Chip.

    Welche, Full Speed oder Hi-Speed? Für letztere brauchst Du unter Umständen bessere USB-Strippen!

    _matze schrieb:

    Die Treiber sind die gleichen wie auf allen Systemen, aber du hast Recht. Ich könnte mal schauen, ob es eine neue Version gibt.

    Schaden kann das nicht. Hoffentlich sind das auch orginale FTDIs, sonst... 😃

    _matze schrieb:

    Ich glaube, wir kaufen schon halbwegs anständige USB-Kabel.

    Zeritifzierte?



  • _matze schrieb:

    Die ist ziemlich wüst (und unfertig,

    Vor allem unfertig. Du bist doch bereits in der ersten Antwort auf Flusskontrolle angesprochen worden...

    Du musst den DCB schon komplett initialisieren. Das machst Du nicht, und das ist ein Fehler!



  • Andromeda schrieb:

    Das sollte man tun, wenn ein Übertragungsfehler aufgetreten ist.

    Soweit die Theorie. Praktisch kommt das nur bei Dir vor.



  • Mox schrieb:

    Andromeda schrieb:

    Das sollte man tun, wenn ein Übertragungsfehler aufgetreten ist.

    Soweit die Theorie. Praktisch kommt das nur bei Dir vor.

    Nope; prinzipiell ist der RS232-Treiber eine State-Machine. Gibts 'nen Bus-Error macht er dicht. Und das kann sich durchaus auch darin äußern, dass man ein Handle nicht closen kann. Matze sollte das einfach mal checken. 🙂



  • Mox schrieb:

    Du musst den DCB schon komplett initialisieren. Das machst Du nicht

    Macht er schon, denn er setzt ihn auf 0. 🙂



  • Andromeda schrieb:

    Macht er schon, denn er setzt ihn auf 0. 🙂

    Und überschreibt das gleich wieder mit dem Ist-Zustand:

    b = GetCommState(m_hCom, &dcb);



  • Andromeda schrieb:

    Nope; prinzipiell ist der RS232-Treiber eine State-Machine. Gibts 'nen Bus-Error macht er dicht. Und das kann sich durchaus auch darin äußern, dass man ein Handle nicht closen kann. Matze sollte das einfach mal checken. 🙂

    Bus-Error? Es geht hier um RS232. Und nach irgendwelchen Übertragungsfehlern kannst du das Handle immer schließen. Wenn das nicht funktioniert, geht was ganz anderes schief. ClearCommError hilft Dir in diesem Falle auch nicht.



  • Mox schrieb:

    Bus-Error? Es geht hier um RS232. Und nach irgendwelchen Übertragungsfehlern kannst du das Handle immer schließen. Wenn das nicht funktioniert, geht was ganz anderes schief. ClearCommError hilft Dir in diesem Falle auch nicht.

    Die Frage ist, was das sein könnte. 😕

    Mit dem DCB hast du Recht. Werde ich korrigieren. Das ist aber sicher nicht das eigentliche Problem, oder?

    Ich habe momentan einen Test hier im Büro laufen. Fast 500000 Kommunikationsversuche, alle erfolgreich. Ich kann das USB-Kabel ziehen und wieder dranstecken, und das Weiderverbinden funktioniert problemlos. Ich kriege dann halt Access Denied, dann suche ich mir wieder den richtigen COM-Port raus und es geht anstandslos weiter. Was zur Hölle passiert da beim Kunden? ^^



  • Mox schrieb:

    Bus-Error? Es geht hier um RS232.

    RS232 ist ein serieller Bus. 🙂

    Mox schrieb:

    Und nach irgendwelchen Übertragungsfehlern kannst du das Handle immer schließen.

    In seinem Fall wohl nicht.

    Mox schrieb:

    ClearCommError hilft Dir in diesem Falle auch nicht.

    Das vermutest du, aber wir wissen es nicht.


  • Mod

    _matze schrieb:

    Was zur Hölle passiert da beim Kunden? ^^

    Der einfachste Weg das herauszufinden ist, dass Du einen Speicherdump mit dem Taskmanager machst.

    Du benötigst dafür dann für die Analyse die entsprechenden passenden PDB Dateien der Executables. Dann könntest Du Dir auch den Callstack anstehen und kontrollieren worauf "im inneren" wirklich gewartet wird. Ist natürlich nur Usermode... aber könnte evtl. helfen.



  • Andromeda schrieb:

    Das vermutest du, aber wir wissen es nicht.

    Ich habe ClearCommError eingebaut. Ich hoffe, dass ich die neue DLL morgen beim Kunden aufspielen kann.



  • _matze schrieb:

    Andromeda schrieb:

    Das vermutest du, aber wir wissen es nicht.

    Ich habe ClearCommError eingebaut. Ich hoffe, dass ich die neue DLL morgen beim Kunden aufspielen kann.

    Sag bitte Bescheid, wie der Versuch ausgegangen ist. 🙂



  • Andromeda schrieb:

    _matze schrieb:

    Andromeda schrieb:

    Das vermutest du, aber wir wissen es nicht.

    Ich habe ClearCommError eingebaut. Ich hoffe, dass ich die neue DLL morgen beim Kunden aufspielen kann.

    Sag bitte Bescheid, wie der Versuch ausgegangen ist. 🙂

    Wird bis nächste Woche warten müssen. Der Kunde will die Produktion nicht anhalten... 🙄



  • Andromeda schrieb:

    Mox schrieb:

    Bus-Error? Es geht hier um RS232.

    RS232 ist ein serieller Bus. 🙂

    Entweder RS232 oder Bus, aber nicht beides. Klemm doch einfach mal mehrere Geräte an Deinen "Bus"...



  • _matze schrieb:

    Mox schrieb:

    Bus-Error? Es geht hier um RS232. Und nach irgendwelchen Übertragungsfehlern kannst du das Handle immer schließen. Wenn das nicht funktioniert, geht was ganz anderes schief. ClearCommError hilft Dir in diesem Falle auch nicht.

    Die Frage ist, was das sein könnte. 😕

    Mit dem DCB hast du Recht. Werde ich korrigieren. Das ist aber sicher nicht das eigentliche Problem, oder?

    Es ist auf jeden Fall ein Problem, das korrigiert werden muss. Das bringt dich jedenfalls deutlich weiter als der Schwachsinn mit ClearCommError.

    _matze schrieb:

    Ich habe momentan einen Test hier im Büro laufen. Fast 500000 Kommunikationsversuche, alle erfolgreich. Ich kann das USB-Kabel ziehen und wieder dranstecken, und das Weiderverbinden funktioniert problemlos. Ich kriege dann halt Access Denied, dann suche ich mir wieder den richtigen COM-Port raus und es geht anstandslos weiter. Was zur Hölle passiert da beim Kunden? ^^

    Das ist sicherlich ein Problem innerhalb Deines Treibers. Dieser ist als erstes zu aktualisieren. Und dann schau Dir die verwendeten Strippen an, notfalls einfach tauschen. Danach wird Ruhe sein.


Anmelden zum Antworten