Step 7 Was macht der CPU- Akku hier genau?

borromeus

Level-1
Beiträge
2.271
Reaktionspunkte
329
Zuviel Werbung?
-> Hier kostenlos registrieren
Liebe Freunde,
ich reib mir seit 30min die Augen, weil ich nicht verstehe was ich hier sehe.

Anbei Testauszug einen FB's der im CFC aufgerufen wird.

Kann mir wer sagen warum nach dem LAR2 Befehl im nachfolgendem Akku Ladebefehl 0 drinnensteht?
Wenn ich den LAR2- Befehl auskommentiere passt alles.
 

Anhänge

  • Lade.PNG
    Lade.PNG
    25,6 KB · Aufrufe: 105
Cursor auf "LAR2" setzen, F1 drücken und lesen. Da müsste drinstehen was der Befehl tut und wie er nach Ausführung die Akkus beeinflusst.

Tipp: LAR2 lädt dein Adressregister 2 um und damit auch deinen Multiinstanzoffset.
Sofern "I_RCP_sel" im IN/OUT/STAT des FB liegt führt der Zugriff auf "I_RCP_sel" vor dem LAR2 auf eine andere Adresse im Instanz-DB als danach.
 
Zuletzt bearbeitet:
Ja stimmt sorry, da muss man etwas genauer suchen. Vor allem zur Bedeutung von AR2 in Multiinstanzen.

Schau mal was in der Spalte AR2 steht. Ich nehme an das "I_RCP_sel" im IN/OUT/INOUT/STAT des FB liegt.
Beim ersten Ladebefehl steht dort DB0.0. Dem Anschein nach ist also der FB eine Einzelinstanz oder eine Multiinstanz wobei die beobachtete Instanz die erste im Aufruferbaustein ist.

Das Adressregister 2 enthält den Multiinstanzoffset.
Wenn z.B. dein "I_RCP_sel" in deiner Bausteinschnittstelle den Offset 10 hat, dann wird mit "L I_RCP_sel" auf AR2 + 10, bei der ersten Instanz also 0+10 zugegriffen.
Wenn du jetzt mehrere Instanzen im Aufrufenbaustein hättest dann liegt "I_RCP_sel" nicht mehr bei 10 sondern bei der Anfangsadresse der Instanz + 10.
Diese Anfangsadresse bekommt der Multiinstanz-FB automatisch beim Aufruf in das AR2 geschrieben.

Jetzt wird das AR2 aber aus irgendeinem Grund umgeladen. Will man auf eine andere Instanz zugreifen oder ob Programmierfehler weiß ich nicht.
Beim zweiten Ladebefehl hast du dann 130 im AR2 stehen.

Der erste Ladebefehl geht also auf 0+"Offset von I_RCP_sel in der Schnittstelle" und der zweite Ladebefehl auf 130+"Offset von I_RCP_sel in der Schnittstelle".
Da du also von 2 verschiedene Adressen und möglicherweise 2 unterschiedliche " I_RCP_sel" lädst, bekommst du auch Unterschiedliche Werte im Akku.

Gib mal ein paar Infos zu dem Baustein. Schnittstelle, Instanzaufbau vom Aufrauf, Sollfunktion....
 
Zuletzt bearbeitet:
Also wie gesagt ist das ein CFC Baustein- läuft mit PCS7.
Aufgerufen wird der FB aus einem compilierten FC, Code siehe anbei- den erzeugt das System selbst.

Der I_RCP_sel entspricht einer Rezepturnummer und ist ein IN-Parameter.
Der Baustein kopiert im Prinzip Daten von einer Rezepturdatenbank, die im InstanzDB liegt, auf Ausgangsdaten, die dann im CFC weiterverwendet werden sollen.
Das was man hier sieht ist lediglich ein Test weil mir die CPU (PLC-Sim) gleich mal auf Stopp gegangen ist.

Ich kenne das Problem mit dem AR2 eigentlich schon, dachte aber, dass das nur Auftritt wenn man einen FB aus einem FB aufruft.




Edit: es gibt also im Code u.a. mehrere Schleifen, die 122 Bytes von einem IN_OUT-Bereich auf einen anderen, berechneten IN_OUT-Bereich kopieren sollen.
Dazu dachte ich mal der Einfachheit halber ich mache das mit AR1 und AR2.
 

Anhänge

  • FC917.PNG
    FC917.PNG
    7,1 KB · Aufrufe: 39
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hast Du das Programm selber geschrieben oder irgendwo so vorgefunden?

Mir scheint, als ob alle Anweisungen nach dem "= #REZ_GEW" (fehlerhafte) Testleichen ohne Funktion sind (und gelöscht werden können).
Oder wird nach dem Aufruf des FB1131 der Inhalt von AR1, AR2 oder der AKKUs weiterverwendet??!! --> äußerst unsauber

"LAR2 P##RCP0_B_1" lädt die Adresse der Instanz-Variable RCP0_B_1 (130.0 im IDB) in den AR2.
Wenn der FB als multiinstanzfähig übersetzt wurde, dann wird bei allen Zugriffen auf Instanz-Variablen der Multiinstanz-Offset aus AR2 zur Instanz-Adresse addiert ---> dann greifen alle folgenden Zugriffe auf Instanz-Variablen um 130 Byte zu hoch in den IDB zu!! ---> deshalb liefert das nächste "L #I_RCP_sel" nicht mehr den selben Wert wie vor der Veränderung des AR2 ---> das ist ein Programmierfehler (Bug) oder absichtlich äußerst unsaubere Programmierung

(PS: zu langsam getippt)

Harald
 
Zum besseren Verständnis, hab ich mal kurz nen FB als Einzelinstanz aus nem FC aufgerufen.
Sofern der FB mit Einstellung "Multiinstanzfähig" erstellt/kompiliert wurde wirkt sich das AR2 auch bei dem Einzelinstanzaufruf aus dem FC aus.
S7_300_AR2.jpg

Wenn der FB, wie Harald schon schrieb, nicht als Multiinstanzfähig erstellt wurde, dann bleibt AR2 ohne Wirkung.

Das was man hier sieht ist lediglich ein Test weil mir die CPU (PLC-Sim) gleich mal auf Stopp gegangen ist.
Das hinter dem LAR2 sieht ja ganz sinnig aus. Da wird ein auf Grund eines Selektors (#I_RCP_sel) eine Adresse errechnet, ins Poiterformat gewechselt und dann in AR1 geladen.
Damit könnte man später (hoffentlich noch im selben Baustein) über registerindierekte Adressierung was lesen.

In dem Moment wo aber die 130 auf das AR2 geladen wird, wird auf den Instanzbereich ab 130 zugegriffen.
Ich könnte mir ja vorstellen dass das eine grausame Art ist, dynamisch auf eine einzelne aus einer Anzahl von Instanzen im IDB zuzugreifen.

Also wie gesagt ist das ein CFC Baustein- läuft mit PCS7. Aufgerufen wird der FB aus einem compilierten FC, Code siehe anbei- den erzeugt das System selbst.
Wer hat dann die Quelle für den FB geschrieben, irgendwer muss sich dass ja ausgedacht haben.
 
Zuletzt bearbeitet:
Wer hat dann die Quelle für den FB geschrieben, irgendwer muss sich dass ja ausgedacht haben.
Also ich glaube auch nicht, dass der Baustein von PCS7/Siemens mitgeliefert wurde.
Das sieht doch wirklich nach einem in AWL geschriebenen Baustein aus. Und in PCS7 ist doch alles in SCL geschrieben, bzw. wenn der Baustein direkt aus dem CFC kommt, geht das auch über den SCL-Zwischenschritt und dann würde der Code auch anders aussehen...
F
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nene Freunde, der Code des FB's ist schon von mir.

Wo schon oben geschrieben, ist das, was hier im Screenshot ist nur ein kleiner Teil, den ich von einem anderen Netzwerk in das NW1 hineinkopiert habe, weil ja auch hier der Fehler ist- das ist keine Leiche sondern ein Teil eines Netzwerkes.
Der Code generiert aus einer- wie Ronin messerscharf geschlossen hat- Rezepturnummer I_RCP_SEL (0-50) einen Pointer wo denn diese Rezeptwerte in der Instanz liegen.

OK- dann funzt das also so nicht.

Also was ich möchte ist:

Ich habe IN_OUT Variabeln.

REZ0_Wert1
REZ0_Wert2
REZ0_Wert3
.
.
REZ0_Wert40


REZ1_Wert1
REZ1_Wert2
REZ1_Wert3
.
.
REZ1_Wert40

....

REZ50_Wert1
REZ50_Wert2
REZ50_Wert3
.
.
REZ50_Wert40


Also rund 2000 Parameter als 51 Rezepte mit ~40 Werten.
Diese sollen nun nach verschiedenen Benutzerfunktionen hin und herkopiert werden. Teilweise muss man Werte auch noch umrechnen, somit funktioniert ein BLK_MOV mal nicht so einfach (also über Umweg schon).

Wie ist denn der "gängige" Weg wenn ich innerhalb einer Instanz Daten (in Schleifen) von einer Adresse zu einer anderen kopieren möchte, ohne das AR2 zu verwenden?



Mir fällt nur ein sowas wie:
Code:
L P##Adresse1
...
Rechnung
....
T #TEMP_DINT1


L P##Adresse2
...
Rechnung
....
T #TEMP_DINT2


Schleife beginn

L #TEMP_DINT1
TAR1
L W [AR1, P#0.0]


L #TEMP_DINT2
TAR1
TAK
T W [AR1, P#0.0]

L #TEMP_DINT1
L L#16 //2 Bytes dazu
+D
T #TEMP_DINT1

L #TEMP_DINT2
L L#16 //2 Bytes dazu
+D
T #TEMP_DINT2


Schleife Ende


Wenn ich den FB nicht multiinstanzfähig mache, dann funktioniert es aber auch so, auf den ersten Blick- ist das "stillos?".
 
Man kann durchaus auch in multiinstanzfähigen FB das AR2 verwenden/verändern, man muß dann halt lediglich den Inhalt des AR2 sichern, nach dem Ändern des AR2 nicht mehr auf Instanz-Variablen zugreifen, und vor Zugreifen auf Instanz-Variablen das AR2 wiederherstellen. Auf TEMP-Lokalvariablen kann man unabhängig vom AR2 immer zugreifen. Indirekte Adressierung kann man übrigens auch speicherindirekt tun (L DBX [#tempVar]) und kommt dann mit dem AR2 gar nicht in Konflikt.

Harald
 
Wie PN/DP schon schrieb ist an Verwendung von AR2 nichts auszusetzen, aufpassen muss man halt.

Sind deine 2000 Werte im IN-Bereich wirklich Einzelwerte oder liegen die in irgendwelchen Strukturen?
Ich würd mir wahrscheinlich zuerst das gewünschte Rezept in den Temp kopieren, dann die von dir genannten Berechnungen ausführen und danach dort hin kopieren wo es hin soll. Da wäre auch SFC20 wieder denkbar.

Geht eigentlich auch "L DID[#tempVar]"? Bin mir grad nicht sicher.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Man kann durchaus auch in multiinstanzfähigen FB das AR2 verwenden/verändern, man muß dann halt lediglich den Inhalt des AR2 sichern, nach dem Ändern des AR2 nicht mehr auf Instanz-Variablen zugreifen, und vor Zugreifen auf Instanz-Variablen das AR2 wiederherstellen.

Harald


"nach dem Ändern des AR2 nicht mehr auf Instanz-Variablen zugreifen"

Oder wieder 0.0 reinschreiben, das müsste ja auch klappen.
 
"nach dem Ändern des AR2 nicht mehr auf Instanz-Variablen zugreifen"

Oder wieder 0.0 reinschreiben, das müsste ja auch klappen.
Nein, besser den Wert vorher sichern und danach wiederherstellen. Woher weiß der FB, ob da vorher P#DBX0.0 drin stand oder ob der FB als Multiinstanz aufgerufen wurde? Ob man P#DBX0.0 oder den gesicherten Wert in AR2 lädt, hat keinen Einfluß auf die Programmlänge - lediglich das zusätzliche sichern macht das Programm gerade mal 4 Byte länger. Wenn man einen FB als multiinstanzfähig markiert, dann sollte man ihn auch multiinstanzfähig programmieren.
Code:
//FB-Adressregister sichern
      TAR2  #tmp_AR2_Save
      L     DINO
      T     #tmp_DI_Save

//Adressregister für Kopieren initialisieren
      AUF   DB [#tmp_QuellDB]
      LAR1  #tmp_QuellAdr

      AUF   DI [#tmp_ZielDB]
      LAR2  #tmp_ZielAdr

//zwischen 2 DB kopieren
      L     DBD [AR1,P#0.0]
      T     DID [AR2,P#0.0]

//FB-Adressregister wiederherstellen
      LAR2  #tmp_AR2_Save
      AUF   DI [#tmp_DI_Save]

Harald
 
Und das gleiche speicherindirekt ohne Verwendung von AR1 und AR2:
Code:
//FB-Adressregister sichern
      L     DINO
      T     #tmp_DI_Save

//Adressregister für Kopieren initialisieren
      AUF   DB [#tmp_QuellDB]
      AUF   DI [#tmp_ZielDB]

//zwischen 2 DB kopieren
      L     DBD [#tmp_QuellAdr]
      T     DID [#tmp_ZielAdr]

//FB-Adressregister wiederherstellen
      AUF   DI [#tmp_DI_Save]

Harald
 
Zurück
Oben