Forum: Mikrocontroller und Digitale Elektronik Konzept: Protokoll und Statemaschine


von Richard (Gast)


Lesenswert?

Hallo,

mich würde interessieren, wie man sauber eine Software (Statemaschine)
programmiert, die Daten mit einer Gegenstelle über ein definiertes
Protokoll austauscht.
Angenommen das Protokoll läuft über eine Bus-Schnittstelle und kennt
verschiedene Befehle wie z.B. 'RelaisAbfragen'. Wird dieser Befehl
vom Master übertragen, so weiß die Gegenstelle (also das "Relais"),
daß sie eine (dem Protokoll entsprechende) Antwort zu senden hat.
Der Master fragt jetzt reihum einige Relais ab (ohne auf die
Eintreffende Antwort zu warten). Manche Antworten lassen aber
"länger" auf sich warten, bevor der Slave Antwort geben kann. Der
Master läßt sich dadurch natürlich nicht blockieren und fährt in seinem
Hauptprogramm fort. Irgendwann treffen jetzt in beliebiger Reihenfolge
die Antworten der Slaves ein.

Mich interessiert jetzt aus Sicht des Masters wie dieser dann
prinzipiell diese Antworten seinen zuvor versendeten Befehlen
zuordnet.


Ich würde mich freuen, wenn ihr kurz berichten könntet wir ihr sowas
umsetzt. Mich interessiert weniger der prinzipielle Aufbau von
Statemaschinen oder gar Code, sondern ein Konzept.


mein Wissensstand: Statemaschinen sind kein Fremdwort; (gute)
Programmierkenntnisse in C vorhanden

Hoffentlich habe ich nicht zu viele wichtige Details vergessen.

Danke und Gruß, Richard

von Richard (Gast)


Lesenswert?

Ergänzung: Daß die Antwort der Slaves natürlich mit Absendekennung usw.
versehen ist, sei natürlich vorausgesetzt.
Wie stelle ich die Beziehung zwischen gesendeten Daten und darauf
empfangenen Daten her, unter der Nebenbedingung, daß Senden und
Empfangen voneinander asynchron(?) erfolgen kann?

Richard

von Wirus! (Gast)


Lesenswert?

Moin,

schau Dir mal das Modbus-Protokoll an, das arbeitet mit einem Master
und mehrern Sklaven.

Unter http://www.mcselec.com/modbus.htm findest Du eine praktische
Umsetzung mit Bascom für den AVR.

Prinzip:
Master sendet Slaveadresse, Request (Befehl wie lesen, schreiben etc.),
gewümscher Abfrageparameter (Schaltzustand, Wert, etc.) und Checksumme.

Slave antwortet mit seiner Adresse, Request, Bytelänge der Daten, Daten
und Checksumme.

Ich hoffe, das hift & schöne grüße, Wirus!

von Richard (Gast)


Lesenswert?

@Wirus:
Soweit ist mir das alles klar. Und das was ich unter dem Link gelesen
habe, beschreibt auch nur daß auf eine Anfrage eine Antwort folgt. Mich
interessiert, wie der Zusammenhang in der Software zwischen den beiden
hergestellt wird.

Einmal habe ich einen sendenden "Task" (so nenn ichs jetzt mal,
obwohls praktisch eine Statemaschine ist) und als zweites habe ich
einen empfangenden Task. Die beiden haben soweit ja noch nichts
miteinander zu tun - also wie verbindet man die beiden?

Vielleicht seh' ich auch nur den Wald vor lauter Bäumen nicht...?

Danke, Richard

von A.K. (Gast)


Lesenswert?

1: Der bei Controllern häufige Trivialfall: Die Slaves sind
Zustands-Sensoren wie z.B. Schalter, Temperatur etc. Die Kommunikation
zwischen Slave und Master erfolgt zwar asynchron, es kann aber nicht
vorkommen, dass mehrere Messages eines(!) Slaves gleichzeitig unterwegs
sind und sich überholen können (bei RS485 ist das eher unüblich).

Wichtig ist hier üblicherweise nur, dass der neueste Wert vorliegt. Der
Zustand wird im Receiver-Interrupt oder einem Receiver-Thread zusammen
mit der Timestamp des Eintreffens der Message global gespeichert. Muss
man dann nur in geeigneter Form auf den Fall reagieren, dass die
Timestamp zu alt ist.


2: Wenn sich Messages doch überholen können (Ethernet, evtl. bei CAN je
nach Implementierung): Timestamp oder Sequence-Number mitschicken
(entweder lang genug, oder mit deren Überlauf klarkommen) die vom Slave
unverändert retourniert wird. Nur neuere Responses werden gespeichert.
Die Seqno kann auch im Slave selbst erzeugt werden, dann muss man aber
mit einem autonomen Reset vom Slave klar kommen.


3: Die universelle Variante bei komplexem mehrphasigem Master/Slave
Protokoll. In dem Fall neige ich eher zu einem RTOS, in dem die
diversen Master/Slave Protokolle in jeweils eigenen Threads ablaufen.
Es ist lediglich notwendig, beim Empfang von Messages abhängig von der
Absenderkennung den richtigen Prozess zu benachrichtigen. Das ist im
Grunde nichts anderes als Programmierung mit BSD-Sockets. Verklemmungen
werden erkannt, indem jeder Thread eine Timestamp mitzieht und eine
separate Instanz auf veraltete Timestamps überprüft.

von Wirus! (Gast)


Lesenswert?

@Richard

Tja, das ist Sache des Masters. Da der Slave immer mit seiner Adresse
und dem angeforderten Befehl antwortet, kann man einfach eine Liste
führen, die alle offenen Requests vorhält.

Trifft eine Antwort ein, ist der entsprechende Request aus der Liste zu
entfernen. Zusätzlich ist noch ein Timeout-Handling zu implementieren,
das überfällige Requests entfernt und ggf. Fehlermeldungen ausgibt.

Natürlich sollte an einen Slave mit einem offenem Request auch kein
neuer Befehl geschickt werden, sondern erst nach der Antwort oder dem
Timeout.

Grüße, der Wirus!

von Richard (Gast)


Lesenswert?

Danke für die Beiträge.

Ich hatte mich so auf die Statemaschinen versteift und wollte unbedingt
die Rx- mit der Tx-Statemaschine (SM) "verheiraten", d.h. Rx schaltet
den State von Tx weiter nachdem eine gültige Antwort eingetroffen ist.
Theoretisch erschien mir das unsauber, daß "von außen" die States
verändert werden...

Die Hinweise oben mit der Liste, die dann die offenen/erledigten
Anfragen/Antworten enthält, scheint ein guter Ansatz zu sein.

Kurzum:
Unabhängig von Rx- und Tx-SM brauche ich noch einen globalen
"Speicher", der erstens mitprotokolliert was noch offen steht und
zweitens die empfangenen Daten aufnehmen kann. Eine übergeordnete
Instanz sieht anhand dieses "Speichers" und/oder Liste was als
nächstes zu tun ist und gibt den Rx- und Tx-SMs neue "Aufträge"...
Die "Intelligenz" verschiebe ich also weg von den Rx- und Tx-SMs hin
in eine Übergeordnete SM.

So sollte das doch zu lösen sein.

Danke, Richard.

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
Noch kein Account? Hier anmelden.