FB in einem FB aufrufen

Woto

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

ich möchte einen FB2 in einem FB1 aufrufen. Das Problem dabei ist, das der FB2 den InstanzDB vom äußeren FB1 benutzen soll. Also habe ich eine temporäre Variable vom Typ FB2 im FB1 deklariert. Im FB1 wird dann der FB2 aufgerufen:
Code:
CALL #FB2
...
Der FB2 hat einen AnyPointer als Eingang (E1). Dieser wird von einer temporären Variablen V1 vom Typ AnyPointer im FB1 versorgt. Im FB1 hat die temporäre Variable V1 die Werte:
P#0.0 1002h
P#2.0 000Fh
P#4.0 0008h
P#6.0 8400h
P#8.0 0000h

Im FB2 hat der Eingang E1 folgende Werte:
P#0.0 0001h
P#2.0 0100h
P#4.0 1002h
P#6.0 000Fh
P#8.0 0008h

Warum sind die Werte nicht gleich?
Ich vermute, das ich einen Pointer auf einen Pointer habe.

Gruss, Woto
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich möchte einen FB2 in einem FB1 aufrufen. Das Problem dabei ist, das der FB2 den InstanzDB vom äußeren FB1 benutzen soll. Also habe ich eine temporäre Variable vom Typ FB2 im FB1 deklariert.
Hallo Woto,
heißt das, dass du den FB2 im TEMP-Bereich des FB1 deklariert hast ? Doch wohl nicht ... der gehört in den STAT-Bereich hinein ...

Bezüglich deines ANY-Pointers sieht es für mich nach einem Verdreher aus. Du hast ja im FB2 die richtigen Inhalte - nur doppelwortweise vertauscht. Vielleicht postest du mal den Code (die relevanten Stellen von beiden Bausteinen) - dann läßt sich vielleicht mehr dazu sagen ...

Gruß
LL
 
Hallo,

Im FB1 wird der folgende Code aufgerufen:
Code:
      L     P##t_SENDDATA
      LAR1  
      L     W [AR1,P#0.0]
      T     "test".t10
      L     W [AR1,P#2.0]
      T     "test".t12
      L     W [AR1,P#4.0]
      T     "test".t14
      L     W [AR1,P#6.0]
      T     "test".t16
      L     W [AR1,P#8.0]
      T     "test".t18
 
      CALL  #s_ComTCP
       ID_185      :=#ID
       LADDR_185   :=#LADDR
       STrig_185   :=#STrig
       SData_185   :=#t_SENDDATA
       RData_185   :=#t_RCVDATA
       BlkRcv_185  :="m_eins"
       EndSign_185 :=
       NDR_185     :=#s_NDR
       ERR_185     :=#s_ERR
       S_Status_185:=#s_S_Status
       R_Status_185:=#s_R_Status

s_ComTCP ist eine statische Variable vom Datentyp FB2. Der Eingang SData_185 ist ein ANYPOINTER. Der Parameter t_SENDDATA ist eine temporäre Variable vom Datentyp ANYPOINTER.

Innerhalb des FB2 frage ich den Inhalt des Anypointer ab:
Code:
      L     P##SData_185
      LAR1  
      L     W [AR1,P#0.0]
      T     "test".t20
      L     W [AR1,P#2.0]
      T     "test".t22
      L     W [AR1,P#4.0]
      T     "test".t24
      L     W [AR1,P#6.0]
      T     "test".t26
      L     W [AR1,P#8.0]
      T     "test".t28

Der Inhalt der beiden ANYPOINTER t_SENDDATA und SDATA_185 sind unterschiedlich.
Waraum ist das so? Wie kann ich auf den Inhalt des übergebenen Pointer zugreifen?
Wenn ich den FB2 im FB1 mit einem eigenen InstanzDB aufrufe, funktioniert alles.
Gruss, Woto
 
Hallo Woto,
mit "L W [AR1,p#0.0]" greifst du auf den TEMP-Bereich zu. Wenn du an die Schnittstelle (z.B. IN-Bereich) willst, dann wäre "L DIW [AR1,p#0.0]" der richtigere Befehl ...

Es hätte mich übrigens auch interessiert, wo der ANY-Pointer her kommt.

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry Laffer,

der ANYPOINTER im FB1 wird folgendermaßen versorgt:
Code:
      TAR1  #t_ADR1          // Adressregister retten
      TAR2  #t_ADR2
      LAR1  P##SData        // AnyPointer auf temporäre AnyZeiger kopieren
      LAR2  P##t_SENDDATA
      L     W [AR1,P#0.0]
      T     W [AR2,P#0.0]
      T     "test".t0
      L     W [AR1,P#2.0]
      T     W [AR2,P#2.0]
      T     #s_SendLength
      T     "test".t2
      L     W [AR1,P#4.0]
      T     W [AR2,P#4.0]
      T     "test".t4
      L     W [AR1,P#6.0]
      T     W [AR2,P#6.0]
      T     "test".t6
      L     W [AR1,P#8.0]
      T     W [AR2,P#8.0]
      T     "test".t8
      LAR1  #t_ADR1                     // Adressregister zurückschreiben
      LAR2  #t_ADR2

SData ist ein IN vom Typ Anypointer.

Leider hat dein Tip mit "L DIW[AR1,P#0.0]" zum gleichen Ergebnis geführt wie"L W[AR1,P#0.0]".

Gruß, Woto
 
... ist schon merkwürdig ... bei mir hat es funktioniert ...

Wo kommt denn im FB1 der ANY-Pointer her ? Erzeugst du ihn dort (zu Fuß) oder ist das auch wieder ein IN-Parameter ? Was für eine Variable übergibst du an den FB2 (TEMP ?) ?

In dem letzten Codeschnipsel arbeitest du übrigens auch wieder mit "L W ..."

Gruß
LL
 
Halo Larry Laffer,

der FB1 hat einen IN-Parameter vom Datentyp ANY. Diesen Anypointer kopiere ich auf eine temporäre Variable vom Typ ANY. Diese temporäre Variable übergebe ich dem FB2 über einen IN-Parameter vom Typ ANY. Im FB2 möchte ich dann letztendlich den am FB1 über den IN-Parameter angebundenen ANYPOINTER bearbeiten.

Ich habe mal ein kleines Bild vorbereitet, um das Ganze zu veranschaulichen.
 

Anhänge

  • FBinFB.pdf
    12,5 KB · Aufrufe: 41
Hallo Larry Laffer,

ich habe dein Beispiel mal nachgebaut und es funktioniert.

Dann habe ich aber mal im FB2 vor dem Anypointer myPointer eine BOOL-Variable deklariert. Danach funktioniert es nicht mehr.

z.B.:
IN
HALLO Bool 0.0
myPointer Any 2.0
 
hier meine Bilder, wenn der AnyPointer nicht an 1. Stelle in der Deklaration ist.
 

Anhänge

  • FB2.JPG
    FB2.JPG
    166,1 KB · Aufrufe: 14
  • FB1.JPG
    FB1.JPG
    202,3 KB · Aufrufe: 14
  • OB1.JPG
    OB1.JPG
    117,4 KB · Aufrufe: 12
Zuviel Werbung?
-> Hier kostenlos registrieren
Na ... da kann ich jetzt auch nicht wechseln.
Ich habe das mal nachgestellt. Ist bei mir genau so - und zwar unabhängig, ob ich den FB2 als eingelagerte Instanz oder als eigenständige Instanz betreibe.
Möchte ich den korrekten Inhalt des ANY-Pointers (mit PLC-Sim) sehen, dann muß ich im FB2 den AR1 mit dem Offset der ersten Variablen in der Schnittstelle setzen.
Testest du das auch mit PLC-Sim ?
Ich probiere das gleich auch noch mal mit einer richtigen CPU ...

Gruß
LL
 
Ich habe das mit einer realen CPU getestet.

Wie kann ich das AR1 mit dem Offset der 1. Variablen setzen?

Gruß,
Woto
 
Hier kommt das AR2 zum tragen:

Bei Aufruf eines Multiinstanz-FBs enthält AR2 den Offset vom Beginn des gesamten Instanz-DBs zum Beginn des Datenbereichs der Instanz des aktuellen FBs (ich liebe diese Sätze ...). Dieser Offset muss zu AR1 addiert werden, damit das klappt.

Z.B. sieht der Instanz-DB eines FB1 mit einem statischen Wort und zwei enthaltenen Instanzen eines anderen FBs der jeweils 1 Wort IN und 1 Wort OUT hat etwa so aus:

Code:
DATA_BLOCK DB 1
TITLE =
VERSION : 0.0

 FB 1
BEGIN
   MeinWort := W#16#0; 
   ErsterFB.Hinein := W#16#0; 
   ErsterFB.Hinaus := W#16#0; 
   ZweiterFB.Hinein := W#16#0; 
   ZweiterFB.Hinaus := W#16#0; 
END_DATA_BLOCK
Während jetzt der FB ErsterFB läuft verweist AR2 (als Offset!) auf ErsterFB.Hinein.

Während jetzt der FB ZweiterFB läuft verweist AR2 (als Offset!) auf ZweiterFB.Hinein.

Zugriffe innerhalb Multiinstanz-FBs laufen bei Pointeradressierung also immer auf eine schlußendliche Addition

Code:
TAR2
+AR1
mit dem anschließenden Zugriff via AR1 hinaus.

In genau dieser Verwendung liegt auch begründet, dass man in Multiinstanzen tunlichst entweder die Finger von AR2 lässt oder AR2 erst sichert und nach den eigenen Aktionen mit AR2 wieder restauriert.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... liegt auch nicht an PLC-Sim ...

Schreib mal im FB2 : "L P##Hallo" statt dem richtigen Offset für den ANY ...

Ich denke, das ist dann ein Fall für die Hotline ... mir fällt da jetzt nichts mehr dazu ein.
Nach meiner Meinung ist das was du und wie du es programmiert hast absolut OK ... und funktionieren sollte das auch.

Gruß
LL
 
In genau dieser Verwendung liegt auch begründet, dass man in Multiinstanzen tunlichst entweder die Finger von AR2 lässt oder AR2 erst sichert und nach den eigenen Aktionen mit AR2 wieder restauriert.

Hast du dir mal den Beitrag #6 in diesem Thread von Woto angesehen ?

Nachsatz:
Ich habe den AR2-Save und -Restore auch mal gerade in meinen Code intergriert - ändert nichts ...
 
Zuletzt bearbeitet:
Ich habe das mit der Erklärung von hovonlo nicht verstanden.

Wie kann ich denn nun auf den Anypointer "yourPointer" im FB 2 zugreifen?
So in etwa:
Code:
      L     P##yourPointer
      LAR2  
      +AR1  
      L     DIW [AR1,P#0.0]
      L     DIW [AR1,P#2.0]
      L     DIW [AR1,P#4.0]
      L     DIW [AR1,P#6.0]
      L     DIW [AR1,P#8.0]

Dann bin ich aber irgendwie 1 Wort zu weit.

Ein Beispiel wäre nicht schlecht.

Gruß,
Woto
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hovonlo meinte :
Code:
      L AR1   P##yourPointer
      TAR2  
      +AR1  
      L     DIW [AR1,P#0.0]
      L     DIW [AR1,P#2.0]
      L     DIW [AR1,P#4.0]
      L     DIW [AR1,P#6.0]
      L     DIW [AR1,P#8.0]
... und so funktioniert es dann auch - die Rettung des AR2-Registers im FB1 wirkt sich aber überhaupt nicht aus (das regelt der FB2 sehr wahrscheinlich schon alleine).

Gruß
LL
 
Hallo Larry Laffer,

wenn ich das mache, habe ich für yourPointer keine Dateninhalte mehr. Wobei myPointer funktioniert.

Ich werde nochmal verrückt :sb7:
 

Anhänge

  • FB2geändert.JPG
    FB2geändert.JPG
    165,8 KB · Aufrufe: 14
Zurück
Oben