Hallo, sorry für das ewig gleiche Thema. Meine selbst geschriebene Klassen für das Senden und Empfangen über UART funktionieren einwandfrei. Das Empfangen möchte jetzt aber optimieren. Bisher sieht das Empfangsprotokoll in etwa so aus: PC --> uC: Anfrage auf Informationen uC --> PC: uC sendet genaue Anzahl von BYTES. (Empfang) Ich möchte nun aber gerne, das meine PC-Software Daten empfängt die irgenwann auf den Bus gelegt werden. In einer while(1)-Schleife in meiner PC-Software möchte und kann ich nicht ewig auf einen Empfang warten. Wie kann ich ohne dieser while-Schleife das machen?????????????? Bin dankbar für jeden Vorschlag, Michael
Entweder per Thread, da ist eine while-Schleife kein Problem, oder mit dem Overlapped-Modus, der blockiert das programm nicht, so dass man regelmässig nachfragen kann, ob was da ist. Zu guter letzt wäre da noch readfileex, das eine Callback-Routine aufruft, wenn es fertig ist, aber damit habe ich noch nichts gemacht vondaher keine Ahnung, wie das genau funktioniert
Hi Tobi, was ist Deiner Meinung nach leichter zu programmieren. Die Thread- oder die Overlappedvariante. Und vielleicht hast Du noch ein paar gute Infolinks. Bei der MSN-Library verstehe ich meistens nur Bahnhof. Bin halt doch mehr der uC-Programmierer. Michael
Hier ist eine sehr gute Beschreibung aus der MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp Ich denke, wenn du noch wie was mit Threads gemacht hast ist die Overlapped-Version einfacher. Aber schau dir den Link mal an, dann solltest du das selbst einschätzen können
Hallo Tobi, danke für die Quelle ich komme damit ziemlich gut zurecht. Ich habe noch eine brauchbare Info gefunden, vorallem für die Einsteiger auf Multi-Thread. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/msdn_threads.asp MfG, Michael
Hallo, ich bin ein gutes Stück weiter mit dem Multithreading. In C ist das ja relativ einfach. Ich habe allerdings echte Probleme wenn ich das ganze im VC++ Code versuche zu implementieren. Ich möchte eine Memberfunktion von CTestboxDlg als BackgroundTread laufen lassen. Diese Memberfunktion soll mir in ein Ausgabefeld die asynchron empfangenen Zeichen (vom UART-Port) schreiben. Meine Fragen: Kann ich überhaupt eine Memberfunktion einer Klasse separat in einem Thread laufen lassen? Wenn ja wie? _beginthread( CTestboxDlg.MyMultiThread, 0, NULL ); funktioniert nicht... Ich hab' auch schon ein paar ander Funktionen auspropiert. Aber ich habe immer Ärger mit dem ersten Parameter. Der wird nie akzeptiert. Danke, Michael
. Kann ich überhaupt eine Memberfunktion einer Klasse separat in einem Thread laufen lassen? Das geht schon, nur muss diese Funktion eine statische Memberfunktion sein. Das bedeutet, daß es in der Funktion keinen this-Pointer gibt, sondern der, wenn benötig, als getrennter Parameter an _beginthread/CreateThread zu übergeben ist und der Funktion bei Aufruf entsprechend übergeben wird.
@ Rufus Danke für Deine schnelle Antwort. Ich bin leider nicht so sattelfest in C++. Kannst Du vielleicht mal einen Code Snippet von der statischen Funktion und der anschließenden Parameterüberger für _beginthread posten. Damit könntest Du mir wirklich weiterhelfen. Michael
Eine statische Member-Funktion ist im Grunde wie eine einzelne, freistehende Funktion. Nur dass sie halt aus welchen Gruenden auch immer, im Namensraum einer Klasse definiert wird. D.h. Du kannst genauso gut auch eine freistehende Funktion machen, die Du in den beginthread hineinstopfts. Schau Dir mal das angehaengte Beispiel an. Die ThreadFunktion bekommt eine globale Variable, die als Window-Handle zum Dialog fungiert. Die Thread- Funktion selbst kommuniziert mit dem Dialog Objekt indem es ihm Messages schickt. Dadurch vermeide ich, daß ich Funktionen des Dialog-Objektes aufrufe, wenn dieses in einem falschen Zustand ist. Die entscheidende Source ist in ThreadDlg.cpp / ThreadDlg.h
Nun, das ist schon noch ein Unterschied. Eine statische Memberfunktion kann über einen ihr übergebenen this-Pointer auf private und protected-Membervariablen ihrer Klasse zugreifen und über den this-Pointer auch nichtstatische Memberfunktionen ihrer Klasse aufrufen; eine alleinstehende nicht-Memberfunktion kann das nicht.
Hallo, Danke für Eure Untersützung. Ich bin jetzt ein gutes Stück weiter.Mein Thread (globale Funktion) läuft. Jetzt muss ich nur noch an ein "Ein-Ausbgabe"-Feld meines Hauptfensters die Daten schicken, die über die UART empfangen wurden . Ich habe es mir so gedacht. static BYTE hMemberVar; // Handle zu meiner AusgabeVariable global static HWND hDlg; // ... void CTestboxDlg::OnStartCatch() { ... hMemberVar = this->m_bCatchResult; hDlg = this->GetSafeHwnd(); } void NewMultiThread(void *pvParam) { BYTE bCatchUART = 34; // Hier empfang über UART *hMemberVar = bCatchUART; // ????????? Funktioniert nicht UpdateData(FALSE); // ????????? Hier hDlg Updaten while(1); } Nochmals Danke für Euren Support... Michael
Sorry muss natürlich ein Zeiger sein. static BYTE *hMemberVar; // Handle zu meiner AusgabeVariable global
Nochmals Sorry, manchmal steht man auf dem Schlauch. Lösung... static BYTE * hMemberVar; hMemberVar = & m_bCatchResult; *hMemberVar = bCatchUART; Allerdings habe ich noch immer das UpdateData(FALSE) Problem.
UpdateData solltest Du auf gar keinen Fall aus einem anderen Thread heraus aufrufen. Besser ist es in diesem Fall mit PostThreadMessage dem GUI-Thread der Applikation eine Nachricht zu senden, die vom Nachrichtenhandler Deines Dialoges ausgewertet wird und an dieser Stelle UpdateData aufruft.
Ok, Danke Leute. Ich hab's kapiert und zum laufen gebracht :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) Michael
Hallo, wie schon gesagt alles funktioniert so wie ich es mir vorstelle. Allerdings möchte ich jetzt noch meinen erzeugten Background-Thread: while (1){ USART Dauerempfang; SendMessage zu Main;} aus dem Bedienfenster wieder beenden. Ich kann das mit Hilfe ein globalen Variable "EndThreadFlg". while (EndThreadFlg == 0){ USART Dauerempfang; SendMessage zu Main;} Es würde mir aber viel besser gefallen, wenn ich eine Message an meinen Background-Thread schicken könnte und dann auf diese Message gezielt reagieren. Mein Backgroundprozess ist aber eine primitive globale Funktion. long WINAPI AsynUsartThread (long *pvParam) { Öffne Port; while (EndThreadFlg == 0){ USART Dauerempfang; SendMessage zu Main;} return 0; } Ist es sehr aufwendig meine AsynUsartThread-Funktion über Messages zu steuern??? Und wie kann man es ungefähr bewerkstelligen. Muss ich für meinen Thread einen großen Overhead anlegen zum Message-Empfang????? Danke für Eure Antworten, Michael
Statt ein Flag auszuwerten kannst Du auch ein Event verwenden. So etwas wird mit CreateEvent erzeugt und mit SetEvent signalisiert. Deine "Dauerempfangsfunktion" wird, sofern sie overlapped I/O verwendet, bereits irgendwo ein WaitForSingleObject verwenden. Wird das durch ein WaitForMultipleObjects ersetzt, kann die Wartefunktion im Thread sowohl eintreffende Zeichen als auch die Signalisierung des Events mitbekommen. Windows-Nachrichten sind für die Kommunikation mit Background-Threads ein eher ungeeignetes Mittel.
das mit den CEvent dingern ist nicht inbedingt notwendig.. wenns nur 1 thread ist geht das mit nem flag auch problemlos.. im übrigen solltest du möglichst NICHTS was einem CWnd gehört in einen thread reintun.. mach dir einen struct mit den daten die du drinnen haben willst, hol dir speicher dafür und gibt den pointer drauf in den thread.. der muss dann am schluss den speicher selbst wieder frei geben... alles andere ist schrott.. also im prinzip sowas... SMeineDaten *MeineDaten=new SMeineDate; MeineDate->m_hWindowToUpdate=<der handle auf das fenster was daten tun soll ;) MeineDate->wasauchimmer dann machst ein AfxBeginThread(....); oder wie auch immer du das erledigen willst... im thread schickst du dann einfach eine window-message and das fenster, von dem du den handle hast und schon rutschen die daten dort hin... (z.b SetWindowText-message) wie gesagt MESSAGE schicken.. nicht funktion aufrufen !!! das ist sonst alles NICHT Threadsafe!!! immer wenn dein fenster nachrichten verarbeitet(also sich neu zeichnet beim verschieben,...) dann wirds auch die box updaten... es gibt aber noch eine variante die ein grober hack ist.. du kannst in einem thread eine eigene message-queue aufbaun und dann das gesamt fenster im thread handlen... aber das ist böse.. tu lieber nachrichten schicken.. das ist unkompliziert und funktioniert gut ;) 73
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.