Step 7 Mehrere Hintergrund-FB-Blöcke

larry

Level-2
Beiträge
28
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Im FB-Block mit mehreren Hintergründen übergibt INOUT einen db-Zeiger als praktisches Argument, im FB-Block mit mehreren Hintergründen, warum die Daten im XS_Status in den TS_Status kopiert werden, TS_Status im Programm verwenden, am Ende des Programms TS_Status nach XS_Status kopieren,Vielen Dank
 

Anhänge

  • copy XS_Status to TS_Status.png
    copy XS_Status to TS_Status.png
    23,7 KB · Aufrufe: 58
  • FB.png
    FB.png
    8,6 KB · Aufrufe: 56
  • TS_Status.png
    TS_Status.png
    33,4 KB · Aufrufe: 51
  • XS_Status.png
    XS_Status.png
    34,1 KB · Aufrufe: 56
Im FB-Block mit mehreren Hintergründen
Was meinst du mit "Hintergründen"? Ist das ein Übersetzungsfehler zu "Deutsch"? Kannst du deine Frage vielleicht besser in englisch formulieren?

In dem Code sollen ein Pointer und ein ANY-Pointer umkopiert werden, was der AWL-Compiler nicht "automatisch" kann und manuell programmiert relativ kompliziert ist, weil in multiinstanzfähigen FB der Multiinstanz-Offset aus AR2 zu Adressen in der IDB-Instanz addiert werden muss, und der Inhalt von AR2 und DINO nicht (bzw. nur temporär) verändert werden dürfen, wenn man noch auf Variablen in der IDB-Instanz zugreifen will.

warum die Daten im XS_Status in den TS_Status kopiert werden, TS_Status im Programm verwenden, am Ende des Programms TS_Status nach XS_Status
Weil es einfacher und effizienter ist, auf Variablen im lokalen TEMP-Speicher (TS_...) zuzugreifen, als auf IN_OUT-Parameter im Multiinstanz-IDB (XS_...). Deshalb wird der UDT aus dem IN_OUT-Parameter XS_Status nach TEMP kopiert und im Programm dann mit der Kopie TS_Status gearbeitet. Wenn Werte in der TEMP-Kopie TS_Status geändert werden, dann muss die geänderte Kopie am Ende des FB auch wieder in den IN_OUT-Parameter XS_Status zurückkopiert werden.

Auf Variablen eines UDT in TEMP kann symbolisch zugegriffen werden z.B. #XS_Status.Op27. Vermutlich werden im Programm auch Tricks bei der Adressierung in den TEMP-Speicher (L...) gemacht, deshalb darf die Variable XS_Status nicht auf andere TEMP-Adressen verschoben werden "do NOT move from the address ..."
 
Was meinst du mit "Hintergründen"? Ist das ein Übersetzungsfehler zu "Deutsch"? Kannst du deine Frage vielleicht besser in englisch formulieren?

In dem Code sollen ein Pointer und ein ANY-Pointer umkopiert werden, was der AWL-Compiler nicht "automatisch" kann und manuell programmiert relativ kompliziert ist, weil in multiinstanzfähigen FB der Multiinstanz-Offset aus AR2 zu Adressen in der IDB-Instanz addiert werden muss, und der Inhalt von AR2 und DINO nicht (bzw. nur temporär) verändert werden dürfen, wenn man noch auf Variablen in der IDB-Instanz zugreifen will.


Weil es einfacher und effizienter ist, auf Variablen im lokalen TEMP-Speicher (TS_...) zuzugreifen, als auf IN_OUT-Parameter im Multiinstanz-IDB (XS_...). Deshalb wird der UDT aus dem IN_OUT-Parameter XS_Status nach TEMP kopiert und im Programm dann mit der Kopie TS_Status gearbeitet. Wenn Werte in der TEMP-Kopie TS_Status geändert werden, dann muss die geänderte Kopie am Ende des FB auch wieder in den IN_OUT-Parameter XS_Status zurückkopiert werden.

Auf Variablen eines UDT in TEMP kann symbolisch zugegriffen werden z.B. #XS_Status.Op27. Vermutlich werden im Programm auch Tricks bei der Adressierung in den TEMP-Speicher (L...) gemacht, deshalb darf die Variable XS_Status nicht auf andere TEMP-Adressen verschoben werden "do NOT move from the address ..."
Thank you very much for your doubts, I don't know much German, and your explanation is very much in line with the meaning of the program
The problem is this: the INOUT of all fb of the project, set a DB pointer argument, and use the XS_Status parameter in the FB program to indirectly save the data of 50 consecutive BOOL pointed by the DB pointer to the temporary variable area TS_Status, and only use the data in the TS_Status in the FB program, and then save the data in the TS_Status to the DB block pointed to by the DB pointer in the XS_Status,

Is this ease and efficiency of your explanation only theoretical? Now the performance of the PLC to consider this aspect of efficiency? Or is it the rigor and efficiency that the author considers when writing the program?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Is this ease and efficiency of your explanation only theoretical? Now the performance of the PLC to consider this aspect of efficiency? Or is it the rigor and efficiency that the author considers when writing the program?
In FB it actually makes a big difference whether variables are accessed in TEMP or IN_OUT.

Code:
// FB / XS_Status in IN_OUT / TS_Status in TEMP

A #XS_Status.Bool1   //  Code size 42 bytes
= #XS_Status.Bool2   //  Code size 42 bytes

A #TS_Status.Bool1   //  Code size 4 bytes
= #TS_Status.Bool2   //  Code size 4 bytes

Accessing 50 variables in TEMP is 200 bytes of code size
Accessing 50 variables in IN_OUT is 2100 bytes of code size


Im FB egal ob Zugriff auf IN/OUT/STAT oder TEMP: 4 Byte
Zugriff auf eine Variable in einem UDT an IN_OUT: 26 Byte bei SCL-Quelle bzw. 42 Byte bei KOP/FUP/AWL-Quelle
Auch deshalb ist es oft sinnvoll, UDT zur Verarbeitung zuerst von IN_OUT in TEMP zu kopieren.
erhöhter Codebedarf für Hidden-Adressberechnung

Das liegt daran, daß alle Datentypen größer 4 Byte nicht als call_by_value sondern als call_by_reference übergeben werden,
d.h. es wird nicht der Wert der Variablen (als Kopie) übergeben, sondern die Adresse der Original-Variablen.
Das ist in Step7 leider nicht so deutlich sichtbar wie z.B. in C, das muß man halt wissen.

Weil dadurch die Adresse der übergebenen Variablen zur Compilierzeit nicht bekannt ist, muß der Baustein die Adresse der Variablen
zur Laufzeit auflösen und in ein AR-Register laden, um danach den Wert der Variablen indirekt zu lesen.
 
In FB it actually makes a big difference whether variables are accessed in TEMP or IN_OUT.

Code:
// FB / XS_Status in IN_OUT / TS_Status in TEMP

A #XS_Status.Bool1   //  Code size 42 bytes
= #XS_Status.Bool2   //  Code size 42 bytes

A #TS_Status.Bool1   //  Code size 4 bytes
= #TS_Status.Bool2   //  Code size 4 bytes

Accessing 50 variables in TEMP is 200 bytes of code size
Accessing 50 variables in IN_OUT is 2100 bytes of code size
erhöhter Codebedarf für Hidden-Adressberechnung


Das liegt daran, daß alle Datentypen größer 4 Byte nicht als call_by_value sondern als call_by_reference übergeben werden,
d.h. es wird nicht der Wert der Variablen (als Kopie) übergeben, sondern die Adresse der Original-Variablen.
Das ist in Step7 leider nicht so deutlich sichtbar wie z.B. in C, das muß man halt wissen.

Weil dadurch die Adresse der übergebenen Variablen zur Compilierzeit nicht bekannt ist, muß der Baustein die Adresse der Variablen
zur Laufzeit auflösen und in ein AR-Register laden, um danach den Wert der Variablen indirekt zu lesen.
Soweit ich mich erinnere, sind das bei jedem Zugriff etwa 42 Byte mehr Code als ein Zugriff auf Variablen im TEMP- oder STAT-Bereich.

Vorsicht!
Egal, ob die Struktur als IN, IN_OUT oder OUT übergeben wird, kann auf Variablen der Struktur geschrieben werden.
Dabei wird die Original-Variable verändert! Der Step7-Editor/Compiler verhindert das nicht!

Gruß Harald
Dann verstehe ich aber in diesem Fall den Größenunterschied nicht. Das sind doch BOOL und die sind doch ein Byte groß.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Egal wie groß die Variable ist, der Aufwand der Adressierung der Variable macht die Codegröße.
Hier im Beispiel werden Bool als Teil von Strukturen/UDT in IN_OUT übergeben. Daher der exorbitante Aufwand für die indirekte Adressierung.
Das mit den Strukturen habe ich übersehen, die sind dann ja größer als 4 Byte.
 
der exorbitante Aufwand für die indirekte Adressierung
• Zunächst muss die Adresse des IN_OUT-Parameters in der Multiinstanz ermittelt werden:
.. bekannter Offset des Parameters innerhalb der Instanz + Multiinstanzoffset aus AR2
• nun muss indirekt die übergebene Adresse des Aktualparameters aus dem IN_OUT-Parameter gelesen werden:
.. Anfangsadresse der Struktur (--> in AR1 und ggf. DB-Nummer)
• nun muss wieder indirekt der Wert der Variable aus der übergebenen Struktur gelesen werden:
.. Anfangsadresse der Struktur (in AR1) + bereits zur Compilierzeit bekannter Offset der Variable innerhalb der Struktur: A [AR1,P#x.y]
 
Heisst das wenn man DB Inhalte in TIA verschieben will in einen anderen DB, ist man mit einer UDT-Variable immer auf der sicheren Seite?
Man packt dann den ganzen Datensatz in einen UDT und dann in einen globalen DB.
Sind Quelle und Ziel gleich funktioniert das.
Habe ich ein Array aus diesem Datentyp UDT funktioniert es ebenfalls?Ist das so richtig?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Heisst das wenn man DB Inhalte in TIA verschieben will in einen anderen DB, ist man mit einer UDT-Variable immer auf der sicheren Seite?
Man packt dann den ganzen Datensatz in einen UDT und dann in einen globalen DB.
Sind Quelle und Ziel gleich funktioniert das.
Hmm, ich verstehe jetzt nicht den Zusammenhang deiner Frage mit dem Thema hier...
Aber ja, es ist guter Programmierstil, wenn man strukturierte Daten in UDT (User-Datentypen) verpackt und so symbolisch übergibt und kopiert. Dann kann der Compiler die Verwendung der korrekten Datentypen überprüfen und den effizientesten Code für das kopieren erzeugen. Der Programmierer muss sich da nicht um die Details des Kopierens kümmern.

Habe ich ein Array aus diesem Datentyp UDT funktioniert es ebenfalls?Ist das so richtig?
ja
 
Zurück
Oben