Multithread Serial Communication Gui Problem...

Alles rund um die Programmierung mit Qt
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Multithread Serial Communication Gui Problem...

Beitrag von pepade »

Hi,

ich habe mir eine Klasse zur Rs232-Kommunikation geschrieben, die 2 threads erstellt (jeweils 1x Transmit/Receive). Der Receive Thread wartet auf die Daten (I/0 Multiplexing mit select(...)). Der Transmit Thread sended sofort die Daten. Beide Threads sind mit Mutex'en abgesichert. Das klappt soweit auch ganz gut auf einem Character-Based User-Interface (Kommandozeilen). Allerdings bin ich bei QT neu und ich bin mir ueber die Implementierung nicht sicher, wie ich meine Klasse in QT mit einbauen kann. Hat jemand eine bahnbrechende Idee fuer mich? :)

Gruß,
Pete...
mathies
Beiträge: 149
Registriert: 9. Februar 2007 17:50
Wohnort: Erfurt

Beitrag von mathies »

Hallo,

generell ist das doch kein Problem. Bisher erzeugst Deine Kommunikationsstrukturen in Deiner main(), nun würdest es halt in einer GUI Struktur machen.

Das einfachste wäre, Du erzeugst Dir erstmal überhapt eine GUI Klasse die Du anzeigen lässt. Dann brauchst doch Deine Strukturen da nur mit reinpachen und fertig :) Wenn diese eh in eigenen Threads laufen blockierst auch die GUI net und es sollte alles ohne Probleme gehen.
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Beitrag von pepade »

ich will die daten die ich ueber die rs232 schnittstelle erhalte, auch darstellen... darum gehts mir. Das bedeutet, ich muss die empfangenden Daten an die GUI weiterleiten. Wie loese ich das am besten?
Zuletzt geändert von pepade am 9. Oktober 2008 10:45, insgesamt 1-mal geändert.
mathies
Beiträge: 149
Registriert: 9. Februar 2007 17:50
Wohnort: Erfurt

Beitrag von mathies »

Dann erstelle in deiner GUI eine public Methode die einen String oder welche Daten Du auch immer hast empfangen kann und sende die Daten von Deiner Struktur an die GUI.

Am besten geht es wenn Du beide (also GUI und Deine Struktur) als dynamische Objekte anlegst und diese dann gegenseitig bekannt machst. Dann kann jeder auf jeden zugreifen, musste dann natürlich auch sichern.

Bsp main():

Code: Alles auswählen

A* gui = new A();
B* com = new B();

gui->setCom( com );
com->setGui( gui );
gui include:

Code: Alles auswählen

class com;

class gui
{
public:
    void setCom( B* com );
protected:
    b* mCom;
}
Für com würde es nur umgedreht aussehen. Somit hättest Du dann in beiden Klassen Zugriff auf die andere und kannst Daten hin und herschicken.
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Beitrag von pepade »

Vielleicht stehe ich gerad auf dem Schlauch, aber das aendert nichts daran, dass ich nicht weiß, wann die Daten angekommen sind. Also meine Com Class weiß, wann Daten angekommen sind. Ich muss der GUI nur signalisieren, dass sie sich die Daten abholt. Die Bekanntmachung der Daten ist nicht das Problem. Ich will in der GUI auch nicht Pollen...Oder reden wir aneinander vorbei?! :)
mathies
Beiträge: 149
Registriert: 9. Februar 2007 17:50
Wohnort: Erfurt

Beitrag von mathies »

Glaub irgendwie schon :)

Du weißt wann daten angekommen sind in Deiner Com Klasse?
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Beitrag von pepade »

Ja klar. Warum sollte ich das nicht wissen :)

Code: Alles auswählen

FD_ZERO(&fdSet);
	FD_SET(This->fileDescriptor, &fdSet);
	while(1){
	//cout << "REC THREAD" << endl;
	cout << "Waiting for Data" << endl;
	cout << "rec_thread_self: " <<  pthread_self() << ", pid: "<< getpid() << ", ppid: "<< getppid() <<  endl;
 	iSelRet = select( FD_SETSIZE, &fdSet, NULL, NULL, NULL );
	cout << "blaBla" << endl;
 	 if (iSelRet > 0)
        {
            /* -- we got something on stdin ?? -- */
            if (FD_ISSET (This->fileDescriptor, &fdSet))
            {
            	mutex_lock();
             /* -- we got something from serial line -- */
               cout << "Seriel Console Data" << endl; 
                int res;
                res = read(This->fileDescriptor,This->rBuffer,255);
                 
                if(res > 0){
                	cout << "buffer: " << This->rBuffer << endl;
                	This->rBuffer[res] = '\0';
                	for(int x = 0; x < res; x++)
						cout << "read: " << (int)This->rBuffer[x] << endl;
                }
                mutex_unlock();
               
            }      
        }
        else if (iSelRet < 0)
        { 
            cout << "Select Error" << endl;

        }
        else
        {
            /* just timeout */
        	cout << "TIMEOUT " << endl;
        //    wasEsc = 0;
        }
//		usleep(10000);	801
	}	
mathies
Beiträge: 149
Registriert: 9. Februar 2007 17:50
Wohnort: Erfurt

Beitrag von mathies »

Und wo ist dann das Problem die Daten einfach an die GUI zu schicken, wenn Du ja weißt wann Sie angekommen sind? Somit muss die GUI gar nix machen außer die Daten die Du ihr zuschickst just kurz nachdem Du sie erhalten hast. Oder?
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Beitrag von pepade »

es geht ja ums schicken der daten bzw der gui signalisieren, dass daten gekommen sind :) wir naehern uns...
mathies
Beiträge: 149
Registriert: 9. Februar 2007 17:50
Wohnort: Erfurt

Beitrag von mathies »

Dann schau nochmal in mein erstes Posting :)

Leg ne public Methode an in der Du deine Daten an die GUI übergibst von der COM aus. In der Methode schreibst die Daten dann halt in die Elemente die Du zur Anzeige nutzen willst...fertig. Nix pollen, nix warten...einfach schreiben wenn die Daten angekommen sind.
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Beitrag von pepade »

ah okay... aber neee, keine saubere loesung meines erachtens, denn der ReceiverThread soll die Gui nicht manipulieren. Der Receiver Thread soll lediglich die Daten entgegennehmen, decodieren und mehr nicht.

Was aber moeglich waere ist, dass ich bei den beiden Programmen ueber Sockets telefoniere... Waer auch einfach :)
mathies
Beiträge: 149
Registriert: 9. Februar 2007 17:50
Wohnort: Erfurt

Beitrag von mathies »

Aso haste das gesehen, ok :)

Somit wartet dann die GUI also zusätzlich ^^
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Beitrag von pepade »

richtig :) also hast du einen neuen ansatz? :D
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Wenn du nicht pollen willst ?
Wenn du die daten nicht von der COM Klasse in die GUI pressen willst ?

was bleibt ueber ? Events villeicht ?

BTW, wenn du QT4 verwendest, werden Funktionen die ueber den SIGNAL SLOT Mechanismus entkoppelt (Threadtechnisch) ... und verwenden intern quasi auch events ....

Was ist so schlimm, wenn dei COM-Klasse die die Datenaufbereitet, die daten an die GUI schickt, wenn diese sich gaendert haben ?
Ist das problem mehr logischer oder eher technischer Natur ?

Ciao ...
pepade
Beiträge: 11
Registriert: 29. September 2008 11:44

Beitrag von pepade »

Wie wuerde ich denn die Daten von meiner Com-Class an die Gui schicken, ohne die GUI zu blockieren? Hast du ein eventuell Beispiel?

Die Klasse, die ich geschrieben habe, soll unter umstaenden auch fuer andere Sachen verwendet werden und ich will nicht jedes mall die Klasse aendern.
Antworten