Fehler beim öffnen der seriellen Schnittstelle
-
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?
-
Cosmixx schrieb:
Dieses Flag sollte man aber dann irgendwie in eine CriticalSection o.ä. packen, oder?
Wenn mans wirklich sauber machen will, dann sollte man in der Tat über eine Zugriffsfunktion welche das Flag in einer Thread-Sicheren umgebung abfragt gehen. Der (Prozessor-)Zeitverlust ist meines Erachtens minimal. Wobei das Terminate-Flag in sofern eigentlich nicht weiter Thread-Kritisch sein muss.
Ich hab z.B. immer eine Zugriffsfunktion "Terminate" welche das Flag auf true setzt. Alle anderen lesen nur davon... Theoretisch sollte eigentlich da nix passieren, wenn man den lesenden Zugriff nicht in eine Critical Section passt. Allerdings muss man das natürlich von implementation zu implementation entscheiden... Ich hab mir z.B. eine CThread-Klasse gebaut, welche keine Critical-Sections nutzt. Aus oben genannten Gründen.
Das schlimmste was passieren kann, ist das der Thread in der Schleife einmal mehr durchläuft als eigentlich nötig. Wie gesagt. Der Programmierer muss hier klar abschätzen.
Für die "Sending kill signal"-Phase welche man dann ja mit TerminateThread implementiert, ist das Alles sowieso wieder eher nichtig.
-junix
-
Das man in der Schleife den Thread mit einem Flag auf true setzen beendet ist logisch, ich meinte aber angenommen ich starte einen Thread der etwas abarbeitet und dann beendet werden soll ohne überhaupt nur eine Schleife zu durchlaufen, wie beende ich dann den Thread oder brauche ich das nicht killt Windows dem Thread nach einer Timeoutzeit von alleine ? Was muss ich aber machen wenn ich ihn vorher beenden will und nicht auf Windows warten möchte ?
-
Cosmixx schrieb:
Mmh, also ich dachte das wär so:
Im Thread befindet sich irgendwo die Zeile:
if ( flagShutdown ) { //Thread beenden }Naja würde ich nicht unbedingt sagen. Meistens läuft ein Thread ja mehrere Male durch seine Aufgaben. also sähe es eher so aus:
//-- Setup code while (!flagShutdown) { //-- Working code } //-- Cleanup code return result_intSollte es nun passieren, dass der Thread in sich wieder Aufgaben erledigt, die schleifen enthalten, gilt natürlich das Selbe. Wenn einfach eine "längere" Sequenz innerhalb der Schleife steckt, dann kanns allerdings vorkommen, dass (zumindest ich mach das so) noch ein paar extra if-abfragen gesetzt werden... das kommt bei mir allerdings selten vor, weil ich meistens noch Progressbars aktualisieren möchte, etc. Und dafür kann ich sowieso keine längeren Rechnungen als ca. 0.5s am Stück brauchen.
-junix