# Statische Variablen funktionieren nicht mehr nach LOOP



## trinkiwinki (5 Oktober 2010)

Hallo Leute,

irgendwas machen wir falsch bei unserem LOOP:

CPU 414-3 PN/DP
Step 7 V5.5

Anbei der Code:

//Analogwerte von PST lesen und in DB40 schreiben
      L     #Analog_Input_Adress
      SLD   3
      T     #Offset_adress_AI
      L     #Start_Adress_DB40
      SLD   3
      T     #Offset_adress_DB40
      LAR1  #Offset_adress_AI
      LAR2  #Offset_adress_DB40
      L     9                          
lop1: T     MW   600
      L     PEW [AR1,P#0.0]             
      ITD   
      DTR   
      AUF   DB    40
      T     DBD [AR2,P#0.0]                  
 +AR1  P#2.0                      
 +AR2  P#4.0
 L     MW   600                
 LOOP  lop1


Wenn wir nun nach diesem Netzwerk eine Statische Variable beschreiben, und vor dem Netzwerk wieder verwenden, ist diese "False".

Was mache ich falsch bei der Sache? Hat jemand eine Idee?

Gruß

Marco


----------



## vierlagig (5 Oktober 2010)

ist es dir möglich die gesamte quelle des bausteins (in code-tags!) zu posten? nur so kann man adressüberschneidungen erkennen...

ich nehme an, der baustein ist a) ein nicht multiinstanzfähiger FB und wird b) nur einmal aufgerufen?


----------



## Verpolt (5 Oktober 2010)

> ich nehme an, der baustein ist a) ein nicht multiinstanzfähiger FB und wird b) nur einmal aufgerufen?



denkst du an AR2 sichern und rückschreiben ?


----------



## vierlagig (5 Oktober 2010)

Verpolt schrieb:


> denkst du an AR2 sichern und rückschreiben ?



mindestens + dem AR1 das AR2 mitgeben (bei multiinstanz)
aber eigentlich glaub ich eher an adressierungsüberschneidungen durch die indirekte adressierung


----------



## NBerger (5 Oktober 2010)

Hi...

Wenn Ihr eine statische Variable beschreibt handelt es sich wohl um einen FB
Sicherlich ist er Multiinstanzfähig. Also MUSS AR2 gesichert und nach der Verwendung wieder hergestellt werden! Sonnst sind alle weiteren Instanzzugriffe falsch!
Gruss
Norbert


----------



## Verpolt (5 Oktober 2010)

> Wenn Ihr eine statische Variable beschreibt handelt es sich wohl um einen FB
> Sicherlich ist er *Multiinstanzfähig*



woher willst du das wissen?

Und er hat Globaldatenzugriffe mit drin 



> Also MUSS AR2 gesichert und nach der Verwendung wieder hergestellt werden!



*ACK*


----------



## trinkiwinki (5 Oktober 2010)

NBerger schrieb:


> Hi...
> 
> Wenn Ihr eine statische Variable beschreibt handelt es sich wohl um einen FB
> Sicherlich ist er Multiinstanzfähig. Also MUSS AR2 gesichert und nach der Verwendung wieder hergestellt werden! Sonnst sind alle weiteren Instanzzugriffe falsch!
> ...


 

Hallo Norbert,

der FB ist multiinstanzfähig. Hat das was mit dem TAR Befehl zu tun?

Gruß


----------



## trinkiwinki (5 Oktober 2010)

So funktionierts. Danke an alle....... echt ein klasse Forum......




  TAR1  
      TAR2  
      LAR1  #Offset_adress_AI
      LAR2  #Offset_adress_DB40
      L     9                           //Schleifenzähler 9 Durchgänge
lop1: T     MW   600
      L     PEW [AR1,P#0.0]             //Inhalt des adressierten Datenwortes lesen
      ITD   
      DTR   
      AUF   DB    40
      T     DBD [AR2,P#0.0]             //Inhalt des Akkus in adressiertes Datenwort
      +AR1  P#2.0                       //Pointer auf Datenwort x + 12 Worte setzen
      +AR2  P#4.0
      L     MW   600                    //Schleifenzähler in Akku laden
      LOOP  lop1
      LAR1  
      LAR2


----------



## vierlagig (5 Oktober 2010)

trinkiwinki schrieb:


> So funktionierts. Danke an alle....... echt ein klasse Forum......



nur sauber programmieren bringt dir hier keiner bei...leider!

(ich geh davon aus, dass hinter TAR1 und TAR2 noch ne variable steht ...)


----------



## SPSKILLER (5 Oktober 2010)

vierlagig schrieb:


> (ich geh davon aus, dass hinter TAR1 und TAR2 noch ne variable steht ...)


 
nee. sicher net.

Das mit dem Beschreiben der ARs hinter dem Loop ist eigentlich genial, solange der Baustein nicht als Multiinstanz verwendet wird.

Da bin ich in 15 Jahren nicht drauf gekommen...


----------



## vierlagig (5 Oktober 2010)

SPSKILLER schrieb:


> nee. sicher net.
> 
> Das mit dem Beschreiben der ARs hinter dem Loop ist eigentlich genial, solange der Baustein nicht als Multiinstanz verwendet wird.
> 
> Da bin ich in 15 Jahren nicht drauf gekommen...



hab grad keine hilfe zur hand... was schreibt LAR2 wenn es leer ist? doch den inhalt von akku1 und der ist nach verlassen der schleife NULL ... ist das der trick? kann man ja dann das TAR2 weg lassen...


----------



## SPSKILLER (5 Oktober 2010)

genau. brauchst dann nicht zu sichern.


----------



## vierlagig (5 Oktober 2010)

SPSKILLER schrieb:


> genau. brauchst dann nicht zu sichern.



du bist der erfahrenere von uns beiden: du verlässt dich drauf?


----------



## trinkiwinki (6 Oktober 2010)

SPSKILLER schrieb:


> nee. sicher net.
> 
> Das mit dem Beschreiben der ARs hinter dem Loop ist eigentlich genial, solange der Baustein nicht als Multiinstanz verwendet wird.
> 
> Da bin ich in 15 Jahren nicht drauf gekommen...


 
An das habe ich natürlich nicht gedacht. Der Baustein soll in einem FB 15 mal aufgerufen werden und dann als Multiinstanz......

Das würde dann eben bestimmt nicht mehr funktionieren.....oder? Wenn ich für jeden einen DB nehme, dann schon..... Richtig?

Gruß


----------



## Züttu (6 Oktober 2010)

Ohne Variablen hinter TAR2 und LAR2 kanns nicht funktionieren

Im AR2 und DI Register werden bei einem FB-Aufruf die Adressen der STAT-Register abgelegt, daher musst du diese vorher sichern.

TAR2 #temp_AR2
LAR1 #Offset_adress_AI
LAR2 #Offset_adress_DB40
L 9 //Schleifenzähler 9 Durchgänge
lop1: T MW 600
L PEW [AR1,P#0.0] //Inhalt des adressierten Datenwortes lesen
ITD 
DTR 
AUF DB 40
T DBD [AR2,P#0.0] //Inhalt des Akkus in adressiertes Datenwort
+AR1 P#2.0 //Pointer auf Datenwort x + 12 Worte setzen
+AR2 P#4.0
L MW 600 //Schleifenzähler in Akku laden
LOOP lop1
LAR2 #temp_AR2

ich habs nicht getestet, müsste aber so klappen.


----------



## Züttu (6 Oktober 2010)

Was ich auch nicht verstehe, wieso du den Schleifen Index als MW ausführst und nicht als TEMP Variable?? 
Aber es ist auch noch früh am Morgen, vielleicht versteh ichs einfach nicht....


----------



## SPSKILLER (6 Oktober 2010)

trinkiwinki schrieb:


> An das habe ich natürlich nicht gedacht. Der Baustein soll in einem FB 15 mal aufgerufen werden und dann als Multiinstanz......
> 
> Das würde dann eben bestimmt nicht mehr funktionieren.....oder? Wenn ich für jeden einen DB nehme, dann schon..... Richtig?
> 
> Gruß


 
richtig.

Als Multiinstanz sollte die Variante von Züttu funktionieren.

Die Variable #temp_AR2 ist dabei eine Interne Variable vom Typ DWORD...

edit: Das MW hat da natürlich nix zu suchen, auch wenns funktionieren wird.
Da sollte imho eine Temp Variable vom Typ INT genommen werden.

@4L
Ich würde das nicht so machen, wäre aber auch niemals auf die Idee gekommen es so zu machen.

Micha


----------



## vierlagig (6 Oktober 2010)

zur multiinstanzfähigkeit muß noch gesagt werden, dass das AR1 um das AR2 zum bausteinstart erhöht werden muß (hier kommt dann auch der punkt, wo die einfache LAR2 lösung in MI nicht funktioniert...)

ansonsten: ja, das MW600 bewegte mich im wesentlichen zu meiner aussage, dass dir hier keiner einen sauberen stil bei zu bringen vermag...


----------



## PN/DP (6 Oktober 2010)

SPSKILLER schrieb:


> @4L
> Ich würde das nicht so machen, wäre aber auch niemals auf die Idee gekommen es so zu machen.


Kannste nicht ganz eindeutig schreiben, daß Dein Beitrag #10 ein *Witz* war?
Der Beitrag wird wohl von einigen Lesern für bare Münze genommen werden. 

Harald


----------



## trinkiwinki (6 Oktober 2010)

...... wer lesen kann ist klar im VOrteil....

TAR2 #temp_AR2
 ist diese TEMP oder STAT? Ich gehe von STAT aus....

Gruß


----------



## PN/DP (6 Oktober 2010)

trinkiwinki schrieb:


> TAR2 #temp_AR2
> ist diese TEMP oder STAT? Ich gehe von STAT aus....


TEMP reicht.
Warum wohl hat Züttu die Variable *#temp*_AR2 genannt?

Harald


----------



## trinkiwinki (6 Oktober 2010)

PN/DP schrieb:


> TEMP reicht.
> Warum wohl hat Züttu die Variable *#temp*_AR2 genannt?
> 
> Harald


 

OK hast recht....Entschuldigung

ABer so kann ich es nicht schreiben:

TAR2 #temp_AR2      'Temp_AR2 wird ROT

Muß das evtl. so heißen:

L  #temp_AR2
TAR2

?

Gruß


----------



## PN/DP (6 Oktober 2010)

Hast Du eine TEMP-Variable "temp_AR2" als DWORD angelegt?

Harald


----------



## trinkiwinki (6 Oktober 2010)

PN/DP schrieb:


> Hast Du eine TEMP-Variable "temp_AR2" als DWORD angelegt?
> 
> Harald


 

Ja. Halt noch im STAT Bereich, aber das sollte ja eigentlich keine ROlle spielen....
Gruß


----------



## Züttu (6 Oktober 2010)

Das spielt sehr wohl eine Rolle, denn du weisst nicht mehr wo dein STAT-Register liegt, das steht ja in temp_AR2. Wenn du temp_AR2 im TEMP anlegst wird auch der Aufruf nicht mehr rot


----------



## trinkiwinki (6 Oktober 2010)

Züttu schrieb:


> Das spielt sehr wohl eine Rolle, denn du weisst nicht mehr wo dein STAT-Register liegt, das steht ja in temp_AR2. Wenn du temp_AR2 im TEMP anlegst wird auch der Aufruf nicht mehr rot


 

Alles klar. Ist nun in Ordnung.


DANKE vielmals an alle, die mir geholfen haben, das zu verstehen.......


Gruß

Marco


----------



## PN/DP (6 Oktober 2010)

Doch, das spielt eine Rolle. Es darf nicht STAT sein.
LAR2 #temp_AR2 wäre sogar gar nicht möglich, wenn temp_AR2 in STAT liegen würde.

Was sagt die Fehlermeldung zur rot markierten Zeile?: "*Anweisung nicht erlaubt für AR1/AR2-Befehls-Operanden*"

Auch wichtig:

```
...
LAR2 #Offset_adress_DB40
...
[COLOR="Red"]// hier kann nicht auf STAT-Variablen zugegriffen werden![/COLOR]
...
LAR2 #temp_AR2
// erst wieder ab hier
```

Harald


----------



## SPSKILLER (6 Oktober 2010)

PN/DP schrieb:


> Kannste nicht ganz eindeutig schreiben, daß Dein Beitrag #10 ein *Witz* war?
> Der Beitrag wird wohl von einigen Lesern für bare Münze genommen werden.
> 
> Harald


 
Hey Harald,

was soll die scheiss Anmache?

Nicht mal du als "push" User (wird ja immer als besonders nützlich hervorgerufen *ROFL*) kannst leugnen, dass mein Beitrag #10 richtig ist ist.

Du bist nur der gleiche Depp wie ich, der da niemals drauf gekommen wäre.
Es funktioniert so, und es ist ohne Multiinstanz einfach kürzer als das AR2 zu retten.

Du legst du ja immer wert drauf den kürzesten Code zu posten.

Alle weiterne Einschränkungen hatte ich bereits geschildert.

Ich hoffe mal, dass dein Image des besten Programmierers unter der Sonne dadurch nicht allzu sehr leidet...

Micha


----------



## PN/DP (7 Oktober 2010)

SPSKILLER schrieb:


> PN/DP schrieb:
> 
> 
> > Kannste nicht ganz eindeutig schreiben, daß Dein Beitrag #10 ein *Witz* war?
> ...


Hallo Micha,

was soll denn jetzt Deine echte "scheiss Anmache"? 
Ich war ehrlich davon überzeugt, daß Dein Beitrag #10 nur ein Witz sein kann.


SPSKILLER schrieb:


> vierlagig schrieb:
> 
> 
> > (ich geh davon aus, dass hinter TAR1 und TAR2 noch ne variable steht ...)
> ...



Mit Programmiererfahrung kann man doch nicht wirklich glauben, daß LAR1 + LAR2 hinter LOOP irgendwas sinnvolles bewirkt, außer 
die ARs auf 0 zu schreiben. Mit retten und und wieder herstellen hat das überhaupt nichts zu tun ... es ist noch nicht mal besonders 
kurz, weil komplett überflüssig. Also ich leugne ausdrücklich, daß an solchem Code irgend etwas richtig ist und funktioniert. 

4L hat ja versucht, Dir diplomatisch und schonend beizubringen, daß Du auf dem Holzweg bist, falls Dein Beitrag ernst gemeint war.

Es ging trinkiwinki im Übrigen gerade darum, wegen Multiinstanz die Adressregister zu retten und *wieder herzustellen.*

Weil kürzlich in einem anderen Thread ein User (angeblich mit vollem Wissen) einen nicht richtig funktionierenden Beispielcode postete, 
der zum STOP der CPU führen kann, habe ich Dich einfach gebeten, Deinen vermeintlichen Witz aufzuklären.

Und was Deine weiteren Ausflüsse angeht:
Willst Du nicht am Freitag zum Forum-Stammtisch nach Bielefeld kommen? Da könnten wir schön ein Bier zusammen trinken und Du sagst 
mir mal ins Gesicht, was Dir an mir nicht passt (gut programmieren können ist doch kein Übel). 
Vielleicht kann ich ja mein Auftreten hier noch verbessern.

:sm24:
Prost
Harald


----------



## Perfektionist (7 Oktober 2010)

Damit auch ich das nun endlich begreife ...

Ich dachte, es ist so, dass AR1 zur freien Verfügung steht. Wenn ich also garnicht erst mit AR2 rumhantiere, dann ich auch keine Falle stelle, wo vorübergehend der Zugriff auf die Lokaldaten fehl geht, da man ja AR2 in einem multiinstanzfähigen Baustein verbogen hat. Fazit: wenn man mit einem Quell- und Zielzeiger arbeiten muss, läd man die, wenn auch laufzeituneffektiver, wechselseitig in AR1. Und lässt die Codeakrobatik mit AR2 bleiben, um nicht in die Falle zu treten, dass während verbogenem AR2 der Zugriff auf Lokaldaten in die Hose geht.

... und irgendwie ist das dann doch sinnvoll, in AR2 eine Null zu laden, wenn, ich will es mal Root-Instanz nennen, wenn also der Baustein wie in dem gezeigten Fall auf eine Root-Instanz zugreift. Sowie in AR2 ein Offset steht, weil der gerade bearbeitete Baustein mit einer Multiinstanz aufgerufen wurde, ist es natürlich nicht mehr sinnvoll, dann AR2 mit Null zu füttern. Gut - der Beispielcode, der da die Null in AR2 läd, ist nicht mit voller Absicht entstanden.


----------



## Perfektionist (7 Oktober 2010)

vierlagig schrieb:


> zur multiinstanzfähigkeit muß noch gesagt werden, dass das AR1 um das AR2 zum bausteinstart erhöht werden muß.


Dafür Danke. Den Aspekt habe ich zwar irgendwo schonmal gelesen, wäre aber sicher erstmal drüber gestolpert, hätte ichs dann selbst machen sollen. Bislang hab ich halt nur in Nicht-Multiinstanzen rumgepointert. (Vielleicht sollte ich mal wieder die FAQ des Forums durchgehen.)


----------



## SPSKILLER (7 Oktober 2010)

Hallo,



> Und was Deine weiteren Ausflüsse angeht:
> Willst Du nicht am Freitag zum Forum-Stammtisch nach Bielefeld kommen? Da könnten wir schön ein Bier zusammen trinken und Du sagst
> mir mal ins Gesicht, was Dir an mir nicht passt (gut programmieren können ist doch kein Übel).
> Vielleicht kann ich ja mein Auftreten hier noch verbessern.


 
ich bin grad in Polen zur IBN.
Deshalb scheidet der Vorschlag leider aus.
Ausserdem habe ich nix gegen dich, ich kenn dich doch überhaupt nicht.

Es kommt bei deinen Beiträgen halt oft der Klugscheisser rüber.
Das ist meine Meinung.
Wem das nicht passt, sorry.

Ich meine hier NIX persönlich.

Jetzt noch mal fachlich:



> Mit Programmiererfahrung kann man doch nicht wirklich glauben, daß LAR1 + LAR2 hinter LOOP irgendwas sinnvolles bewirkt, außer
> die ARs auf 0 zu schreiben. Mit retten und und wieder herstellen hat das überhaupt nichts zu tun ... es ist noch nicht mal besonders
> kurz, weil komplett überflüssig. Also ich leugne ausdrücklich, daß an solchem Code irgend etwas richtig ist und funktioniert.


 
Das hat sehr wohl was mit "wieder herstellen" zu tun.
In einem FB, der nicht als Multiinstanz aufgerufen wird ist AR2 beim Aufruf 0.
Wenn das AR2 während der Bearbeitung des FBs verändert wird (im Beispiel hier in der Schleife), dann muss es mit P#0.0 restauriert werden - wenn danach noch auf Instanzdaten zugegriffen werden soll.
P#0.0 ist auch nur ne 0 im Akku 1, deshalb kann man direkt nach der Schleife einfach LAR2 schreiben um AR2 wieder auf 0 zu setzen.
AR1 zu retten ist Quatsch. Brauchts nicht.

Was soll jetzt daran nicht funktionieren 

Es ist nur so wie der Perfektionist geschrieben hat:


> Gut - der Beispielcode, der da die Null in AR2 läd, ist nicht mit voller Absicht entstanden.


 
Ich wollte eigentlich nur sagen, dass ich nicht auf die Idee gekommen wäre mein AR2 so zu "nullen". Dazu muss man anders denken.

Bevor jetzt wieder jemand draufhaut: Klar kann eine Schleife durch einen Sprung verlassen werden, wodurch der Zähler nicht auf 0 runterläuft, aber das interessiert in dem Beispiel nicht.

@Perfektionist

Du hast das schon verstanden!
Aber das Verbiegen des AR2 ermöglicht trotzdem Lokaldatenzugriffe, man kann die Variablen der Instanz aber nur noch indirekt ansprechen...

Micha


----------



## vierlagig (7 Oktober 2010)

*räusper* ... man muß natürlich sicherstellen, dass der AKKU auch wirlich 0 ist ...


----------



## SPSKILLER (7 Oktober 2010)

was soll da in dem Beispiel denn sonst drin stehen?


----------



## vierlagig (7 Oktober 2010)

SPSKILLER schrieb:


> was soll da in dem Beispiel denn sonst drin stehen?



in dem beispiel nicht viel, aber soll auch fälle geben, in denen man eine schleife vorzeitig bedingt verlässt ... 

mir ist das ja sowieso alles wurscht, ich schreib FBs grundsätzlich MI-fähig...


----------



## SPSKILLER (7 Oktober 2010)

mann, ich hab gewusst, dass das kommt 
Lies mal #32 richtig!


----------



## vierlagig (7 Oktober 2010)

SPSKILLER schrieb:


> mann, ich hab gewusst, dass das kommt
> Lies mal #32 richtig!



ja, da ist der verweis auf die 0 nach der schleife drin, aber es ist eben nicht nach jeder schleife 0


----------



## SPSKILLER (7 Oktober 2010)

noch mal für dich:


> Bevor jetzt wieder jemand draufhaut: Klar kann eine Schleife durch einen Sprung verlassen werden, wodurch der Zähler nicht auf 0 runterläuft, aber das interessiert in dem Beispiel nicht.


----------



## PN/DP (8 Oktober 2010)

SPSKILLER schrieb:


> ich bin grad in Polen zur IBN.
> Deshalb scheidet der Vorschlag leider aus.


Das ist schade. Vielleicht laufen wir uns irgendwann mal über den Weg, dann steht mein Angebot mit dem Bier und dem Unterhalten.



> Es kommt bei deinen Beiträgen halt oft der Klugscheisser rüber.


Tja, das ist schon seit meiner Schulzeit mein Problem, daß andere Leute mein Besser-Wissen und meinen Hang zur Perfektion als Klugscheisserei empfinden.
Deshalb korrigiere ich andere Leute normalerweise nur noch, wenn ich direkt gefragt werde. Hier im Forum fühle ich mich direkt gefragt. 
Ich war bisher der Meinung, daß meine Beiträge überwiegend nützlich waren und oft neues nicht allgemein vorhandenes Wissen und Knowhow rüberbringen.



> Das ist meine Meinung.
> Wem das nicht passt, sorry.


Ich habe nicht gesagt, daß mir Deine Meinung nicht passt. Ich habe eher gefragt, was Dir an mir nicht passt. Was Du ja nun beantwortet hast.
Hier im Forum kann zum Glück jeder seine Meinung schreiben - wenn er das Echo verträgt. 



> Ich meine hier NIX persönlich.


Dies hier klingt aber doch ein bißchen persönlich: 


SPSKILLER schrieb:


> Ich hoffe mal, dass dein Image des besten Programmierers unter der Sonne dadurch nicht allzu sehr leidet...






> Jetzt noch mal fachlich:
> 
> Das hat sehr wohl was mit "wieder herstellen" zu tun.
> In einem FB, der nicht als Multiinstanz aufgerufen wird ist AR2 beim Aufruf 0.
> Wenn das AR2 während der Bearbeitung des FBs verändert wird (im Beispiel hier in der Schleife), dann muss es mit P#0.0 restauriert werden - wenn danach noch auf Instanzdaten zugegriffen werden soll.


Das ist nicht ganz richtig.
Das AR2 ist beim FB-Aufruf DW#16#84000000 = P#DBX0.0 . Später P#0.0 in AR2 schreiben ist genau genommen keine korrekte Restauration.
Doch zum Glück wird beim Zugriff auf Multi-Instanzdaten die Bereichskennung im AR2 ignoriert und immer durch DIB (16#85..) ersetzt.

In einem Nicht-Multiinstanz-fähigen FB wird das AR2 gar nicht für den Zugriff auf die Instanzdaten verwendet.
AR2 kann beliebig manipuliert werden und ein wieder-Herstellen wegen Zugriff auf Instanzdaten ist folglich überflüssig.

Der Code in einem Multiinstanz-fähigen FB muß imho immer Multiinstanz-verträglich programmiert sein (auch wenn er momentan nicht als 
Multiinstanz verwendet wird), was bei Benutzung des AR2 ein korrektes wieder-Herstellen erfordert.
Einfach P#0.0 (oder P#DBX0.0) in AR2 schreiben ("ich weiß ja, daß ich diesen Multiinstanz-fähigen Baustein NIE als Multiinstanz benutze") ist 
imho nicht korrekt, auch wenn es in dem speziellen Fall funktioniert.

Wenn man einen FB schreibt, der nicht als Multiinstanz verwendet werden soll, dann sollte man den auch als "nicht Multiinstanz-fähig" anlegen.
Netter Nebeneffekt: der MC7-Code des Bausteins wird dann kürzer.



> AR1 zu retten ist Quatsch. Brauchts nicht.


Das will ich nicht so allgemein stehen lassen.
Das AR2 wird beim Aufruf eines anderen FB automatisch gesichert und wieder hergestellt, das AR1 aber nicht.
Wird nun in einem Baustein A, der AR1 benutzt, ein weiterer Baustein B aufgerufen, der ebenfalls das AR1 benutzt, dann erwarte ich, daß der 
Baustein B das AR1 unverändert an Baustein A zurückgibt - das AR1 also ggf. sichert und restauriert.

Es kann nicht schaden, Bausteine immer so zu programmieren, daß man bei Nutzung dieser Bausteine nicht erst deren Code durchlesen muß, 
um zu sehen, ob diese mit dem aufrufenden Baustein verträglich sind.



> Ich wollte eigentlich nur sagen, dass ich nicht auf die Idee gekommen wäre mein AR2 so zu "nullen". Dazu muss man anders denken.
> 
> Bevor jetzt wieder jemand draufhaut: Klar kann eine Schleife durch einen Sprung verlassen werden, wodurch der Zähler nicht auf 0 runterläuft, aber das interessiert in dem Beispiel nicht.


Wenn ich tatsächlich mal das AR2 nach einer Schleife "nullen" wollte oder ganz allgemein an irgendeiner Programmstelle einen bestimmten Wert 
im AKKU1 brauche, aber nicht extra laden will, weil dieser Wert glücklicherweise schon drin steht, dann schreibe ich das Laden dieses Wertes 
als auskommentierte Zeile dazu. Dann beachte ich diese Bedingung, wenn ich später mal den Code ändern muß:

```
...
      LOOP  lop1
[COLOR="DarkGreen"]//      L     P#0.0       //P#0.0 steht schon im AKKU1[/COLOR]
      LAR2
```

So, nun aber auf nach Bielefeld. 
Harald


----------



## Perfektionist (8 Oktober 2010)

Vorweg: es regt sich bei mir der Widerspruchsgeist, obwohl ich 99% von dem Geschriebenen für richtig befinde.





PN/DP schrieb:


> Das will ich nicht so allgemein stehen lassen.
> Das AR2 wird beim Aufruf eines anderen FB automatisch gesichert und wieder hergestellt, das AR1 aber nicht.
> Wird nun in einem Baustein A, der AR1 benutzt, ein weiterer Baustein B aufgerufen, der ebenfalls das AR1 benutzt, dann erwarte ich, daß der
> Baustein B das AR1 unverändert an Baustein A zurückgibt - das AR1 also ggf. sichert und restauriert.


Werden die Flags automatisch gesichert? Die Akkus werden jedenfalls nicht automatisch gesichert. Das ist sicherlich ein schöner Dienst, den ein FB einem erweisen kann, indem er das AR1 unangetastet lässt. Da mir aber als aufrufender Baustein bewusst sein muss, dass auch dem aufgerufenen Baustein das AR1 zur Verfügung steht und ich als Aufrufender weiss, dass der Aufgerufene mit Akku, Flags und AR1 tun und lassen darf, was er will, muss ich mich selbst vor Aufruf drum kümmern, dass ich meine Werte rette.

Dass das AR2 automatisch gesichert wird ist dem Umstand geschuldet, dass das AR2 dem Anwenderprogramm nicht wirklich zur Verfügung steht. Wenn jemand das AR2 sichert, dann damit hantiert und es danach restauriert, dann hat er sich das AR2 nur vorübergehend vom System ausgeliehen.


----------



## PN/DP (8 Oktober 2010)

Perfektionist schrieb:


> Da mir aber als aufrufender Baustein bewusst sein muss, dass auch dem aufgerufenen Baustein das AR1 zur Verfügung steht und ich als Aufrufender weiss, dass der Aufgerufene mit Akku, Flags und AR1 tun und lassen darf, was er will, muss ich mich selbst vor Aufruf drum kümmern, dass ich meine Werte rette.


Stimmt, da hast Du recht. Es ist besser so.
Meine Erwartung, daß das AR1 unangetastet zurückkommen soll, ist wohl meinen Erfahrungen bei der Assembler-Programmierung von Prozessoren geschuldet.

Harald


----------



## Perfektionist (8 Oktober 2010)

Ich bin jetzt nur noch am Grübeln, wie das innerhalb von Interruptroutinen aussieht. Um Akku und Flags und sicher auch um das AR2 kümmert sich ja das System, wenn z.B. OB35 gestartet oder beendet werden soll. Ich frage mich, wo man das jetzt nachlesen kann, was mit dem AR1 geschieht.

Es gibt übrigens einen Fall, wo das AR1 bereits durch den Call verbogen wird - da hat dann der aufgerufene Baustein keine Chance mehr, das AR1 unangetastet zu lassen:


> In den folgenden Situationen werden die Inhalte des Adressregisters AR1 und des DB-Registers des
> aufrufenden Bausteins überschrieben:​
> 
> 
> ...


Quelle: Handbuch "STEP 7 - Programmieren mit STEP 7" im Lieferumfang der Software, Seite 330 (05/2010, A5E02789665-01), Kapitel 15.8 "Vermeiden von Fehlern beim Aufrufen von Bausteinen"​

Sorry, dass das jetzt ziemlich zerrissen ist - ich hab das aus einer Tabelle des PDF rauskopiert (und bin jetzt ein wenig faul, das auch noch in Form zu bringen).​


EDIT:





> und sicher auch um das AR2 kümmert sich ja das System, wenn z.B. OB35 gestartet oder beendet werden soll.


ähhhmmmm, nein, nicht sicher. Das AR2 braucht ja erst beim Auftreten eines Call innerhalb des OB35 weggeräumt und danach wiederhergestellt zu werden. Oder?


----------



## SPSKILLER (8 Oktober 2010)

Hi Harald,


> Ich war bisher der Meinung, daß meine Beiträge überwiegend nützlich waren und oft neues nicht allgemein vorhandenes Wissen und Knowhow rüberbringen.


Dagegen habe ich kein Argument, und suche auch keines.
Deine Beiträge sind fachlich zu 99,99% richtig, und nie unüberlegt geschrieben.
Über deine Fachkentnisse brauchen wir nicht zu diskutieren.

Aber da ist halt die Haarspalterei.
Was nützt mir ne Aussage wie:


> Das ist nicht ganz richtig.
> Das AR2 ist beim FB-Aufruf DW#16#84000000 = P#DBX0.0 . Später P#0.0 in AR2 schreiben ist genau genommen keine korrekte Restauration.
> Doch zum Glück wird beim Zugriff auf Multi-Instanzdaten die Bereichskennung im AR2 ignoriert und immer durch DIB (16#85..) ersetzt.


Wen interessiert das?
Das ist mir viel zu theoretisch.
Du hast ja mittlerweile selbst geschrieben, dass es doch so funktioniert.
Ich bin Praktiker.
Sag mal ehrlich: Hast du das mit dem "DW#16#84000000" auswendig gelernt, oder ausprobiert???
Ich habe einfach so gepostet.
Aber ich wusste, dass ne "null" das AR2 restauriert (ohne Multiinstanz).


> Wenn man einen FB schreibt, der nicht als Multiinstanz verwendet werden soll, dann sollte man den auch als "nicht Multiinstanz-fähig" anlegen.
> Netter Nebeneffekt: der MC7-Code des Bausteins wird dann kürzer.


Das ist auch richtig, aber wer hakt denn den Multiinstanzhaken schon ab???


> Das will ich nicht so allgemein stehen lassen.
> Das AR2 wird beim Aufruf eines anderen FB automatisch gesichert und wieder hergestellt, das AR1 aber nicht.
> Wird nun in einem Baustein A, der AR1 benutzt, ein weiterer Baustein B aufgerufen, der ebenfalls das AR1 benutzt, dann erwarte ich, daß der
> Baustein B das AR1 unverändert an Baustein A zurückgibt - das AR1 also ggf. sichert und restauriert.
> ...


Dazu erst mal danke am den Perfektionisten.
Er ist mir zuvor gekommen.
Aber da hast ja auch schon eingelenkt.

Eines möchte ich noch mal betonen:
Ich verwende den im Beispiel genannten Code nicht.
Aber ich fand die Idee!? nicht schlecht.
Meine Bausteine sind sauber restauriert.

Da halt ichs wie Kollege 4L:


> mir ist das ja sowieso alles wurscht, ich schreib FBs grundsätzlich MI-fähig...


@Perfektionist:


> ähhhmmmm, nein, nicht sicher. Das AR2 braucht ja erst beim Auftreten eines Call innerhalb des OB35 weggeräumt und danach wiederhergestellt zu werden. Oder?


Ich verstehe nicht genau was du damit meinst.
Aber ich würde nie Variablen in einem Baustein über AR1 oder AR2 lesen oder beschreiben, bevor ich die AR nicht definiert habe.
Damit bist du immer aus der theoretischen Kacke raus.
Das Ganze ist recht ähnlich zu Lokalvariablen, die vor einem lesenden Zugriff beschrieben werden müssen.

Ansonsten liebe ich es mal ein oder ... Bier zu trinken, gerne auch mit dir Harald.

Bis dann.

Micha


----------



## Perfektionist (8 Oktober 2010)

SPSKILLER schrieb:


> Dazu erst mal danke am den Perfektionisten.
> Er ist mir zuvor gekommen.


Sorry. Da hatte ich nicht die Geduld, auf Deine Reaktion zu warten.



SPSKILLER schrieb:


> @Perfektionist:
> Ich verstehe nicht genau was du damit meinst.


Zunächst dachte ich, AR2 würde sicherlich beim Auftreten eines Interrupts (z.B. OB35) durch das System, also S7, gesichert und restauriert werden. Dann fiel mir auf, dass dies nicht beim Auftreten bzw. Abschliessen eines Interrupts notwendig ist, sondern es ausreichen würde, wie bei einem normalen Call innerhalb des OB1 das Register AR2 zu sichern und beim Rücksprung zu restaurieren.


----------



## Thomas_v2.1 (8 Oktober 2010)

Perfektionist schrieb:


> Zunächst dachte ich, AR2 würde sicherlich beim Auftreten eines Interrupts (z.B. OB35) durch das System, also S7, gesichert und restauriert werden. Dann fiel mir auf, dass dies nicht beim Auftreten bzw. Abschliessen eines Interrupts notwendig ist, sondern es ausreichen würde, wie bei einem normalen Call innerhalb des OB1 das Register AR2 zu sichern und beim Rücksprung zu restaurieren.



Das habt ihr doch vor zwei Jahren schon ausdiskutiert:
http://www.sps-forum.de/showthread.php?t=21473
Siemens FAQ gibts sogar auch, das ist doch was für PN zum Verlinken.

Dass man bei Alarm-OBs was selber sichern muss wird ja schon was sowas wie eine Urban Legend...


----------



## SPSKILLER (8 Oktober 2010)

meine späte Reaktion ist auf die schlechte Infrastrucktur in Polen (Ostroleka) zurückzuführen.
Aber besser hätte ich es ohnehin nicht schreiben können.
Ich bin Schwabe 
Mit dem Hochdeutsch haben wirs nicht so...

Ansonsten liegst du 100% richtig.


----------



## Perfektionist (8 Oktober 2010)

Perfektionist schrieb:


> Werden die Flags automatisch gesichert?


Für diejenigen Leser, die nicht einen F1-Tastenschlag von dieser Information entfernt sitzen: die Flags (Statusregister), die die Binärverknüpfungen betreffen, werden bei Aufruf und Beendigung eines Bausteins auf Standardwerte gesetzt, sodass grundsätzlich eine neue Verknüpfungskette beginnen kann. Die Flags, die z.B. das Ergebnis von Vergleichsoperationen anzeigen, bleiben jedoch unverändert.


----------

