Das Adressregister - tolle Sache, aber was gibt es zu beachten

LittleJack86

Level-1
Beiträge
44
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Erst mal einen guten Morgen!

Ich habe schon öfter gelesen, dass es bei der Verwendung der Adressregister notwendig ist, zuvor ihren Inhalt zu sichern und nach der Verwendung den Inhalt wieder herzustellen.
Nur wann sollte man dies machen? Nur bei der Verwendung in Multiinstanzen?
Weiters, bei der indirekten Adressierung in Multiinstanzen muss man ja einen Versatz, welcher im AR2 steht, mit einbeziehen, oder?

Was gibt es denn generell und bei spezielleren Anwendungen (z.B. Multiinstanz) der Adressregister zu beachten?

Schon mal vielen Dank für die Info!
Flo
 
Nur wann sollte man dies machen? Nur bei der Verwendung in Multiinstanzen?
Zuerst einmal muss man unterscheiden: Die S7 hat zwei Adressregister, sinnigerweise Adressregister 1 (AR1) und Adressregister 2 (AR2) genannt.
AR1 wird vom System nicht verwendet und kann vom Benutzer immer frei verwendet werden, auch in FBs und sogar in Multiinstanzen. Wenn man AR1 verwendet, muss man den Inhalt vorher nicht sichern.
Bei AR2 ist das anders und damit zu Deiner zweiten Frage:
Weiters, bei der indirekten Adressierung in Multiinstanzen muss man ja einen Versatz, welcher im AR2 steht, mit einbeziehen, oder?
In einem FB steht in AR2 der Versatz, ab welcher Adresse die Daten für den aktuellen Aufruf im IDB stehen. Wenn es sich nicht um einen Multiinstanz-Aufruf handelt und der FB seinen eigenen IDB hat, steht hier also P#0.0. Bei einem Multiinstanz-Aufruf ändert sich das entsprechend.
Bei jedem symbolischen Zugriff auf den IDB (also jeder Zugriff auf IN, OUT INOUT oder STAT) wird das AR2 zur Adresse im Variablendeklarationsteil des Bausteins dazugezählt, auch bei nicht-Multiinstanz-Aufrufen. Wenn man also mit dem AR2 in einem FB arbeitet (was man vermeiden sollte), dann muss man vorher den Inhalt sichern und vor dem nächsten symbolischen Zugriff auf den IDB wieder zurückschreiben, da sonst die Zugriffe verschoben sind.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In einem FB steht in AR2 der Versatz, ab welcher Adresse die Daten für den aktuellen Aufruf im IDB stehen. Wenn es sich nicht um einen Multiinstanz-Aufruf handelt und der FB seinen eigenen IDB hat, steht hier also P#0.0. Bei einem Multiinstanz-Aufruf ändert sich das entsprechend.
Bei jedem symbolischen Zugriff auf den IDB (also jeder Zugriff auf IN, OUT INOUT oder STAT) wird das AR2 zur Adresse im Variablendeklarationsteil des Bausteins dazugezählt, auch bei nicht-Multiinstanz-Aufrufen. Wenn man also mit dem AR2 in einem FB arbeitet (was man vermeiden sollte), dann muss man vorher den Inhalt sichern und vor dem nächsten symbolischen Zugriff auf den IDB wieder zurückschreiben, da sonst die Zugriffe verschoben sind.

Damit ich das jetzt richtig verstehe:
Also wenn ich in einem FB (egal ob Multi oder nicht) symbolisch auf den IDB zugreife, wird IMMER AR2 zur Adresse hinzugezählt. Soweit mal richtig?

Dies ändert nur in einem NICHT Multi-FB nichts an der Adresse, da AR2 NULL ist.
Wenn ich aber in einem Multiinstanzaufruf größer als dem ersten Aufruf bin, so steht im AR2 der Versatz bis zum jeweiligen Datenbereich im IDB, welcher beim symbolischen Zugriff auf den IDB mit eingerechnet wird.

Das Hinzurechnen geschieht allerdings automatisch von der Steuerung. In welchen Fällen muss dieser Versatz dann von mir aktiv berücksichtigt werden? Wenn ich z.B. mit LB auf den Lokal-Datenbereich zugrefen möchte?

Wenn ich also nicht direkt den Inhalt des AR2 überschreibe (z.B. mit LAR2) dann brauche ich es auch nicht zu sicher? oder kann ich es auch anderwertig überschreiben?
Und das AR1 kann ich auch immer ändern ohne es zu sichern?
 
Damit ich das jetzt richtig verstehe:
Also wenn ich in einem FB (egal ob Multi oder nicht) symbolisch auf den
IDB zugreife, wird IMMER AR2 zur Adresse hinzugezählt. Soweit mal richtig?
Ja.
Dies ändert nur in einem NICHT Multi-FB nichts an der Adresse, da AR2
NULL ist.
Wenn es nicht geändert wurde.
Wenn ich aber in einem Multiinstanzaufruf größer als dem ersten Aufruf bin,
so steht im AR2 der Versatz bis zum jeweiligen Datenbereich im IDB,
welcher beim symbolischen Zugriff auf den IDB mit eingerechnet wird.
Fast richtig. Wenn der aufrufende FB eigene Variable mitbringt, beginnt der erste Aufruf nicht bei Adresse 0.0.
Das Hinzurechnen geschieht allerdings automatisch von der Steuerung.
Ja.
In welchen Fällen muss dieser Versatz dann von mir aktiv berücksichtigt werden? Wenn ich z.B. mit LB auf den Lokal-Datenbereich zugrefen möchte?
Nein. Mit LB greifst Du immer auf die temporären Lokaldaten zu. Aber wenn Du z.B. mit L DIW xx auf die jeweilige Instanz zugreifen möchtest, musst Du den Versatz berücksichtigen.
Wenn ich also nicht direkt den Inhalt des AR2 überschreibe (z.B. mit LAR2) dann brauche ich es auch nicht zu sicher? oder kann ich es auch anderwertig überschreiben?
Wenn Du das AR2 nicht veränderst, musst Du es auch nicht sichern.
Und das AR1 kann ich auch immer ändern ohne es zu sichern?
Ja.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Alle Register werden systemseitig verwendet!

Alle Register (AR1, AR2, DB- und DI-Register, Akkus) werden je nach Situation systemseitig verwendet!
Das kann man sehr leicht in der Step7-Hilfe und den diversen Step7-Programmierhandbüchern nachlesen.

Die Step7-Hilfe > Hilfethemen... > Index: Adressregister ergibt folgenden informativen Beitrag:
Hinweise zur Änderung von Register-Inhalten

Wenn Sie die im Anschluss beschriebenen Programmiermöglichkeiten und gleichzeitig die genannten Register/Akkus nutzen, müssen Sie selbst für eine Wiederherstellung der Register- bzw. Akku-Inhalte sorgen, da es sonst zu einem Fehlverhalten kommen kann.

Die Verwendung der folgenden höheren Sprachkonstrukte kann dazu führen, dass die Inhalte von DB-Register und Adressregister AR1 verändert werden:
  • vollqualifizierter DB-Zugriff (z.B. DB20.DBW10) als Aktualparameter für FC
  • FB- und Multiinstanz-CALL
  • Strukturkomponente eines Formalparameters als Operand innerhalb eines FC oder FB
  • Strukturkomponente eines Formalparameters als Aktualparameter für FC oder FB
Beim FB-, FC-, Multiinstanz-CALL dürfen VKE oder AKKU1 und AKKU2 nicht als zusätzliche (implizite) Parameter verwendet werden.

Das DI-Register und das Adressregister AR2 werden systemseitig für den FB- und Multiinstanz-CALL verwendet und dürfen deshalb innerhalb von FB's nicht verändert werden.

Das Adressregister AR1 wird von einem Teil der ladbaren Standardbausteine verwendet.

Der Befehl "L P#Parametername" lädt innerhalb eines FB den Adressoffset des angegebenen Parameters, relativ zum Adressregister AR2. Um in multiinstanzfähigen FBs den absoluten Offset im Instanzdatenbaustein zu ermitteln, muss zu diesem Wert noch der bereichsinterne Zeiger (nur Adresse) des AR2-Registers addiert werden.

Weitere Information zu den Registern der CPU finden Sie in der Hilfe zur Programmiersprache (KOP/FUP/AWL).

Siehe auch:
Vermeiden von Fehlern beim Aufrufen von Bausteinen
Der Hilfe-Beitrag "Vermeiden von Fehlern beim Aufrufen von Bausteinen" beschreibt noch ausführlicher die Situationen, in denen Register modifiziert werden.

Harald
 
  • vollqualifizierter DB-Zugriff (z.B. DB20.DBW10) als Aktualparameter für FC
  • FB- und Multiinstanz-CALL
  • Strukturkomponente eines Formalparameters als Operand innerhalb eines FC oder FB
  • Strukturkomponente eines Formalparameters als Aktualparameter für FC oder FB
Wenn ich mich nicht irre, sind das alles Sachen, die nur das DB-Register oder das AR2 ändern. Welches davon ändert das AR1? Oder ist da womöglich ein Schreibfehler in der Überschrift?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Alle Register (AR1, AR2, DB- und DI-Register, Akkus) werden je nach Situation systemseitig verwendet!
Das kann man sehr leicht in der Step7-Hilfe und den diversen Step7-Programmierhandbüchern nachlesen.

Hallo,
also die Hilfe dazu kenne ich, die habe ich auch gelesen, allerdings nicht so wirklich verstanden. Weshalb ich diesen Betrag begonnen habe.

Ich würd an dieser Stelle aber gerne darauf eingehen:



  • vollqualifizierter DB-Zugriff (z.B. DB20.DBW10) als Aktualparameter für FC
Was soll das genau bedeuten?



  • FB- und Multiinstanz-CALL
..ist mir jetzt glaube ich klar



  • Strukturkomponente eines Formalparameters als Operand innerhalb eines FC oder FB
  • Strukturkomponente eines Formalparameters als Aktualparameter für FC oder FB
...und da weiß ich auch nicht so recht was denn gemeint ist.
 
Was soll das genau bedeuten?.
z.B. DB20.DBW10 als IN, INOUT oder OUT-Parameter eines FC (ändert das DB-Register)
..ist mir jetzt glaube ich klar.
...und da weiß ich auch nicht so recht was denn gemeint ist.
Wenn Du eine Struct als FB- oder FC-Parameter angibst, ändert sich jedesmal, wenn Du auf einen Teil davon zugreifst, das AR1, Du musst also in diesem Fall darauf aufpassen, dass ein evtl. von Dir dort hinterlegter Wert nicht überschrieben wird.
 
D
Das Hinzurechnen geschieht allerdings automatisch von der Steuerung. In welchen Fällen muss dieser Versatz dann von mir aktiv berücksichtigt werden? Wenn ich z.B. mit LB auf den Lokal-Datenbereich zugrefen möchte?

Mann kann dies schön sehen wenn man sich den MC7 Code der auf der Steuerung ist wieder in AWL zurückwandelt:

aus z.b.:

Code:
      U     #INIT
      R     #TRIGGERABRUCH_GESENDET
      R     #TRIGGER_GESENDET

wird dann:

Code:
      U     DIX[AR2,P#8.1]
      R     [AR2,P#64.3]  
      R     [AR2,P#64.2]

und aus zugriffen an höhren adressen wird (bb liegt bei 60000)

Code:
     L    #bb

wird

Code:
      TAR2  LD0           
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      L     DIW[AR2,P#2740.0]
      LAR2  LD0
 
Zuviel Werbung?
-> Hier kostenlos registrieren
z.B. DB20.DBW10 als IN, INOUT oder OUT-Parameter eines FC (ändert das DB-Register)
...also so geschrieben ist mir das eh klar, ändert aber NUR das DB-Register.
Noch was dazu, der übergebene Wert z.B. DB20.DBW10 als INOUT-Parameter wird aber beim Aufruf des FC in den Temporären bereich übergeben und ändert somit nur direkt beim aufruf des FC das DB-Register, oder wird das DB-Register immer geändert sobald ich im FC diese Variable anspreche? (habe ich eigentlich noch nie so in einem FC verwendet)

Wenn Du eine Struct als FB- oder FC-Parameter angibst, ändert sich jedesmal, wenn Du auf einen Teil davon zugreifst, das AR1, Du musst also in diesem Fall darauf aufpassen, dass ein evtl. von Dir dort hinterlegter Wert nicht überschrieben wird.
kannst du mir dazu ein kurzes Bespiel geben? Dass ist mir noch nicht ganz verständlich.
 
Kleine Abschwächung:
Im Gegensatz zum AR2 muß man AR1 nicht vor der Verwendung für das System sichern und wiederherstellen.
Das System erwartet keinen bestimmten Inhalt im AR1. Wenn es AR1 verwendet, dann initialisiert es das AR1 auch jedesmal selbst.

Man muß nur aufpassen wenn man selbst AR1 verwendet (z.B. in einer Schleife!) und eine der 4 genannten Situationen hat. Dann muß man damit rechnen, daß das System rücksichtslos "meinen" AR1-Inhalt verändert hat. Man muß den eigenen AR1-Inhalt selber vor dem System retten.

@LittleJack86
"vollqualifizierter DB-Zugriff" ist, wenn in der Zugriffsadresse die DB-Nummer mit enthalten ist: L DB20.DBW10
Dann macht das System bei jedem Zugriff implizit ein AUF DBxx.
L DBW10 ohne Angabe der DB-Nummer ist ein "unqualifizierter" DB-Zugriff auf den gerade (zufällig?!) geöffneten DB.

"Strukturkomponente eines Formalparameters"
Wenn z.B. eine Struktur an einen FC oder FB übergeben wird, dann wird tatsächlich nur die Anfangsadresse als Pointer übergeben. Wenn nun innerhalb der FC oder FB auf ein Element der übergebenen Struktur zugegriffen wird, dann muß "das System" selber indirekt adressieren. D.h. in etwa: AR1 wird mit dem übergebenen Pointer geladen und zeigt damit auf den Anfang der Struktur, für den Zugriff auf ein Element wird dann noch der bekannte Offset zum AR1 adressiert.
Wenn die übergebene Struktur aus einem DB stammt (was fast immer der Fall ist), dann muß auch das DB-Register für den indirekten Zugriff auf die Struktur vom System verwendet werden. Das DB-Register enthält nach dem Zugriff die DB-Nummer der übergebenen Struktur.
Diese normalerweise nicht sichtbaren indirekten Zugriffe auf Strukturkomponenten verbrauchen übrigens unheimlich viel Programmspeicher für die Adressberechnung, ich meine das waren je Zugriff ca. 42 Byte Code. Deshalb sollte man bei Übergabe von Strukturen diese vor der Verwendung zuerst in die temporären Lokaldaten umkopieren und dann auf diese lokale Kopie zugreifen.

Harald
 
Jetzt ist mir das Ganze schon viel besser verständlich.
Einmal Danke an alle für eure Antworten!

@Jochen Kühner
Diese Ansicht auf den Code zeigt schon sehr gut wie die SPS die Adressen verarbeitet.

@PN/DP
Dir natürlich auch vielen Dank für die Erklärung!
Du hast ja den Aufwand für die SPS bei einem Zugriff mit Structurkomponenten angesprochen, dazu fällt mir noch eine Frage ein welche ich mir schon länger gestellt habe.
Weißt du evtl. ob es für die SPS mehr Aufwand ist wenn ich
DB10.DBW 100 anspreche oder wenn ich
MW100 anspreche?

Florian
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Weißt du evtl. ob es für die SPS mehr Aufwand ist wenn ich DB10.DBW 100 anspreche oder wenn ich
MW100 anspreche?

Wenn Du mit Aufwand "Zeitaufwand" meinst: Ja, es ist mehr Aufwand (zumindestens bei der S7-300).

Wenn Dich das ganze im Detail interessiert, kannst Du Dir beim Siemens-Support die Operationslisten herunterladen, da steht die detailierte Ausführungszeit für jede Anweisung drin.
 
Ja meinte ich, es äußert sich eh jeder Aufwand in Zeit. Die Liste werd ich mach nachlesen.
Auf die Frage bin ich gekommen weil ich schon öfter mal gesehen hab das Werte in einen DB geschrieben werden (so als Merkerersatz) obwohl dies eigentlich nicht wirklich notwendig gewesen wäre. Es vermutlich nur aus dem Grund geschehen ist damit man das Programm problemlos in eine Steuerung kopieren kann ohne auf die Belegung der Merker eingehen zu müssen (was natürlich auch ein Grund sein kann).
DANKE
 
Weißt du evtl. ob es für die SPS mehr Aufwand ist wenn ich
DB10.DBW 100 anspreche oder wenn ich
MW100 anspreche?
Die Operations-Ausführungszeiten sind CPU-abhängig. Bei den aktuellen S7-300 CPU besteht kein Unterschied bei der Ausführungszeit einer Ladeoperation, egal ob auf ein Merkerwort (L MW100) oder vollqualifiziert auf ein DB-Wort (L DB10.DBW100) zugegriffen wird. Bei älteren S7-300 CPU hat das Laden eines DB-Wortes mehr als doppelt so lange wie das Laden eines Merkerwortes gedauert (wegen der implizit enthaltenen Operation AUF DBxx).

Die Ladeoperationen sind aber je nach Operand unterschiedlich lang, L MWxx benötigt 2 Byte Programmspeicher, L DBxx.DBWxx benötigt 6 Byte Programmspeicher.

Details siehe in den Operationslisten der jeweiligen CPU - dabei genaue Bestell-Nummer beachten!

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Operations-Ausführungszeiten sind CPU-abhängig. Bei den aktuellen S7-300 CPU besteht kein Unterschied bei der Ausführungszeit einer Ladeoperation,...
Das trifft für solche CPUs zu, die bereits mit der Firmwareversion 3.0 erschienen sind. Die aktuellen Kompakt-CPUs haben alle noch ältere Fimrware und somit unterschiedliche Zugriffszeiten.
 
Wie schaut es denn aus, wenn ich einen AR2 Zugriff innerhalb eines FCs mache, dieser FC wird in oberster Instanz im OB1 gecallt.

Der FC hat sowohl Eingangs und Ausgangsparameter

Führt das zu Problemen bei der Benutzung mit AR2?
 
Zuletzt bearbeitet:
Zurück
Oben