Lokalvariablen in Multiinstanzen

Grisu88

Level-1
Beiträge
61
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen,

Ich habe ein Problem mit Multiinstanzen und zwar:

habe ich einen Funktionsbaustein erstellt der eine Kommunikation via SNMP mit anderen Netzwerk Teilnehmern aufbaut und verarbeitet. Dieser Funktionsbaustein enthält als Eingangsgrößen ANY Zeiger, die im Funktionsbaustein als lokale ANY Zeiger abgespeichert werden. Mein Problem ist nun die Verwendeung von mehreren dieser Funktionsbausteine in einer Multiinstanz. Die Instanz-Datenbausteine dieses Funktoinsbausteine enthalten definierte Lokalevariablen im Temp Bereich, die beim einfügen in einer multiinstanz nicht übernommen werden. Werden nun meherere dieser Funktionsbausteine ausgeführt werden alle ANY Zeiger vom ersten Funktionsbaustein übernommen.

Ich hoffe ich konnte mein Problem darstellen :p

mfg
 
Nein, du hast dich leider nicht ganz klar ausgedrückt. Instanzdatenbausteine enthalten keine Temp-Variablen, nur IN, OUT, INOUT und STAT. Wenn du Temp-Var in deinen FB verwendest, mußt du sicherstellen, dass diese immer vor der Verwendung mit Werten beschrieben werden, also in jedem Durchlauf (Zyklus).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also ich habe ANY Pointer meinem Funktionsbaustein übergeben (IN Variable). Die übgergebende Variable ist aber ein Pointer der auf das erste Bit des übergebenden ANY Pointer zeigt. Damit ich nun den eigentlichen ANY Pointer in meinem Funktionsbaustein verwenden kann muss ich diesen mit Lokalvariablen neu erstellen. Im nachfolgenden Beispiel übergeb ich einen Speicherbereich dem Funktionsbaustein:

Code:
      L     P##DATENABLAGE
      LAR1  
      L     D [AR1,P#0.0]
      T     LD    70
      L     D [AR1,P#4.0]
      T     LD    74
      L     W [AR1,P#8.0]
      T     LW    78

hier wurde nun der ANY zeiger in den Lokalvariablen ab Lokalbyte 70 geschrieben.

Dieser Schritt wurde mehrmals im Programm mit unterschiedlichen Eingängen durchgeführt.
 
Zuletzt bearbeitet:
Hallo,
ich habe es auch nicht wirklich verstanden.
Ich nenn mal Beispielhaft Namen :
- du hast einen FB1, dem du den ANY übergibst.
- in dem FB1 hast du als MultiInstanz mehrmals den Aufruf des FB2 drin, der mit dem ANY der an den FB1 übergeben wurde, arbeiten soll.
Ist es das ?
Wenn ja, dann mußt du den Inhalt des ursprünglichen ANY's in deinem neuen ANY abbilden, den du dem "FB2" übergeben willst ...

Gruß
Larry
 
nicht ganz

FB1 bekommt ANY zeiger

und FB1 liegt mehrmals in FB2

das hat den Grund das FB1 sehr oft mit unterschiedlichen ANY zeiger aufgerufen werden soll und durch die Multiinstanzen soll die Anzahl der Instanzdatenbausteine gering gehalten werden.

Das Problem ist jedoch das alle FB1 die übergebenden ANY Zeiger vom ersten FB1 aufruf bekommen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Multiinstanz-Offset in AR2 beachten

Wie kann man die Variablenadresse in multiinstanzfähigen Funktionsbausteinen ermitteln?

In multiinstanzfähigen Funktionsbausteinen wird bei den Bausteinparametern und den statischen Lokaldaten die absolute Adresse relativ zum Adressregister AR2 geladen. Wenn man die absolute Adresse der Variablen im Instanzdatenbaustein ermitteln will, muss man den bereichsinternen Zeiger (nur die Adresse von AR2) zur geladenen Variablenadresse addieren.

Beispiel:
Code:
TAR2                  // Lade Adressregister in den AKKU 1 (Offset)
UD DW#16#00FF_FFFF    // Ausblenden der Bereichskennung
L P##variable         // Lade Adresse der Variablen
+D                    // Addiere Offset und Variablenadresse
LAR1                  // Speichere das Ergebnis im Adressregister AR1

Harald
 
ich glaube zu wissen wo das Problem liegt. Wie kopierst du den Any-Pointer in de Temp-Bereich? Wenn du das indirekt oder absolut adressiert machst hast du wahrscheinlich übersehen, dass der Instanz-Offset aus AR2 nicht berücksichtigit wird.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Einmal so:

Code:
      L     P##COMMUNITY
      LAR1  
      L     D [AR1,P#0.0]               //übergebender Pointer wird in einen ANY Zeiger gewandelt
      T     LD     0
      L     D [AR1,P#4.0]
      T     LD     4
      L     W [AR1,P#8.0]
      T     LW     8

und so

Code:
      L     B#16#10                     //Syntax beinhaltet immer 10hex
      T     LB    20
      L     B#16#2                      //Datentyp 02hex := BYTE
      T     LB    21
      L     #LEN_COMMUNITY              //Wiederholungsfaktor
      T     LW    22
      L     DBNO                        //Datenbausteinnummer der beinhaltenen Informationen (hier wurde die aufgeschlagene 
      T     LW    24                    //Datenbank mit L DBNO geladen 
      L     2                           //Anfangsadresse
      SLD   3                           //Pointer aus der Anfangsadresse generieren
      T     LD    26
      L     B#16#84                     //Speicherbereich (84hex := Datenbaustein)
      T     LB    26
 
Das ist nicht ganz so schwer:

Code:
      L     P##COMMUNITY   // Hier wrid ein Pointer geladen den du im Deklarationsteil bei deiner Variable ablesen kannst. beispielsweise P#DI10.0
      LAR1  
      L     D [AR1,P#0.0]               //Und hier wird dann das DID 10 geladen
      T     LD     0
      L     D [AR1,P#4.0]
      T     LD     4
      L     W [AR1,P#8.0]
      T     LW     8

Wenn du jetzt deinen FB als Multiinstanz aufrufst beginnt die Instanz des FB aber meist nicht im Instanz-DB auf der Adresse 0.0 sondern irgendwo. Und genau der Anfang deiner Instanz steht im AR2.

also sollte es so besser funktionieren:
Code:
      L     P##COMMUNITY   // Hier wrid ein Pointer geladen den du im Deklarationsteil bei deiner Variable ablesen kannst. beispielsweise P#DI10.0
      +AR2                          // Beispielsweise beginnt deine Instanz bei 100.0
      LAR1  
      L     D [AR1,P#0.0]               //Und hier wird dann das DID 110 geladen
      T     LD     0
      L     D [AR1,P#4.0]
      T     LD     4
      L     W [AR1,P#8.0]
      T     LW     8
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ganz verstanden hab ich das noch nicht mit dem AR2 :p
Du willst auf die absolute Adresse Deines IN-Parameters zugreifen, "L P##DATENABLAGE" liefert Dir aber nur die relative Adresse zum Anfang der aktuellen Multiinstanz. Du mußt noch die Anfangsadresse der aktuellen Multiinstanz aus dem AR2 dazurechnen.

Code:
      [COLOR="#FF0000"]TAR2                     // Anfangsadresse der aktuellen Instanz
      UD    DW#16#00FF_FFFF    // Ausblenden der Bereichskennung[/COLOR]
      L     P##DATENABLAGE
      [COLOR="#FF0000"]+D                       // Addiere Offset und Variablenadresse[/COLOR]
      LAR1
      L     D [AR1,P#0.0]
      T     LD    70
      L     D [AR1,P#4.0]
      T     LD    74
      L     W [AR1,P#8.0]
      T     LW    78

Harald
 
Achso,

reicht es denn einmal das ich am Anfang des Funktionsbaustein Aufrufs die relative Adresse herrausfinde?

irgendwie so?
Code:
L P#0.0
+AR2
LAR1
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
also sollte es so besser funktionieren:
Code:
L     P##COMMUNITY   // Hier wrid ein Pointer geladen den du im Deklarationsteil bei deiner Variable ablesen kannst. beispielsweise 
P#DI10.0      
+AR2                          // Beispielsweise beginnt deine Instanz bei 100.0      
LAR1       
L     D [AR1,P#0.0]               //Und hier wird dann das DID 110 geladen      
T     LD     0      
L     D [AR1,P#4.0]      
T     LD     4      
L     W [AR1,P#8.0]      
T     LW     8

ich glaube so geht das noch nicht ganz :p

der Befehl +AR2 addiert doch zum Adressregister 2, muss nicht die Adresse vom Adressregister 2 zum Adressregister 1 addiert werden?

mit der Methode von Harald geht das besser :p

oder hab ich da wieder was flasch verstanden
 
Zuletzt bearbeitet:
Das Maskieren mit dem UD sollte drinbleiben, da hiermit eine evtl. im AR2 mit enthaltene Bereichskennung (M, L, LV, DB, DI) entfernt wird - man weiß ja nie.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich glaube so geht das noch nicht ganz :p

der Befehl +AR2 addiert doch zum Adressregister 2, muss nicht die Adresse vom Adressregister 2 zum Adressregister 1 addiert werden?

mit der Methode von Harald geht das besser :p

oder hab ich da wieder was flasch verstanden

Stimmt. Sorry, da hatte ich den Befehl falsch rum im Kopf.
 
ich habe jetzt jedes LAR1 durch den nahcfolgenden Code ersetzt


Code:
      TAR2                              // Anfangsadresse der aktuellen Instanz
      UD    DW#16#FFFFFF                // Ausblenden der Bereichskennung
      +D                                // Addiere Offset und Variablenadresse
      LAR1

jedoch bekomme ich nun einen Systemfehler wenn ich mehr als einen FB benutze muss ich noch mehr beachten?
 
es müsste doch auch ohne

Code:
UD    DW#16#FFFFFF

gehen oder?
Beim Addieren von Adressen darf nur eine der beiden Adressen eine Bereichskennung enthalten (bereichsübergreifende Adresse), die andere Adresse darf nur einen relativen Offset ohne Bereichskennung enthalten (bereichsinterne Adresse) - sonst würde ja beim Addieren die Bereichskennung "verdoppelt".

- "L P##INSTANZVAR" lädt eine Adresse inklusive Bereichskennung
- in AR2 ist die Anfangsadresse der aktuellen Instanz inklusive Bereichskennung

Beim Addieren mit +D muß bei einer der beiden Adressen die Bereichskennung ausgeblendet/gelöscht werden - am einfachsten mit "UD DW#16#FFFFFF". Oder man addiert mit +AR1 - diese Operation berücksichtigt das Ausblenden der Bereichskennung. Es gibt viele Möglichkeiten, das AR2 korrekt zur Adresse der Instanzvariable zu addieren:
Code:
// von Siemens empfohlener Code:
      TAR2
      UD    DW#16#00FF_FFFF
      L     P##INSTANZVAR
      +D
      LAR1

// oder:
      L     P##INSTANZVAR
      UD    DW#16#00FF_FFFF
      TAR2
      +D
      LAR1

// oder:
      L     P##INSTANZVAR
      LAR1
      TAR2
      +AR1

// oder:
      LAR1  P##INSTANZVAR
      TAR2
      +AR1

Noch ein Hinweis:
Das AR2 muß bei einem symbolischen Zugriff auf Instanz-Variablen in multiinstanzfähigen FB den vom System eingetragenen Inhalt vom Bausteinaufruf haben - falls AR2 verändert wird, dann muß vor einem solchen Zugriff das AR2 wiederhergestellt werden.

Harald
 
Zurück
Oben