Fehler beim öffnen der seriellen Schnittstelle



  • danke für deine hilfe aber es geht immer noch nicht kann einmal diese Funktion bei Programmstart ausführen danach bekomme ich wieder von GetLastError die 6 zurück

    noch ne andere Idee ?



  • Hmmm, das is komisch. Ich mach eigentlich alles genauso wie Du beim Öffnen der seriellen Schnittstelle - und bei mir funktionierts. Das einzige is, dass ich die Timeouts anders setze. Vielleicht probierst Du das mal:

    COMMTIMEOUTS comtime;
    GetCommTimeouts( m_hPort, &comtime );  
    comtime.ReadIntervalTimeout= MAXDWORD;
    comtime.ReadTotalTimeoutMultiplier=0;
    comtime.ReadTotalTimeoutConstant= 0;
    comtime.WriteTotalTimeoutMultiplier=10;
    comtime.WriteTotalTimeoutConstant=100;
    SetCommTimeouts( m_hPort, &comtime );
    


  • Der Fehler tritt ja schon vorher auf bei
    m_hCom = CreateFile(...), deshalb kann das nicht an den Werten der COMMTIMEOUT Struktur liegen. Ich bekomme ja bei h_mCom das vorher ausgeführt wird den ungültigen Handle. Auch schon mit PurgeCom.. und CloseHandle... ausprobiert aber irgendwie funzt das alles nicht :-(( Bekomme immer wieder von GetLastError 6 zurück komisch.

    Hast du sonst noch eine Idee ?

    Kann ich z.B. abfragen warum ich keinen gültigen HANDLE bekomme um auf die Ursache zu stossen ?

    // Serielle Schnittstelle konfigurieren
    	m_hCom = CreateFile(m_pCOMPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 
    	BOOL handle = GetCommState(m_hCom, &dcb);		// Werte des COM-Ports holen (vorinitialisieren)
    	int error = GetLastError();
    
    	dcb.BaudRate	 = CBR_9600;
    	dcb.ByteSize	 = 8;
    	dcb.Parity		 = NOPARITY;
    	dcb.StopBits	 = ONESTOPBIT;
    
    	SetCommState(m_hCom, &dcb);		// neue Werte übergeben
    
    	// Timeout-Zeit für die Serielle Schnittstelle einstellen
    	GetCommTimeouts(m_hCom, &comtimeout);			
    	comtimeout.ReadIntervalTimeout = MAXDWORD;	
    	comtimeout.ReadTotalTimeoutConstant = 500;	
    	comtimeout.ReadTotalTimeoutMultiplier = 10;
    	comtimeout.WriteTotalTimeoutConstant = 500;
    	comtimeout.WriteTotalTimeoutMultiplier = MAXWORD;
    	SetCommTimeouts(m_hCom, &comtimeout);
    

    MfG



  • GetLastError sollte helfen.

    Ich bin mal so neugierig: Hast du keine MSDN? Ich habe nur das Kapitel zu CreateFile überflogen und das gefunden.
    Das soll jetzt keineswegs böse gemeint sein, ich bin echt nur neugierig.



  • Habe noch zu erwähnen das das ganze im Thread abläuft sorry. Nämlich so
    wird sie aufgerufen:

    Ablauf:
    OnStartSim ruft - > MainThread und der wiederrum -> Automaticsim. Am Ende der Simulation wird dann SendStopCommand aufgerufen um den Test zu beenden.

    void CLVErrSimDlg::OnStartsim01() 
    {
    	// Listboxinhalt löschen
    	m_ctrLogStatus.ResetContent();	
    	m_ctrLogStatus.AddString("Test wird gestartet");
    
    	m_nFlagNum = 2;
    	CWinThread* pThread = AfxBeginThread(MainThread, this);
    }
    
    UINT CLVErrSimDlg::MainThread(LPVOID pParam)
    {
    	CLVErrSimDlg* pDlg = (CLVErrSimDlg*) pParam; // Konverierung des NULL-Zeigers in den gewünschten
    
    	if(pDlg->m_nFlagNum == 1)
    	{
    		pDlg->DataSend();																// normale Simulation ausführen
    		return 0;
    	}
    
    	if(pDlg->m_nFlagNum == 2)
    	{
    		pDlg->Automaticsim();														// automatische Simualation ohne Rücksprung auf 00 ausführen 
    		return 0;
    	}
    
    	if(pDlg->m_nFlagNum == 3)
    	{
    		pDlg->Automaticsim2();													// automatische Simualation mit Rücksprung auf 00 ausführen 
    		return 0;
    	}
    
    return	1;
    }
    
    void CLVErrSimDlg::Automaticsim() 
    {
    		m_nAnzlichtsnr = 100;
    		m_nFehlerstation = 11;
    		m_nCodeNum = 1;
    
    		m_bWrite = 0;
    		m_bReadStatus = 0;
    		m_bErrFlgTr = FALSE;
    		m_bErrFlgRc = FALSE;
    
    		m_bStartFlg = TRUE;
    		m_bAutomTestFlg = TRUE;
    		int nDelayTime = 1;
    		BOOL status = TRUE;				// Status der Datenkommunikation
    
    		// Start -und Stoppbit werden automatisch generiert
    
    		// SerielleSchnittstelle konfigurieren
    		if((status = this->SerialCommunikation()) == FALSE)
    			MessageBox("Kein Zugriff auf die serielle Schittstelle !!!", "Zugriffsverweigerung auf die serielle Schnittstelle", MB_ICONERROR);
    
    		else
    		{...}
    }
    
    BOOL CLVErrSimDlg::SendStopCommand()
    {
    	DWORD f = 10; 
    	int m_nAKN = 0;
    	BOOL m_bWrite = 0;
    	BOOL m_bReadStatus = 0;
    
    	if((m_bStartFlg == TRUE) && (m_bErrFlgRc == FALSE))
    	{...}
    
    	//m_hCom = 0;
    	m_bStartFlg = FALSE;
    	m_bErrFlgTr = FALSE;
    	m_bErrFlgRc = FALSE;
    	m_bAutomTestFlg = FALSE;
    	m_nFlagNum = 0;
    
    	m_ctrLogStatus.AddString("Test gestoppt !!!");
    
    	BOOL handle = CloseHandle(m_hCom);
    
    int error = GetLastError();
    	if((m_bErrFlgTr == FALSE) && (m_bErrFlgTr == FALSE))
    		return 1;
    	else
    		return 0;
    }
    


  • Ja ich habe die MSDN aber da steht auch nicht mehr wie

    Communications Resources
    The CreateFile function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, and the hTemplate parameter must be NULL. Read, write, or read-write access can be specified, and the handle can be opened for overlapped I/O. For more information about communications, see Communications.

    drinne. Und das habe ich alles gemacht.

    GetLastError() benutze ich auch.



  • Aaaaah,
    schreib mal beim 6. Parameter von CreateFile FILE_ATTRIBUTE_NORMAL hin.



  • Und was sagt dir GetLastError?



  • funzt auch nicht

    GetLastError sagt liefert immer noch 6 zurück.

    Gibts keine API oder MFC-Funktion Funktion die mir sagen kann warum mir das Betriebssystem keinen gültigen HANDLE übergibt ?

    MfG



  • Mach mal das hier:

    LPVOID lpMsgBuf;
    FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        0, // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
    );
    // Process any inserts in lpMsgBuf.
    // ...
    // Display the string.
    MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
    // Free the buffer.
    LocalFree( lpMsgBuf );
    


  • Mein letzter Versuch:

    Du machst vielleicht schon vor dem Öffnen was falsch. Habe gerade das hier gefunden:

    ERROR_INVALID_HANDLE : The internal file identifier is incorrect.

    Naja, noch viel Glück



  • Habe eine neue Erkenntnis erlangt. Nachdem ich den Rechner neugestartet habe, und vorher den 6 Parameter auf FILE_ATTRIBUTE_NORMAL geändert habe, funzt es (bin zwar immer noch nicht 100% sicher das es auf Langzeit ohne Probleme läuft aber werde ich ja sehen) z.B. hat eben das Programm nach 3 mal starten gehangen und muste es über den Task-Manager beenden. Hast du eine Idee wie ich das abfangen kann (also das das Programm nicht hängen bleibt)?

    Finde es echt blöd das wenn man im Debugmodus einmal einen üngültigen Handler durch die Programmierung bekommt, das man Win neustarten muss. Verstehst du warum das so ist ?

    Weist du des weiteren vieleicht wie ich einen Thread ausserhalb einer Schleife beenden kann.

    MfG



  • Schön das es funktioniert. Das mit dem neustarten is komisch. Am besten is, wenn Du im Hintergrund einem Port-Monitor laufen hast, dann siehst Du genau, was passiert, z.B. Portmon (Freeware) bei www.sysinternals.com

    Von außen kann man einen Thread über TerminateThread beenden, das sollte man aber im Normalfall unterlassen (Siehe MSDN).



  • Danke für Eure Hilfe Jungs,

    aber warum sollte man es unterlassen einen Thread von aussen zu beenden ?

    MfG



  • 🙂

    TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.

    This function reduces memory leaks by clearing the stack before exiting. It also terminates the thread process only if the thread in question is the main or primary thread.

    TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:

    If the target thread owns a critical section, the critical section will not be released.
    If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread’s process could be inconsistent.
    If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.



  • Weil der Thread sonst keine Aufräumarbeiten mehr erledigen kann. Sowas sollte man tatsächlich nur im Ausnahmefall machen oder wenn man keinen Einfluss hat auf den Thread. Da du aber den Thread selber schreibst, kannst du auch eine Abfrage auf ein Flag einfügen, das den Thread dazu veranlasst zu beenden.

    Ich machs häufig ähnlich dem Shutdown-Prozess von Linux:
    Erst das Flag setzen (Sending term Signal), eine bestimmte Zeit auf den Thread warten, und dann, wenns bis dahin nicht beendet wurde, mit Gewalt dahinter (Sending kill signal) um den restlichen Ablauf nicht zu stören.

    -junix



  • Oh oh da habt Ihr Recht.

    Aber gibts denn eine Methode die laufende Threads des Programms aus abfragen kann ohne externe Programme wie z.B. den Prozessexplorer zu verwenden ?



  • Ja, GetExitCodeThread()

    @junix
    Dieses Flag sollte man aber dann irgendwie in eine CriticalSection o.ä. packen, oder?



  • wieso in eine CriticalSection dieses Flag rettet nur im Falle der Terminierung des Threads den Zustand also ob der Thread erfolgreich oder nicht erfolgreich beendet wurde mehr macht diese Funktion doch nicht.

    Ich finde sogar was oft in Vergessenheit gerät weil man schneller programmieren will sollte man generell bei mehreren Threads Prioritäten vergeben und Isollieren d.h. wie z.B. CriticalSection aber den Thread an sich nicht den Zusatand des Flags oder ?



  • Mmh, also ich dachte das wär so:

    Im Thread befindet sich irgendwo die Zeile:

    if ( flagShutdown )
    {
     //Thread beenden
    }
    

    So. Und wenn jetzt irgendwo im Programm dieses Flag auf true gesetzt wird,
    während der Thread gerade die Zeile if( flagShutdown ) liest, dann ist das doch nicht ynchronisiert oder hab ich da was falsch verstanden? 😕


Anmelden zum Antworten