TIA X_GET und X_PUT auf collision detection Verfahren vertrauen?

SanjaDO

Level-1
Beiträge
177
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

ich habe hier ein Code den ich mit drei CPUs ausprobiert habe und habe die Daten kreuz und quer geschickt und ausgelesen. Das Ganze funktioniert auch ohne Probleme. Die Frage ist ob man nach der Fehlermeldung "80C0" darauf vertraut, dass die Daten verschickt werden sobald der Bus wieder frei ist. Ich bin auf eure Antworten gespannt.

Code:
IF #busy = 0  THEN
  #req:=1;
ELSE
  #req:=0;
END_IF;




#ret:=X_GET(REQ:=#req,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX0.0 INT 32,
            BUSY=>#busy,
            RD=>P#DB10.DBX0.0 INT 32);
#ret:=X_GET(REQ:=#req,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX64.0 INT 32,
            BUSY=>#busy,
            RD=>P#DB10.DBX64.0 INT 32);


#ret:=X_GET(REQ:=#req,
            CONT:=false,
            DEST_ID:=4,
            VAR_ADDR:=P#DB1.DBX0.0 INT 32,
            BUSY=>#busy,
            RD=>P#DB10.DBX130.0 INT 32);
#ret:=X_GET(REQ:=#req,
            CONT:=false,
            DEST_ID:=4,
            VAR_ADDR:=P#DB1.DBX64.0 INT 32,
            BUSY=>#busy,
            RD=>P#DB10.DBX194.0 INT 32);


#ret:=X_PUT(REQ:=#req,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX130.0 INT 32,
            BUSY=>#busy,
            SD:=P#DB10.DBX260.0 INT 32);
#ret:=X_PUT(REQ:=#req,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX194.0 INT 32,
            BUSY=>#busy,
            SD:=P#DB10.DBX324.0 INT 32);


#ret:=X_PUT(REQ:=#req,
            CONT:=false,
            DEST_ID:=4,
            VAR_ADDR:=P#DB1.DBX130.0 INT 32,
            BUSY=>#busy,
            SD:=P#DB10.DBX390.0 INT 32);
#ret:=X_PUT(REQ:=#req,
            CONT:=false,
            DEST_ID:=4,
            VAR_ADDR:=P#DB1.DBX194.0 INT 32,
            BUSY=>#busy,
            SD:=P#DB10.DBX454.0 INT 32);


Damit Req gesetzt wird muss ja der letzte Aufruf busy = 0 setzten. Wenn aber der Aufruf davor mit der Übertragung noch nicht fertig ist dann wird ja der Req nochmal "eins" gesetzt.
Also wie genau das Ganze abläuft ist mir noch nicht ganz klar. ABER ES FUNKT!


Danke
 
Das Ganze funktioniert auch ohne Probleme.
Du kannst Dich bei Siemens bedanken, daß die Firmware der CPUs solch planlos programmierte SFC-Aufrufe geordnet ausführt.


Damit Req gesetzt wird muss ja der letzte Aufruf busy = 0 setzten. Wenn aber der Aufruf davor mit der Übertragung noch nicht fertig ist dann wird ja der Req nochmal "eins" gesetzt.
Also wie genau das Ganze abläuft ist mir noch nicht ganz klar.
Das glaube ich Dir. Anscheinend ist Dir nicht nur nicht klar wie die aufgerufenen SFC funktionieren, noch ist Dir klar was Dein selber drumherum geschriebenes Programm tut.

Dein umständliches "IF #busy = 0 THEN #req:=1; ..." sieht zwar so aus als ob #req nur einen Zyklus lang 1 würde, tatsächlich jedoch ist #req die meiste Zeit lang 1 und nur wärend der letzte X_PUT zur CPU 4 läuft, wird #req = 0. Was die 7 SFC-Aufrufe davor tun hat keinen Einfluß.

Da X_PUT und X_GET keine Flanke zum Kommunikationsanstoß benötigen, könntest Du ebensogut #req fest auf 1 setzen und die Kommunikation würde trotzdem genauso funktionieren. :cool:


Die Frage ist ob man nach der Fehlermeldung "80C0" darauf vertraut, dass die Daten verschickt werden sobald der Bus wieder frei ist.
Der Status 80C0 bedeutet nicht, daß es Buskollisionen gab, sondern daß der Auftrag von der CPU momentan nicht ausgeführt werden kann, weil bei S7-Basiskommunikation generell immer nur 1 Auftrag zu einem Teilnehmer aktiv sein kann.
Dies ist von Siemens mehrfach dokumentiert, u.A. auch bei der Bausteinhilfe der SFCs X_PUT/X_GET/X_...

Die Daten werden nicht automatisch nach Wegfall des Ressourcenengapss verschickt sondern der Kommunikationsauftrag muß erneut ausgelöst werden. Das kann man ebenfalls in der Bausteinhilfe nachlesen. Der Baustein schreibt 80C0 in RET_VAL, schreibt BUSY auf 0 und vergißt den Kommunikationsauftrag.

Schau Dir mal die Step7 Hilfe zu Systemfunktionen/-funktionsbausteinen das Kapitel "Übersicht über die Bausteine der S7-Basiskommunikation" an.
Wenn Sie einen Auftrag angestoßen haben, dann kann die dafür aufgebaute Verbindung momentan nur für diesen einen Auftrag benutzt werden. Andere Aufträge zu demselben Kommunikationspartner können erst dann wieder abgewickelt werden, wenn der laufende Auftrag beendet ist. Beachten Sie daher folgenden Hinweis:

Hinweis
Wenn Ihr Programm mehrere Aufträge zu demselben Kommunikationspartner enthält, müssen Sie dafür Sorge tragen, daß Sie diejenigen SFCs, bei denen W#16#80C0 in RET_VAL angezeigt wird, zu einem geeigneten späteren Zeitpunkt erneut aufrufen.

Die Ausgänge der SFC geben wichtige Informationen zurück, die schmeißt man nicht einfach in einen Sammel-Mülleimer wie bei Deinem Programm - insbesondere darf man nicht ein-und-dieselbe Variable an alle BUSY-Ausgänge aller SFC schreiben wenn man den BUSY-Status auswerten will, denn dann hat die Variable bei der Auswertung immer nur den Zustand vom letzten SFC-Aufruf und allein dieser letzte SFC-Aufruf steuert die Kommunikationsaufträge für alle SFC-Aufrufe gleichzeitg.

Schau Dir mal die Step7 Hilfe zu Systemfunktionen/-funktionsbausteinen das Kapitel "Bedeutung von REQ, RET_VAL und BUSY bei asynchron arbeitenden SFCs" an.


Ich würde selbst für eine Auftrags-Verteilung und Verriegelung sorgen. Für jeden MPI-Teilnehmer getrennt. Jeder SFC-Aufruf braucht seine eigenen REQ- und BUSY-Variablen.

Alternativ:
Sind Deine 3 CPU alle in einem Projekt? Dann könntest Du eine Globaldatenkommunikation einrichten und bräuchtest gar keine Bausteine aufrufen.

Harald
 
Da X_PUT und X_GET keine Flanke zum Kommunikationsanstoß benötigen, könntest Du ebensogut #req fest auf 1 setzen und die Kommunikation würde trotzdem genauso funktionieren. :cool:


Harald

Oh, das ist mir so nicht bewußt gewesen, zumindest für PUT ging ich immer von der Flanke aus, kann aber sein, dass ich das mit anderen Sende-Funktionen durcheinanderwerfe. :? Dachte immer, die bilden selbst eine Flanke intern, also kann man das Signal danach wegnehmen oder anstehen lassen, ganz nach belieben. Würden die Funktionen einen weiteren Sendeauftrag auslösen wenn sie fertig sind und eine 1 an REQ noch immer ansteht??? Ich habe mich immer an dem Siemens-Bsispiel orientiert, also den Auftrag gesetzt und mit NDR oder ERROR zurückgesetzt. (allerdings verwende ich derzeit gerade PUT/GET und X_PUT/X_GET ist doch etwas anders, wie ich gerade sehe :-( )
Wo genau kann man das nachlesen Harald?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja hast recht req ist nicht flanken-gesteuert! Funktioniert auch mit dauer req:=1 genauso. Es war mir schon klar dass das Busy immer wieder nur von der letzten SFC war. Also sollte man das Ganze in einer Schritt-kette mit z.B. 1s Verzögerung aufbauen.
 
ok ich hab das jetzt mit einer Schrittkette gemacht, ab und zu kommt aber trotzdem die Fehlermeldung 80C0. Verstehe noch nicht warum das so ist....wo ist der Fehler?

Code:
IF "Wiederanlauf" THEN
  #sm[0]:=1;
  #sm[1]:=0;
  #sm[2]:=0;
  #sm[3]:=0;
  #sm[4]:=0;
  #sm[5]:=0;
  "Wiederanlauf":=0;
END_IF;


#Timer0(IN:=#sm[0],PT:=T#2s);


IF #sm[0] THEN
  IF NOT #busy0 AND #Timer0.Q THEN
    #req0:=1;
  END_IF;
  IF #busy0 THEN
    #req0:=0;
    #sm[0]:=0;
    #sm[1]:=1;
  END_IF;
END_IF;


#Timer1(IN:=#sm[1],PT:=T#2s);


IF #sm[1] THEN
  IF NOT #busy1 AND #Timer1.Q THEN
    #req1:=1;
  END_IF;
  IF #busy1 THEN
    #req1:=0;
    #sm[1]:=0;
    #sm[2]:=1;
  END_IF;
END_IF;


#Timer2(IN:=#sm[2],PT:=T#2s);


IF #sm[2] THEN
  IF NOT #busy2 AND #Timer2.Q THEN
    #req2:=1;
  END_IF;
  IF #busy2 THEN
    #req2:=0;
    #sm[2]:=0;
    #sm[3]:=1;
  END_IF;
END_IF;


#Timer3(IN:=#sm[3],PT:=T#2s);


IF #sm[3] THEN
  IF NOT #busy3 AND #Timer3.Q THEN
    #req3:=1;
  END_IF;
  IF #busy3 THEN
    #req3:=0;
    #sm[3]:=0;
    #sm[4]:=1;
  END_IF;
END_IF;


#Timer4(IN:=#sm[4],PT:=T#2s);


IF #sm[4] THEN
  IF NOT #busy4 AND #Timer4.Q THEN
    #req4:=1;
  END_IF;
  IF #busy4 THEN
    #req4:=0;
    #sm[4]:=0;
    #sm[5]:=1;
  END_IF;
END_IF;


#Timer5(IN:=#sm[5],PT:=T#2s);


IF #sm[5] THEN
  IF NOT #busy5 AND #Timer5.Q THEN
    #req5:=1;
  END_IF;  
  IF #busy5 THEN
    #req5:=0;
    #sm[5]:=0;
    #sm[0]:=1;
  END_IF;
END_IF;




#ret0:=X_GET(REQ:=#req0,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX0.0 INT 32,
            BUSY=>#busy0,
            RD=>P#DB10.DBX0.0 INT 32);
#ret1:=X_GET(REQ:=#req1,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX64.0 INT 32,
            BUSY=>#busy1,
            RD=>P#DB10.DBX64.0 INT 32);
#ret2:=X_GET(REQ:=#req2,
            CONT:=false,
            DEST_ID:=4,
            VAR_ADDR:=P#DB1.DBX0.0 INT 32,
            BUSY=>#busy2,
            RD=>P#DB10.DBX130.0 INT 32);
#ret3:=X_GET(REQ:=#req3,
            CONT:=false,
            DEST_ID:=4,
            VAR_ADDR:=P#DB1.DBX64.0 INT 32,
            BUSY=>#busy3,
            RD=>P#DB10.DBX194.0 INT 32);
#ret4:=X_PUT(REQ:=#req4,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX130.0 INT 32,
            BUSY=>#busy4,
            SD:=P#DB10.DBX260.0 INT 32);
#ret5:=X_PUT(REQ:=#req5,
            CONT:=false,
            DEST_ID:=3,
            VAR_ADDR:=P#DB1.DBX194.0 INT 32,
            BUSY=>#busy5,
            SD:=P#DB10.DBX324.0 INT 32);
 
Eingangsparameter REQ der SFCs zur S7-Basiskommunikation

Da X_PUT und X_GET keine Flanke zum Kommunikationsanstoß benötigen, könntest Du ebensogut #req fest auf 1 setzen und die Kommunikation würde trotzdem genauso funktionieren. :cool:
Wo genau kann man das nachlesen Harald?
STEP 7 V5.x enthält das Beispielprojekt Com_SFC1 zur S7-Basiskommunikation. Da werden X_PUT und X_GET mit permanentem REQ=1 aufgerufen.

Nachlesen kann man in der Step7 "Hilfe zu Systemfunktionen/-funktionsbausteinen" (SFC-Baustein markieren + F1) und textgleich im Referenzhandbuch "System- und Standardfunktionen für S7-300/400"

Hier mal die relevanten Stellen (rote Markierungen sind von mir):

23.5 Daten in einen Kommunikationspartner außerhalb der eigenen S7-Station schreiben mit der SFC 68 "X_PUT" schrieb:
Die Aktivierung des Schreibvorgangs erfolgt nach Aufruf der SFC mit REQ=1. Anschließend rufen Sie die SFC so lange auf, bis der Quittungsempfang mit BUSY=0 angezeigt wird.

23.1 Gemeinsame Parameter der SFCs der S7-Basiskommunikation schrieb:
Eingangsparameter REQ

Der Eingangsparameter REQ (request to activate) ist ein pegelgetriggerter Steuerparameter. Er dient dazu, den Auftrag (die Datenübertragung bzw. den Verbindungsabbruch) anzustoßen:
  • Wenn Sie die SFC zu einem Auftrag aufrufen, der momentan nicht aktiviert ist, so stoßen Sie mit REQ=1 den Auftrag an. Besteht zum Zeitpunkt des Erstaufrufs einer SFC noch keine Verbindung zum Kommunikationspartner, dann wird diese vor Beginn der Datenübertragung aufgebaut.
  • Wenn Sie einen Auftrag angestoßen haben und dieser noch nicht abgeschlossen ist und Sie die SFC zum gleichen Auftrag erneut aufrufen, so wird REQ durch die SFC nicht ausgewertet.
[...]
Ausgangsparameter RET_VAL und BUSY

Die SFCs der S7-Basiskommunikation sind asynchron laufende SFCs, d. h. die Abwicklung eines Auftrags erstreckt sich über mehrere SFC-Aufrufe. Über die Ausgangsparameter RET_VAL und BUSY wird der Zustand des Auftrags angezeigt. Siehe auch Bedeutung von REQ, RET_VAL und BUSY bei asynchron arbeitenden SFCs
Das heißt: Ob nach dem Auftragsanstoß REQ auf 1 bleibt oder auf 0 zurückgesetzt wird, ist der SFC egal.

2.2 Bedeutung von REQ schrieb:
Eingangsparameter REQ

Der Eingangsparameter REQ (request) dient ausschließlich dem Anstoß des Auftrags:
  • Wenn Sie die SFC zu einem Auftrag aufrufen, der derzeit nicht aktiviert ist, so stoßen Sie mit REQ = 1 den Auftrag an (Fall 1).
  • Ist ein bestimmter Auftrag angestoßen und noch nicht abgeschlossen und Sie rufen die SFC zum gleichen Auftrag erneut auf (z. B. in einem Weckalarm-OB), so wird REQ durch die SFC nicht ausgewertet (Fall 2).
[...]

Ausgangsparameter RET_VAL und BUSY

Über die Ausgangsparameter RET_VAL und BUSY wird der Zustand der Auftragsausführung angezeigt.
[...]
  • Im Fall 1 (Erstaufruf mit REQ=1) wird bei freien Systemressourcen und korrekter Versorgung der Eingansparameter in RET_VAL W#16#7001 eingetragen, und BUSY wird gesetzt.

    Falls die benötigten Systemressourcen momentan belegt sind oder ein Fehler in den Eingangsparametern vorliegt, wird in RET_VAL der zugehörige Fehlercode eingetragen, und BUSY wird mit 0 beschrieben.
  • [...]
  • Beim letzten Aufruf für einen Auftrag gilt:
    • [...]
    • Bei allen anderen SFCs wird bei fehlerfreier Auftragsausführung in RET_VAL 0 eingetragen, und BUSY wird mit 0 beschrieben. Im Fehlerfall wird in RET_VAL der Fehlercode eingetragen, und BUSY wird mit 0 beschrieben.

Hinweis
Falls erster und letzter Aufruf zusammenfallen, gilt für RET_VAL und BUSY das für den letzten Aufruf gesagte.

23.2 Fehlerinformationen der Kommunikations-SFCs für nichtprojektierte S7-Verbindungen schrieb:
Fehlerinformationen
Die in der folgenden Tabelle u. a. angegebenen "echten" Fehlerinformationen für die SFCs 65 bis 74 können Sie wie folgt klassifizieren:
80Cx
Temporärer Fehler
[...]
Spezifische Fehlerinformationen für die SFCs 65 bis 74
[TABLE="class:ilc_table_StandardTable"]
[TR]
[TD]80C0
[/TD]
[TD]Die angegebene Verbindung ist durch einen anderen Auftrag bereits belegt.
[/TD]
[/TR]
[/TABLE]

21.1 Unterschiede zwischen den Bausteinen der S7-Kommunikation und der S7-Basiskommunikation schrieb:
[TABLE="class:ilc_table_StandardTable"]
[TR]
[TD]Kriterium
[/TD]
[TD]S7-Basiskommunikation
[/TD]
[TD]S7-Kommunikation
[/TD]
[/TR]
[TR]
[TD]Mehrere Verbindungen
zu einem
Kommunikationspartner
[/TD]
[TD]Es gibt zu jedem Zeitpunkt maximal
eine Verbindung zu einem
Kommunikationspartner.

[/TD]
[TD]Sie können mehrere Verbindungen zu ein und
demselben Kommunikationspartner aufgebaut
haben.
[/TD]
[/TR]
[/TABLE]

21.4 Übersicht über die Bausteine der S7-Basiskommunikation schrieb:
Verbindung zum Kommunikationspartner
Bei den SFCs der S7-Basiskommunikation wird die Verbindung zur Laufzeit der SFC aufgebaut; je nachdem, welchen Wert Sie dem Eingangsparameter CONT zugewiesen haben, bleibt sie nach dem Abschluß der Datenübertragung bestehen, oder sie wird wieder abgebaut.

  • Falls momentan keine Verbindung zu einem Kommunikationspartner aufgebaut werden kann, weil die Verbindungsressourcen (auf der eigenen CPU oder beim Kommunikationspartner) alle belegt sind, so erhalten Sie dies in RET_VAL angezeigt. Sie müssen dann den Auftrag zu einem geeigneten späteren Zeitpunkt erneut anstoßen. Es kann jedoch nicht garantiert werden, daß der Verbindungsaufbau zu einem späteren Zeitpunkt gelingt. Gegebenenfalls müssen Sie Ihr Programm hinsichtlich der gemeinsamen Verwendung von Verbindungsressourcen überprüfen

Wenn Sie einen Auftrag angestoßen haben, dann kann die dafür aufgebaute Verbindung momentan nur für diesen einen Auftrag benutzt werden. Andere Aufträge zu demselben Kommunikationspartner können erst dann wieder abgewickelt werden, wenn der laufende Auftrag beendet ist. Beachten Sie daher folgenden Hinweis:

Hinweis
Wenn Ihr Programm mehrere Aufträge zu demselben Kommunikationspartner enthält, müssen Sie dafür Sorge tragen, daß Sie diejenigen SFCs, bei denen W#16#80C0 in RET_VAL angezeigt wird, zu einem geeigneten späteren Zeitpunkt erneut aufrufen.

Harald
 
Ich weiß nicht, wie groß die Abweichungen zwischen GET/PUT und X_GET/X_PUT sind, ich spreche somit über GET/PUT. Die Bausteine gehören, wenn sie zur gleichen Verbindung gehören, in eine Schrittkette. DONE vom vorhergehenden ist REQ für den nächsten. Gleichzeitig anstoßen oder dauerhaft anstoßen führt zu dem Status "Warnung: Neuer Auftrag ist unwirksam, da vorangegangener Auftrag noch nicht abgeschlossen ist."
Damit ist auch die Frage beantwortet, ob der selbe Merker als Startsignal funktioniert oder nicht. Wenn man alle Aufrufe gleichzeitig starten möchte, startet zwangsläufig nur der erste, weil danach die Verbindung belegt ist. Ich könnte mir vorstellen, dass es mit geringen Datenmengen funktioniert, weil der Auftrag dann innnerhalb des Aufrufs direkt abgeschlossen wird, aber das habe ich noch nie ausprobiert und würde mich auf keinen Fall darauf verlassen.
Siehe auch: http://support.automation.siemens.com/WW/view/de/65975617
 
Zurück
Oben