Multiinstanzproblem

sixt

Level-1
Beiträge
16
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich arbeite momentan an einem multiinstanzfähigen Funtkionsbaustein für die offene Kommunikation über TCP und verwendet dabei die Bausteine FB65 "TCON, FB63 "TSEND", FB64 "TRCV" und FB66 "TDISCON".

Icharbeite dabei mit einer CPU414-3 PN/DP mit der Firmware-Version 2.5 und Step7 5.4.

Nun habe ich das Problem, dass ein Verbindungsaufbau einwandfrei funktioniert wenn ich den FB 2 mal mit jeweils einem eigenen Instanz-DB aus dem OB1 aufrufe, wobei jeder Aufruf natürlich eine eigene ID und Verbindungs-Struktur in einem globalen DB besitzt.

Sobald ich jedoch versuche den Baustein 2 mal aus einem FB aufzurufen, wobei die sich die Instanzen im Instanz-DB des aufrufenden FBs befinden, funktioniert der Verbindungsaufbau nur noch bei der 1.Instanz. Die 2.Instanz wird zwar aufgerufen und Testvariablen werden auf TRUE gesetzt, die Verbindung bleibt jedoch tot. Wenn ich die Verbindungs-IDs und Adressen der Verbindungsparameter tausche funktioniert wieder nur die 1. Instanz während die 2. keine Verbindung aufbaut. Auch ein Tausch in der Reihenfolge des Aufrufes bringt dabei keine Änderung. Es ist immer die 2. Instanz die nicht funktioniert.

Noch ein bisschen zu meinem Programm:

Die Instanzen der Kommunikations-FBs befinden sich in meinem Baustein. Um zu verhindern, dass der Kunde später im Baustein noch etwas ändern muss habe ich ausserdem den Eingangsparameter CONNECT nach aussen weitergeschleift sodass man die Adresse der Verbindungsstruktur jederzeit einfach ändern kann.

Dazu habe ich einen Eingangsparameter vom Typ Any geschaffen, den ich intern auf einen temporären Parameter kopiere, mit dem ich den FB65 aufrufe.

Habt ihr Ideen, wo mein Fehler liegt???
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nein, ich hatte als Grundlage einen FB der mit dem AR2 gearbeitet habe. Das hab ich aber schon rausgeschmissen. Ich zeig dir mal kurz den Code.

Das hier ist der Code den ich verwende um den Eingangsparameter ConnectionPointer auf einen temporären zu kopieren (TempConPointer).
TempConPointer wird dann beim Aufruf des FB65 verwendet.
Code:
    [FONT=Arial]LAR1  P##ConnectionPointer[/FONT]
  [FONT=Arial]      L     P##TempConPointer[/FONT]
  [FONT=Arial]      T     #p_tmp1[/FONT]
  [FONT=Arial]//copy IN-parameter ANY to ANY-tmp[/FONT]
  [FONT=Arial] [/FONT]
  [FONT=Arial]      L     D [AR1,P#0.0][/FONT]
  [FONT=Arial]      T     LD [#p_tmp1]                [/FONT]
  [FONT=Arial]      L     #p_tmp1[/FONT]
  [FONT=Arial]      +     32[/FONT]
  [FONT=Arial]      T     #p_tmp1                     [/FONT]
  [FONT=Arial]      L     D [AR1,P#4.0][/FONT]
  [FONT=Arial]      T     LD [#p_tmp1]                [/FONT]
  [FONT=Arial]      L     #p_tmp1[/FONT]
  [FONT=Arial]      +     32[/FONT]
  [FONT=Arial]      T     #p_tmp1                     [/FONT]
  [FONT=Arial]      L     W [AR1,P#8.0][/FONT]
  [FONT=Arial]      T     LW [#p_tmp1]        [/FONT]

Diesen Code verwende ich z.B. für den FB63, wobei das Problem schon damit beginnt, dass bei der 2. Instanz keine Verbindung aufgebaut werden kann.
Code:
    [FONT=Arial]      LAR1  P##Data_Pointer_OUT[/FONT]
  [FONT=Arial]      L     #Type_of_Data[/FONT]
  [FONT=Arial]      T     LW [AR1,P#0.0][/FONT]
  [FONT=Arial]      L     #TCP_Telegramlength[/FONT]
  [FONT=Arial]      T     LW [AR1,P#2.0][/FONT]
  [FONT=Arial]      L     DINO[/FONT]
  [FONT=Arial]      T     LW [AR1,P#4.0][/FONT]
  [FONT=Arial]      TAR2  [/FONT]
  [FONT=Arial]      UD    DW#16#FFFFFF[/FONT]
  [FONT=Arial]      L     P#DBX 134.0                 //Head_1.OutData.[/FONT]
  [FONT=Arial]      +D    [/FONT]
  [FONT=Arial]      T     LD [AR1,P#6.0][/FONT]
 
war da nicht irgendwas mit versatz AR2 hinzuzählen wenn man es multiinstanzfähig haben will,oder verwechsle ich da jetzt was?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Jap... Irgendwie oder so ähnlich war das mit dem AR2. Bin noch relativ neu und blicke was AR1/AR2 angeht und den Aufbau noch nicht 100% durch.

Mit dem Aufruf hat das Problem nichts zu tun, das es ja bei der 1. Instanz einwandfrei funktioniert. Nur die 2. Instanz zeigt dieses Problem unabhängig davon ob diese vor oder nach der ersten aufgerufen wird und mit welchen Verbindungsdaten.
 
Ich will dir nicht gleich die Lösung zeigen, da die Pointergeschichten nur durch "selbst probieren" verstanden werden. Aber hier ein snipplet:"Hinweise zur Änderung von Register-InhaltenDer 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".



Schreib jetzt mal einen FB2:
Code:
VAR_INPUT
  eingang1 : INT ;    
END_VAR
VAR_OUTPUT
  test : INT ;    
END_VAR


LAR1  P##eingang1; 
 L     W [AR1,P#0.0]; 
T     #test;
und einen FB1, in dem 2 Instanzen von FB2 aufgerufen werden:
Code:
VAR
  a : FB 2;    
  b : FB 2;    
END_VAR
BEGIN
NETWORK
TITLE =


      CALL #a (
           eingang1                 := EW     0,
           test                     := AW     0);
      CALL #b (
           eingang1                 := EW     2,
           test                     := AW     2);
Und spiel mal damit, du wirst sehen, dass AW2 immer EW0 ausgibt. Der Pointer der durch LAR1 P##eingang1;geladen wird, zeigt wohl immer nur auf den Eingang der ersten Instanz. Nun nochmal mit

Code:
      LAR1  P##eingang1; 
      TAR2  ; 
      UD DW#16#00FF_FFFF;
      +AR1  ; 
      L     W [AR1,P#0.0]; 
      T     #test;
probieren und auf dein Problem übertragen. Viel Erfolg und HTH
Gruß von Andy
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Dankeschön, mit ein bisschen Probieren habe ich es letzten Endes geschafft. Das Kopieren von dem Any-Pointer sieht jetzt so aus:

Code:
 LAR1  P##ConnectionPointer
      TAR2  
      UD    DW#16#FFFFFF
      +AR1  
      L     P##TempConPointer
      T     #p_tmp1
//copy IN-parameter ANY to ANY-tmp

      L     D [AR1,P#0.0]
      T     LD [#p_tmp1]                
      L     #p_tmp1
      +     32
      T     #p_tmp1                    
      L     D [AR1,P#4.0]
      T     LD [#p_tmp1]                 
      L     #p_tmp1
      +     32
      T     #p_tmp1                     
      L     W [AR1,P#8.0]
      T     LW [#p_tmp1]

Funktioniert jetzt auf den ersten Blick alles :)

Ich denke aber das mit dem AR1 und AR2 muss man sich noch ein bisschen zu Gemüte führen, bis man das aus der Hüfte kann.

Soweit ich das jetzt verstanden habe, habe ich jetzt die Adresse von ConnectionPointer in AR1 kopiert. Danach habe ich Adressregister2 in AKKU1 geladen um den Offset hinzuzuaddieren zu können. Anschließend habe ich mit einer Maske die Bereichserkennung ausmaskiert und danach die Adresse von AR1 zu dem Zeiger addiert um die Adresse in der jeweiligen Instanz zu erhalten.

Sind soweit noch irgendwelche gedanklichen Fehler drin oder habe ich es soweit verstanden?

Gruß und Dankeschön, Sixt
 
nicht vergessen vorher die adressregister sichern und nachher wieder herstellen.sonst kann das mitunter einmal ein böses erwachen geben.
 
Wie darf ich das verstehen?

Wenn ich die Adressregister AR1 und AR2 in dieser Weise einsetze und z.B. meinen Pointer kopiert habe oder erstellt habe und diesen fertigen Pointer in einer Variable gespeichert habe dann ist der Inhalt von AR1 und AR2 doch nebensächlich.

Hauptsache beim nächsten Aufruf steht werden nicht aus versehen die alten Daten verwendet.

Oder verstehe ich da noch etwas falsch???

Gruß, Sixt
 
Zuviel Werbung?
-> Hier kostenlos registrieren
das ist ja der grund.du veränderst für deine zwecke die AR und wenn du dann die AR wieder benutzt könnten die falschen werte drinnenstehen.
Also immer schön TAR1+2(retten) und LAR1+2(rückschreiben) benutzen.
 
Hallo sixt,

Dein Programm benutzt das AR2 nicht exclusiv!

Bei jedem Zugriff auf Multiinstanz-Variablen erwartet das MC7-Programm,
daß im AR2 der Offset zur Anfangsadresse der Multiinstanz-Variablen steht.
Wenn Du nun AR2 änderst, dann crasht der nächste Zugriff.

Wenn Dein Programm einen FB aufruft, dann ist bei der Rückkehr eventuell der
Inhalt des AR2 durch das MC7-Programm verändert. Dann crasht Dein Programm.

Gruß
PN/DP
 
Zurück
Oben