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



  • _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.



  • _matze schrieb:

    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... 🙄

    Wenn wir die Lösung des Problem auf den ClearCommError-Blödsinn schieben wollen, darfst Du zu Testzwecken aber auch nur diesen Part anfassen. Sonst zieht hier jemand am Ende noch falsche Schlüsse...



  • Mox schrieb:

    Entweder RS232 oder Bus, aber nicht beides.

    Doch, beides. 🙂

    Mox schrieb:

    Klemm doch einfach mal mehrere Geräte an Deinen "Bus"...

    Mehrere Slaves geht bereits so. 10 Slaves bei 115kbps und über 5m Kabellänge haut hin (ausprobiert). Die Eingänge sind hochohmig genug, um den Master nicht zu sehr zu belasten. Für Multi-Master-Betrieb ist ein Software-Protokoll nötig, das die Busarbitrierung regelt.

    Natürlich ist das eine Verfremdung von Rs232, das üblicherweise Point-to-Point-Protokoll ist. Aber hey, "Bussystem" bedeutet ja nicht per definitionem, dass es mehr als 2 Teilnehmer geben muss. 🙂

    Was lernen wir daraus? Spitzfindigkeiten sind doof!


Anmelden zum Antworten