Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

Ringpuffer einer seriellen Schnittstelle "parallel" zur Anwendungsoberfläche (GUI) auswerten
musicmiles
myCSharp.de - Member



Dabei seit:
Beiträge: 7
Herkunft: Hessen

Themenstarter:

Ringpuffer einer seriellen Schnittstelle "parallel" zur Anwendungsoberfläche (GUI) auswerten

beantworten | zitieren | melden

Guten Tag myC#-Community,

ich programmiere seid ein paar Jahren verschiedene Mikrocontroller in C. In den Objektorientierten Sprachen habe ich Erfahrungen in C++ und in Java gesammelt, dass liegt aber schon ein paar Jahre zurück.

Nun zum Thema bzw. zu meiner Frage:
Ich habe zur Kommunikation einiger Komponenten (Mikrocontroller) untereinander ein Protokoll entworfen. Dieses Protokoll hat folgenden Aufbau: Befehl, Länge, Daten[n], Checksumme. Sind neue Daten verfügbar, werden diese per Interrupt in einen Ring-Puffer geschrieben und wenn der Prozessor Zeit hat, liest dieser den Ring-Puffer aus und durchläuft Byte für Byte eine Statemaschine und interpretiert diese Daten. Nun möchte ich meine Controller mit einem Programm auf dem Computer kommunizieren lassen und habe dazu eine Forms-Anwendung erstellt. In meine Forms-Anwendung habe ich eine serielle Schnittstelle implementiert und lasse mir, wie auf den Controllern auch, einen Ringpuffer füllen.

Das Füllen des Ringpuffers klappt bisher (testweise) ohne Probleme und wird von dem Ereignis SerialPort.DataReceived folgendermaßen initiert (Code Auszugsweise):


const int MAX_SIZE_REC_QUEUE = 1024;

byte[] ReceiveQueue = new byte[MAX_SIZE_REC_QUEUE];
int RecQueueWrPtr = 0;
int RecQueueRdPtr = 0;
int BytesToRead = 0;

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
	BytesToRead = serialPort1.BytesToRead;
	serialPort1.Read(ReceiveQueue,RecQueueWrPtr,BytesToRead);
	RecQueueWrPtr += BytesToRead;
	if (RecQueueWrPtr ≥ MAX_SIZE_REC_QUEUE - 1)
		RecQueueWrPtr = 0;
}

Nun möchte ich die Daten in meinem Ringpuffer Byte für Byte einer Statemaschine zuführen und überlege wie ich dies in C# am saubersten gestalte. In dem Event-Handler serialPort1_DataReceived() über eine Schleife Byte für Byte durch den Puffer hangeln scheidet aus. Ich würde das gerne parallel oder besser gesagt pseudoparallel zur GUI machen. Auf meinen Controllern läuft einfach in main() eine Endlosschleife in der die entsprechende Überprüfung bei jedem Durchlauf stattfindet und bei Bedarf bei jedem Durchlauf der entsprechende Handler aufgerufen wird. Aber diese Schleife gibt es ja in meinem C#-Programm nicht.
Bei meiner Suche im Forum bzw. im Internet bin auf Begriffe wie Task, Backgroundworker, Thread, Event und Delegates gestoßen. Allerdings erscheint es mir nicht schlüssig, wie man ein solches Problem Grundsätzlich in C# angeht.
Wer kümmert sich bei einer oben genannten Lösung um den interruptfesten Zugriff auf meinen Ringpuffer, etc..

Kann mir jemand geeignete Lektüre empfehlen oder einen Denkansatz bzgl. des oben genannten Problems geben.

Vielen Dank im voraus

musicmiles
private Nachricht | Beiträge des Benutzers
Alf Ator
myCSharp.de - Member



Dabei seit:
Beiträge: 629

beantworten | zitieren | melden

Hallo musicmiles,

da sonst noch keiner geantwortet hat:

Du hast die richtigen Stichworte schon genannt. Du würdest quasi einen weiteren Thread (Task, Backgroundworker, Thread) anstoßen, der die Verarbeitung des Ringpuffers übernimmt.
Über events und delegates findes die Kommunikation zum Form statt.

Als Einstiegspunkt empfehle ich dir diesen Artikel:
[FAQ] Warum blockiert mein GUI?

Dort findest du entsprechende Links zu weiterführenden Informationen.

Gruß, Alf
private Nachricht | Beiträge des Benutzers
musicmiles
myCSharp.de - Member



Dabei seit:
Beiträge: 7
Herkunft: Hessen

Themenstarter:

beantworten | zitieren | melden

Hallo Alf,

vielen Dank für die Antwort. Der Link hat mir sehr geholfen.

Einen schönen Abend

musicmiles
private Nachricht | Beiträge des Benutzers
weismat
myCSharp.de - Member



Dabei seit:
Beiträge: 872
Herkunft: Frankfurt am Main

beantworten | zitieren | melden

Die entscheidende Frage hast Du Dir auch gestellt - das GUI wird immer in einem einzigen Thread aktualisiert - daher brauch man immer Control.Invoke/Dispatcher.Invoke zum Aktualisieren...
private Nachricht | Beiträge des Benutzers