TIA Wie behandelt TIA Datentypen an Eingangsbereiche - standard oder optimiert?

maxder2te

Level-3
Beiträge
1.353
Reaktionspunkte
488
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Situation:
Ich muss eine größere Menge Daten (~120 Byte) direkt im EA-Prozessabild deklarieren. Die Daten sind zusammengehörig und ich habe sie folglich als Datentyp deklariert (1 Datentyp, viele Untertypen). Wie TIA das mit den Füllbytes usw. behandelt, habe ich mir angesehen und mein aktuelle E-Mapping passt soweit mal. Die komplette Eingangsstruktur wird nun von einem optimierten FB eingelesen, dekodiert und wiederum in eine Datenstruktur hinausgeschrieben.

Nun die Frage:
Übergibt man strukturierte Datentypen an einen FB oder FC, wird ja im Leitfaden empfohlen, diese als INOUT zu übergeben (was ja Sinn macht). Übergebe ich die Eingangsvariable (Start I1320.0, Länge 120 Bytes) an den optimierten FB über einen INOUT, wird dann der Inhalt der Variable kopiert oder ein Zeiger übergeben?

Meines Erachtens nach behandelt die Steuerung E- und A-Adressen wie nicht optimierte Speicherstellen, weshalb es dann zu einem IN-Kopieren und einem OUT-kopieren kommen würde. Schreiben auf IN-Variablen zugreifen ist aber hässlich.
Sauberer wäre in diesem Fall die Übergabe der Eingangsvariable als IN-Parameter.

Was meint ihr dazu? Der Leitfaden macht hierzu ja keine Aussage.

lg


PS: Ich hoffe ich habe mich verständlich genug ausgedrückt.
 
Aus dem Eintrag hier kann man sich einige Infos rauslesen.
https://support.industry.siemens.com/cs/de/de/view/109011420/71500818699

In den Tabelle "Parameterübergabe bei S7-1200/1500" siehst du wie die 1200/1500 das im generellen handelt.
Grundsätzlich werden strukturierte Datentypen also sowohl bei FB als auch FC als Referenz am INOUT übergeben.
Eine Ausnahme für EA-Bereiche steht hier nicht dabei, bei der Tabelle weiter unten für die 300 ist diese Ausnahme extra angeführt.

Unter der Tabelle für die 1500 steht noch dass, wenn optimierte Daten an einen nicht optimierten Baustein übergeben werden, sich die Abhandlung auf Kopie ändert.
Hier werden aber nicht optimierte Daten (EA) an einen optimierten FB/FC übergeben, sollte also nicht zutreffen.
Demnach müsste die Struktur als Referenz übergeben werden.

Wenn ich aber einen kleinen Test mache...
UDT ab E0.0 angelegt, an einen optimierten FC als INOUT übergeben und in eine CPU ohne gesteckte EA-Karten geladen.
Wenn ich jetzt im Programm außerhalb des FC-Aufrufes den E0.0 im Prozessabbild beeinflusse (Zuweisung) dann kommt das im FC über den UDT an.
Wenn ich aber den E0.0 innerhalb des FC auf TRUE zuweise, dann kommt die Änderung nicht im UDT innerhalb des FCs an und nach dem Verlassen des FC ist der E0.0 wieder FALSE.
Sieht also tatsächlich so aus als würde der E0.0 am Ende des FC-Aufrufs mit den Inhalten der Struktur überschrieben.

Das würde auf eine Übergabe als Kopie hindeuten, würde mir selbst auch logischer vorkommen.
Vielleicht ist die Beschreibung im dem Support-Artikel nicht komplett oder ich hab's nicht richtig verstanden.

Die Frage ist nur, warum willst du einen E-Bereich an einen INOUT anhängen, hier wäre ein reiner IN doch sinnvoller. Einen Vorteil durch INOUT würdest du ja nicht bekommen...
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Aus dem Eintrag hier kann man sich einige Infos rauslesen.
https://support.industry.siemens.com/cs/de/de/view/109011420/71500818699

In den Tabelle "Parameterübergabe bei S7-1200/1500" siehst du wie die 1200/1500 das im generellen handelt.
Grundsätzlich werden strukturierte Datentypen also sowohl bei FB als auch FC als Referenz am INOUT übergeben.
Eine Ausnahme für EA-Bereiche steht hier nicht dabei, bei der Tabelle weiter unten für die 300 ist diese Ausnahme extra angeführt.

Unter der Tabelle für die 1500 steht noch dass, wenn optimierte Daten an einen nicht optimierten Baustein übergeben werden, sich die Abhandlung auf Kopie ändert.
Hier werden aber nicht optimierte Daten (EA) an einen optimierten FB/FC übergeben, sollte also nicht zutreffen.
Demnach müsste die Struktur als Referenz übergeben werden.
Das ist alles soweit bekannt, steht ganz eindeutig im Programmierleitfaden S7-1200/1500 drinnen.

Mir ging es aber um eine Aussage, wie der Compiler den %I-Bereich behandelt - optimiert oder nicht optimiert.



Wenn ich aber einen kleinen Test mache...
UDT ab E0.0 angelegt, an einen optimierten FC als INOUT übergeben und in eine CPU ohne gesteckte EA-Karten geladen.
Wenn ich jetzt im Programm außerhalb des FC-Aufrufes den E0.0 im Prozessabbild beeinflusse (Zuweisung) dann kommt das im FC über den UDT an.
Wenn ich aber den E0.0 innerhalb des FC auf TRUE zuweise, dann kommt die Änderung nicht im UDT innerhalb des FCs an und nach dem Verlassen des FC ist der E0.0 wieder FALSE.

Dein Versuch bestätigt, dass die Variablen aus dem %I-Bereich bei der INOUT-Übergabe in den Baustein hinein kopiert werden.
Nach dem Beenden des FC passiert aber eigentlich so gesehen was inkonsequentes, denn das Herauskopieren unterbleibt.

Es macht zwar prinzipiell Sinn, dass auf diese Weise %I-Bereiche nicht überschrieben werden, das Verhalten passt allerdings zu im Leitfaden beschriebenen Variante und ist daher meiner Meinung nach als "undefiniert" anzusehen, weshalb ich das so nicht einsetzen werde.


Das würde als auf einen Übergabe als Kopie hindeuten, würde mir selbst auch logischer vorkommen.
Vielleicht ist die Beschreibung im dem Support-Artikel nicht komplett oder ich hab's nicht richtig verstanden.

Die Beschreibung ist schlicht nicht komplett. Danke auf jeden Fall für den Kurztest, sobald meine Laborhardware wieder frei ist werde ich da mal umfangreichere Versuche dazu machen.
 
Nach dem Beenden des FC passiert aber eigentlich so gesehen was inkonsequentes, denn das Herauskopieren unterbleibt.
Das hab ich jetzt nicht verstanden.
Wenn ich aber den E0.0 innerhalb des FC auf TRUE zuweise, dann kommt die Änderung nicht im UDT innerhalb des FCs an und nach dem Verlassen des FC ist der E0.0 wieder FALSE.
Das würde doch bedeuten dass der E0.0 bei dem Versuch zwar im FC mittels Zuweisung auf TRUE gesetzt wird, kann im FC auch als TRUE zurückgelesen werden, nach dem Verlassen aber durch das zurückkopieren des als Kopie übergebenen UDT wieder überschrieben wird und nach dem Ablauf des FC (außerhalb) dann mit FALSE zurückgelesen wird.
Das erscheint mir wie erwartet für eine INOUT-Übergabe als Kopie.
 
Zuletzt bearbeitet:
Wenn ich aber den E0.0 innerhalb des FC auf TRUE zuweise, dann kommt die Änderung nicht im UDT innerhalb des FCs an und nach dem Verlassen des FC ist der E0.0 wieder FALSE. Sieht also tatsächlich so aus als würde der E0.0 am Ende des FC-Aufrufs mit den Inhalten der Struktur überschrieben.

Das nicht hatte ich überlesen. Das von dir beschriebene Verhalten ist für mich noch unlogischer.

Ich versuche das mal an einem konkreten Beispiel durchzuexerzieren (im Pseudocode)

Code:
UDT "typeData"
  a : INT;
  b : INT;
  c : DINT;
  d0 : BOOL;
  d1 : BOOL;
  d2 : BOOL;
  d3 : BOOL;
  d4 : BOOL;
  d5 : BOOL;
  d6 : BOOL;
  d7 : BOOL;
  d8 : BOOL;
  d9 : BOOL;
  d10 : BOOL;
  d11 : BOOL;
  d12 : BOOL;
  d13 : BOOL;
  d14 : BOOL;
  d15 : BOOL;
END_UDT;

Ich lege nun im Eingangs-PE eine Variable data ab %I0.0 vom Type typeData an, d.h. "data".a = %IW0, "data".d0 = %I8.0, usw.
Diese Variable wird nun einem optimierten FC als INOUT-Variable idata mit übergeben.

Ich erwarte folgendes Verhalten (egal, ob optimiert oder nicht optimiert):
  1. %I8.0 außerhalb auf TRUE setzen --> #idata.d0 = TRUE innerhalb des FC, "data".d0 = TRUE nach dem FC-Aufruf
  2. FC mit %I8.0 = FALSE aufrufen --> #idata.d0 = FALSE innerhalb des FC, "data".d0 = FALSE nach dem FC-Aufruf
  3. FC mit %I8.0 = FALSE aufrufen, innerhalb des FC #idata.d0 auf TRUE setzen --> #idata.d0 = TRUE nach dem Setzen innerhalb des FC, "data".d0 = TRUE nach dem FC-Aufruf


Deine Beobachtung deckt sich aber nicht mit dem Beschriebenen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Da bin ich bei allen 3 Fällen bei dir, passt schon.
Ich hatte oben folgenden Fall, wenn auch wahrscheinlich zu lang und missverständlich, beschrieben...

(Annahme aus deinem Beispiel: %I8.0 ist der Eingang selbst, #data.d0 das Pendant von %I8.0 über UDT-Deklaration, #idata ist der INOUT an der Schnittstelle)


  • %I8.0 ist vor dem Aufruf FALSE
  • Beim Aufruf wird #data als Kopie #idata an den FC übergeben und in der CPU vom Compiler zwischengespeichert.
    In diesem Moment hat #idata.d0 entsprechend %I8.0 den Wert FALSE
  • Im FC setze ich jetzt aber %I8.0 auf TRUE (nicht #idata.d0).
  • Da #idata.d0 keine Referenz auf #data.d0 sondern eine Kopie ist bleibt #idata.d0 unbeeinflusst und weiterhin auf FALSE.
    %I8.0 kann ich im FC ab diesem Moment als TRUE zurücklesen (habe es ja gerade geschrieben)
  • Beim Verlassen des FC wird der Inhalt von #idata.d0 über den am INOUT verschaltenen Parameter #data wieder auf %I8.0 zurückgeschrieben.
    %I8.0 das ich im FC auf TRUE gesetzt hatte wird damit also wieder auf FALSE (Wert der Kopie #data.d0) überschrieben.
  • Nach dem Aufruf des FC ist sowohl #data.d0 als auch %I8.0 FALSE.

Das hatte ich so beobachtet, wie erwartet für die INOUT-Übergabe als Kopie.
Ebenfalls die drei Fälle die du beschrieben hattest.
 
Zuletzt bearbeitet:
  • Im FC setze ich jetzt aber %I8.0 auf TRUE (nicht #idata.d0).

Diesen Konnex konnte ich nicht herstellen ;) Danke für die Antworten und danke fürs Austesten. Eigentlich schade dass die Tatsache, dass E/A/M-Bereiche als nicht-optimiert behandelt werden nicht explizit im Leitfaden steht - wäre doch eine Ergänzung wert, oder @S? :ROFLMAO:

Also zusammenfassend:
Die Bereiche %M, %I und %Q (Merker, Eingänge, Ausgänge) werden wie DBs mit Standard-Zugriff behandelt.
 
Zurück
Oben