FB in einem FB aufrufen

Zuviel Werbung?
-> Hier kostenlos registrieren
Welche Aufgabe soll eigentlich gelöst werden ?
Ich stimme mit Gerhard K dass es ist vielleicht sehr einfach mit Multi-Instanzen.

Anstatt zu sagen das der untergeordnete FB soll die Daten von der übergeordnete FB zugreifen, dann probier es umgekehrt. also, die untergeordnete Daten sind integriert in der übergeordnete FB wo sie auch zur verfügung steht.
Ich habe eine kleine Beispiel angehängt.
 

Anhänge

  • Test_mul.zip
    31,6 KB · Aufrufe: 5
Hallo Larry Laffer,

wenn ich die Versorgung der AnyPointer im FB1 umdrehe, funktioniert es.

Ich verstehe bald garnichts mehr.

Gruß,
Woto
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sorry, ich konnte nicht früher antworten:

Ursache für die Nicht-versorgung deines zweiten Anypointers ist, dass du mit dem Umkopieren der Anys aus IN nach Temp dein ursprüngliches AR2 zerstörst.
Sichere mal das AR2 vor der ersten Verwendung im FB1 in eine Tempvariable der Länge DWord weg und restauriere es nach deiner Umkopieraktion:
Code:
      TAR2  #Save_AR2

      L     P##FB1_Any
      LAR1  
      L     P##myPointer
      LAR2  

      L     DIW [AR1,P#0.0]
      T     W [AR2,P#0.0]
      L     DIW [AR1,P#2.0]
      T     W [AR2,P#2.0]
      L     DIW [AR1,P#4.0]
      T     W [AR2,P#4.0]
      L     DIW [AR1,P#6.0]
      T     W [AR2,P#6.0]
      L     DIW [AR1,P#8.0]
      T     W [AR2,P#8.0]


      L     P##FB1_Any2
      LAR1  
      L     P##yourPointer
      LAR2  

      L     DIW [AR1,P#0.0]
      T     W [AR2,P#0.0]
      L     DIW [AR1,P#2.0]
      T     W [AR2,P#2.0]
      L     DIW [AR1,P#4.0]
      T     W [AR2,P#4.0]
      L     DIW [AR1,P#6.0]
      T     W [AR2,P#6.0]
      L     DIW [AR1,P#8.0]
      T     W [AR2,P#8.0]

      LAR2  #Save_AR2
Und schon wird's klappen.

Ursache ist der nachfolgende CALL #myFB:
Code:
     CALL  #myFB
       Hallo      :="m_null"
       myPointer  :=#myPointer
       yourPointer:=#yourPointer
Der hier durch den Compiler zusammengebaute Code sieht folgendermaßen aus:
Code:
      Call
      BLD   14
      =     L     26.0
      L     DINO
      T     LW    24
      TDB   
      AUF   DI [LW 24]
      TAR2  LD    20
      U     M      0.0
      =     DIX [AR2,P#20.0]
      L     LD     0
      T     DID [AR2,P#22.0]
      L     LD     4
      T     DID [AR2,P#26.0]
      L     LW     8
      T     DIW [AR2,P#30.0]
      L     LD    10
      T     DID [AR2,P#32.0]
      L     LD    14
      T     DID [AR2,P#36.0]
      L     LW    18
      T     DIW [AR2,P#40.0]
      +AR2  P#20.0
      UC    FB     2
      LAR2  LD    20
      TDB   
      BLD   15
      End Call
Es wird also direkt das vorhandene AR2 verwendet um die vorbereiteten Daten in die passenden Instanzbereiche umzukopieren. Genau dieses AR2 hast du aber vorher mit deinem Pointer auf yourPointer überladen.

Dass es umgekehrt funktioniert (erst yourPointer, dann myPointer) liegt daran, dass dann AR2 wieder auf den richtigen Wert gesetzt wird, da myPointer der erste IN-Parameter des FB1 ist. Wäre vorher noch ein anderer Parameter, dann würde es auch nicht funktionieren.
"Richtig" ist hier natürlich auch nur teilweise zutreffend, ursprünglich war AR2 ein Pointer auf DBX 0.0 nun aber auf L 0.0 - das wird aber durch die explizite Typzuweisung in der Parameterübergabe ignoriert; Die relative Position ist identisch.

Wie bereits in meinem ersten Post gesagt: Bei Multiinstanzen immer AR2 sichern und restaurieren wenn man's selber verwenden will!
 
Guten Morgen zusammen,:D

heute ist ein guter Tag, denn hovonlo hat die Lösung für die letzte Hürde geliefert.:s12:

Vielen Dank hovonlo, Larry Laffer und allen anderen.

Ich habe das Testprojekt angehängt, falls jemand Interesse hat.

Gruß,
Woto
 

Anhänge

  • Test_FB_IN_FB.zip
    367,7 KB · Aufrufe: 9
In deinem Code kann es aber trotzdem noch zu Problemen kommen.

Der Befehl +AR1 oder auch +AR2 macht nur eine 16-Bit Addition.
Wenn Du nun diesen Baustein als Multiinstanz irgendwo einfügst und
die Instanzdaten auf einer Adresse >= 8192.0 liegen kriegst Du ein
großes Problem.

Dein Code:
Code:
FB2
 
      LAR1  P##myPointer
      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]
 
      LAR1  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]


universeller Code auch über Adressen 8192.0 gültig

Code:
      L     P##myPointer            // Startadresse #myPointer laden
      UD    DW#16#FFFFFF        // Bereichscodierung ausmaskieren
      TAR2                              // Start der Multiinstanz im DI laden
      +D    
      LAR1                              // Adresse im DI (Multiinstanz)
      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]
   ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
zur Verdeutlichung das Projekt mit einem zusätzlichem FB3 in der
verbesserten Version.

siehe Bilder und Projekt
 

Anhänge

  • FB2.JPG
    FB2.JPG
    81,3 KB · Aufrufe: 17
  • FB3.JPG
    FB3.JPG
    111,8 KB · Aufrufe: 16
  • Test_r_1.zip
    394,3 KB · Aufrufe: 2
Da hat Sarek wohl Recht - fast!

Es ist sogar noch schlimmer, da +AR1 bzw. +AR2 die in Akku-1-L vorliegenden 16 Bit vorzeichenrichtig erweitert und dann draufschlägt. Ist der Wert in Akku-1-L als Pointer zwischen 4096.0 (==> 32768dez; 0x8000) und 8191.7 (==> 65535dez; 0xFFFF) wird dieser als negativer Offset betrachtet und somit subtrahiert!

An diese +-15/16-Bit Beschränkung von +AR1 hab' ich auch nicht mehr gedacht, sorry.

In dem Zusammenhang ist mir noch eingefallen, dass an sich der FB1 aus dem Beispiel von Woto auch nicht Multiinstanzfähig ist, da hier auch die Verrechnung des AR2 aufs AR1 fehlt ...
 
irgendwo wird einem immer ein Bein gestellt.

Vielen Dank nochmal für eure Anmerkungen, werde dies in Zukunft berücksichtigen.

Viele Grüße,
Woto
 
Zurück
Oben