Wert in AR2 nach FB Call

  • Ersteller Gelöschtes Mitglied 17702
  • Erstellt am
G

Gelöschtes Mitglied 17702

Guest
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Tag!

Ich analysiere gerade einen FB. In diesem wird zu Beginn das AR2 gerettet und später wieder verwendet. Aufgrund von fehlen eines Programmierbuches (liegt im Büro) und unzureichender Step7 Hilfe frage ich hier an.
Was beinhaltet das AR2 nach dem Call eines Multiinstanz FBs?

Gruß Polo
 
Guten Tag!

Ich analysiere gerade einen FB. In diesem wird zu Beginn das AR2 gerettet und später wieder verwendet. Aufgrund von fehlen eines Programmierbuches (liegt im Büro) und unzureichender Step7 Hilfe frage ich hier an.
Was beinhaltet das AR2 nach dem Call eines Multiinstanz FBs?

Gruß Polo

Das AR2 beinhaltet den Verweis auf den Anfang der Instanzdaten der Multiinstanz. (in der "übergeordneten" Instanz)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Step 7 verwendet bei "multiinstanzfähigen" Funktionsbausteinen das Adressregister AR2 als "Basisadressregister" für Instanzdaten. Beim Aufruf einer Instanz steht P#DBX0.0 im AR2 und alle zugriffe auf Bausteinparameter oder statische Lokaldaten im FB verwenden die registerindirekte bereichsinterne Adressierung mit dem Operandenbereich DI über dieses Register.
Ein Aufruf einer Lokalintanz erhöht mit +AR2 P#y.x die "Basisadresse" so dass innerhalb des aufgerufenen Funktionsbausteins, der den Instanz-Datenbaustein des aufrufeenden Funktionsbausteins verwendet, relativ zu dieser Adresse zugegriffen werden kann.
Auf diese Weise können Funktionsbausteine sowohl als eigenständige Instanz als auch als Lokalinstanz (und hier an beliebiger Stelle in einem Funktionsbaustein, auch mehrfach) aufgerufen werden.
 
Das heißt es werden mit jedem Aufruf des Bausteins die Lokaldaten gebildet und das AR2 zeigt auf den Beginn dieser Lokaldaten? Hab ich das richtig verstanden?
(Sorry setze mich das erste mal mit multiinstanzfähigen Bausteinen auseinander)
 
Jeder FB hat bestimmte Daten im Kopf, das sind die Bausteinparameter wie IN, OUT, IN_OUT, STAT, TEMP, diese wenn verwendet bekommen Namen.
Als Beispiel:
STAT
Merker_1 - Bool - irgendein Merker
Merker_2 - Bool - irgendein Merker
Im Baustein kannst du dann Programmieren.
Code:
U  Merker_1
=  Merker_2

Wenn du jetzt den FB wir nennen ihn mal FB1 aufrufst, must du eine Instanz nennen, einen Datenbaustein jetzt als Beispiel DB1

Code:
Call FB1 , DB1

Der Kompiler fragt dich jetzt wenn der Baustein nicht vorhanden ist ob er diesen erzeugen soll.
In diesen DB1 stehen jetzt deine Instanzdaten, wenn der Baustein bearbeitet wird.

Der DB1 sieht dann so aus:
0.0 STAT Merker_1 Bool
0.1 STAT Merker_2 Bool

Das heist:
DB1.DBX0.0 ist dann "DB1".Merker_1
DB1.DBX0.1 ist dann "DB1".Merker_2

Während der abarbeitung des Programm wird mit dem AR2 auf diese Adressen gezeigt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jup soweit ist das klar.

Bei mir sieht der CALL jedoch so aus:

Code:
CALL #station1

wobei #station1 eine STAT Variable vom TYP FB59 (mein multiinstanz FB den ich analysiere) in dem FB in dem der Aufruf stattfindet ist. Hier können mehrere Variablen von diesem Typ sein die dann genau so aufgerufen werden.
Erzeugt jetzt jeder Aufruf praktisch seinen eigenen DB auf den das AR2 dann zeigt?

Danke schon mal für deine Bemügungen! :)
 
Wenn du den FB59 als Multiinstanz öfter in einen FB aufrufst wird später nur ein DB erzeugt in den die Daten für alle aufrufe stehen. Mit den AR2 wird dann auf die entsprechende Instanz für den jeweiligen Aufruf gezeigt.
 
Aaah OK! Super! Danke dir!

Nur eine letzte Frage noch. :) Zeigt das AR2 dann auf den Beginn dieses Bereichs, also da wo die IN Parameter stehen oder direkt auf die STAT Parameter?
 
Im Zusammenhang mit Multiinstanzen (MI) und AR2 versteckt der Step7 Editor einige Dinge die man zum Verständnis des Ganzen braucht.

Ich versuche mal eine Erläuterung anhand eines Beispieles:

Zwei Bausteine FB1 und FB2. FB1 ist MI-fähig, FB2 nicht MI-fähig:
Code:
FUNCTION_BLOCK "FB1_Multiinstanzfaehig"
VAR
  wSTAT : WORD ;    
END_VAR
BEGIN
      L     #wSTAT; 
END_FUNCTION_BLOCK

FUNCTION_BLOCK "FB2_NichtMultiinstanz"
CODE_VERSION1
VAR
  wSTAT : WORD ;    
END_VAR
BEGIN
      L     #wSTAT; 
END_FUNCTION_BLOCK
Bei der symbolischen Programmierung zeigt der Step7 Editor im ersten Netzwerk
L #wSTAT
an.

Da die CPU im Gegensatz zum Step7-Editor keine Symbolik kennt, wird in Wirklichkeit folgendes gemacht:

Im "FB1_Multiinstanzfaehig":
Code:
 L     DIW [AR2,P#0.0]
und im "FB2_NichtMultiinstanz":
Code:
 L     DIW    0
Hier kann man auch sehen, dass ein nicht MI-fähiger FB geringfügig schneller ist als ein MI-fähiger, aber das nur nebenbei.


Nun, wer schreibt in das AR2 den passenden Offset? Das macht auch der Step7 Editor "unter der Haube" beim Aufrufen der entsprechenden Bausteine.

Um dem Beispiel oben zu folgen: Es wird ein FB3 (MI-fähig) angelegt, in dem die Bausteine oben folgendermaßen aufgerufen werden:
1. FB1 als MI im FB3
2. FB1 mit eigenem Instanzdatenbaustein
3. FB2 mit eigenem Instanzdatenbaustein (geht ja auch nicht anders)

Zur Verdeutlichung der Adressen habe ich im Stat-Bereich noch eine Dummy-Variable (wFoo) angelegt.

Code:
FUNCTION_BLOCK "FB3_Aufrufe"
VAR
  wFoo : WORD;
  FB1_Instanz : "FB1_Multiinstanzfaehig";    
END_VAR
BEGIN
NETWORK
TITLE =FB1 als Multiinstanz
      CALL #FB1_Instanz ;
      
NETWORK
TITLE =FB1 mit eigenem Instanz-DB1
      CALL "FB1_Multiinstanzfaehig" , DB     1 ;

NETWORK
TITLE =FB2 (nicht MI-fähig) mit eigenem DB 2
      CALL "FB2_NichtMultiinstanz" , DB     2 ;

END_FUNCTION_BLOCK
Jetzt die verschiedenen Aufrufe mit dem was der Step7 Editor drumherum schreibt:

1. FB1 als Multiinstanz im FB3

Code:
      L     DINO
      T     LW     4
      TDB   
      AUF   DI [LW 4]
      TAR2  LD     0
      +AR2  P#2.0
      UC    "FB1_Multiinstanzfaehig"
      LAR2  LD     0
      TDB
Hier wird einmal das AR2 in LD 0 gerettet (LD 0 ist in diesem Fall frei da keine Temp-Variablen im FB3 angelegt sind).
Dann wird der Offset der Instanzdaten wie in der Deklaration zu AR2 hinzuaddiert.
Somit kann nachhher im Baustein mit L DIW [AR2,P#0.0] auf die Instanzvariablen +Offset zugegriffen werden.

Wie man sieht wird hier das AR2 vor dem Aufruf gesichert und nach dem Aufruf wieder zurückgeschrieben.
So kann ein "wildgewordener" FB wenigstens nur sich, und nicht auch den Aufrufer durcheinanderbringen.

2. FB1 mit eigenem Instanz-DB 1
Code:
      TDB   
      AUF   DI     1
      TAR2  LD     0
      LAR2  P#DBX 0.0
      UC    "FB1_Multiinstanzfaehig"
      LAR2  LD     0
      TDB
Hier wird das AR2 mit einem Zeiger auf DBX0.0 geladen, damit im Baustein am Offset 0 auch der Anfang des eigenen Instanz-DBs steht.

3. FB2 (nicht MI-fähig) mit eigenem DB 2
Code:
      TDB   
      AUF   DI     2
      TAR2  LD     0
      LAR2  P#DBX 0.0
      UC    "FB2_NichtMultiinstanz"
      LAR2  LD     0
      TDB
Hier wird zwar auch das AR2 entsprechend geladen, obwohl es eigentlich unnötig wäre da im FB2 das AR2 für den Zugriff
auf die Stat-Variablen garnicht benötigt wird.
Aber der Step7 Editor "baut" dieses einfach um jeden Aufruf herum.

Gruß
Thomas
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Um eventuellen Missverständnissen vorzubeugen, sollte hier vielleicht noch erwähnt werden das die temp-Daten immer separat behandelt werden.
Also beim Bausteinaufruf (zur Laufzeit) auf dem Lokaldatenstack des aufrufenden OB erzeugt werden.

Stephan
 
@Gerhard K

Also beim Bausteinaufruf (zur Laufzeit) auf dem Lokaldatenstack des aufrufenden OB erzeugt werden.

Hab mich da vielleicht etwas missverständlich Ausgedrückt.
Ich wollte damit eigentlich zum Ausdruck bringen das die temp-Daten auf dem Lokaldatenstack des zugrunde liegenden OB abgelegt werden. Der eigentliche Baustein kann natürlich auch in einem anderen FC/FB aufgerufen werden.

Stephan
 
Zurück
Oben