# Parameter Übergabe in ST



## RobiHerb (5 Mai 2010)

Programmierung in ST: Wie löst man am effektivsten die Übergabe einer grossen STRUCT als Parameter.

VAR_IN_OUT ist anscheinend nur in FB erlaubt, bei einem FUN Aufruf wird die gesamte Datenstruktur kopiert.

Welche Tricks gibt es, um effektiv zu arbeiten, was hat sich bewährt, nimmt man Pointer?


----------



## Neals (5 Mai 2010)

VAR_IN_OUT legt meines wissens immer einen Pointer an. Egal ob FB oder Funktion... falls dem nicht so ist, halt einfach selbst nen Pointer verwenden.


----------



## SBC-User (6 Mai 2010)

VAR_IN legt einen pure-input-pointer an
VAR_OUT legt einen pure-output-pointer an
VAR_IN_OUT legt einen input-pointer an welcher einen return bei weiterverarbeitender routine des VAR_IN erlaubt, in wirklichkeit werden zwei pointer angelegt, spielt aber keine rolle

das var_in_out erlaubt nach e-v-a das ergebniss beim verlassen der funktion auf eine definierte eingangsvariable zu schreiben. in der regel benötigt man das nur für verkettungen wie z.b. regelsequenzen oder ähnliches, mir fällt zumindest ausser knx nichts anderes ein im moment


----------



## RobiHerb (6 Mai 2010)

*Im Prinzip klar, aber ...*

Danke für die Hinweise. Im Prinzip ist mir das schon klar, was da passiert:

Ein VAR_IN_OUT ist das, was in C++ einer Referenz entspricht, ein Pointer, dessen Adresse nicht verändert werden kann, und die Schreibweise vermeidet dann im Programm die eklige ^ Notation.

Soweit ich sehe, ist das mit VAR_IN_OUT aber nur bei FB möglich, von dem ich dann eine Instanz erzeugen muss, die gerade, wenn es mehrfach (z.B. 50 mal) an verschiedenen Stellen gebraucht wird, unnötig viel Speicher verbraucht. 

Deshalb die Frage nach FUN, diesen Konstrukt hält das System nur einmal im Speicher, alle benötigten Infos stecken in den Parametern, aber VAR_IN_OUT ging bei mir schief.


----------



## SBC-User (6 Mai 2010)

ich weiß nicht ob der aktuelle compiler das überhaupt zuläßt, die var-deg müßte dann ja absolut erfolgen (PLC_PRG.Vardieichwill).
Man sollte es aber tunlichst vermeiden variablen in einer fun zu verwenden die nicht inner deklariert sind, die beste variante ist meiner meinung nach in diesem fall eine bit-codiertes byte als var out rauszugeben, damit kannst du je nach codierung bis zu 256 zustände mit einem einzigen byte ausgeben


----------



## M_o_t (9 Mai 2010)

Hallo,

ein FUN lliefert nur ein einziges Ergebnis, also macht eine IN_OUT Variable doch eigentlich keinen Sinn? Ich habe bei meinen Funktionen mit großen Parameterübergaben einen Var_INPUT mit Pointern übergeben.

Gruß

M_o_t


----------



## RobiHerb (9 Mai 2010)

*Ursprüngliche Fragestellung*

meine ursprüngliche Frage ging eigentlich dahin, wie man es am effektivsten und auch elegantesten löst

Ich hatte gedacht, dass auch jemand von 3S das liest und antwortet.


----------



## Benjamin (10 Mai 2010)

Hast du denn überhaupt Probleme mit der Performance? Mir ist die Codepotimierung eigentlich egal. Des macht schließlich der Compiler 

Die SPS-Welt ist etwas anderes als Mikrocontroller. Wenn deine Zykluszeiten zu lange werden, würde ich einfach zur nächst besseren CPU greifen. 

Alternativ die Last auf mehrere CPUs verteilen oder die Funktionen trennen. Ausserdem kann man auch die Programmeinheiten in mehere Tasks aufteilen.

Sich mit Pointern oder Programmierstrategien aus der Computerwelt herumzuschlagen ist meistens am falschen Ende optimiert. Ein Kollege will das Programm auch in 7 Jahren noch nachvollziehen und verändern können.


----------



## RobiHerb (10 Mai 2010)

*So einfach geht das nicht ...*



Benjamin schrieb:


> 1. Hast du denn überhaupt Probleme mit der Performance? Mir ist die Codepotimierung eigentlich egal. Des macht schließlich der Compiler
> 
> 2. Die SPS-Welt ist etwas anderes als Mikrocontroller. Wenn deine Zykluszeiten zu lange werden, würde ich einfach zur nächst besseren CPU greifen.
> 
> ...




Zu 1. ja es gibt Performance Probleme, die Tasks werden ca. 200 msec lang, als Ingenieur versuche ich sowieso so schonend wie möglich mit den Resourcen umzugehen.

Zu 2. es ist eh die schnellste mögliche CPU.

Zu 3. Es wird sowieso aktuell schon auf 6 CPU aufgeteilt, je 2 sind als Sicherheits Tandem SPS jeweils über redundante BUS Systeme verbunden. Der globale Dateneustausch geschieht über 3 getrennte CAN BUS Systeme.

Zu 4. In 7 Jahren hat hoffentlich auch der letzte SPS Programmierer begriffen, dass die SPS nicht in der Steinzeit des Computers stehen bleiben darf.


----------



## Benjamin (10 Mai 2010)

Dann will ich nichts gesagt haben. Ich habe bisher nur kaum jemanden getroffen, der schon mal an die Leistungsgrenze gehen musste und das nicht daran lag, das die billigste CPU verwendet wurde.
Hilft es die Kommunikation in eigene CPUs zu verlagern?



> In 7 Jahren hat hoffentlich auch der letzte SPS Programmierer begriffen,  dass die SPS nicht in der Steinzeit des Computers stehen bleiben darf.


Ich gebe dir vollkommen recht! Nur leider streicht das Gros der SPS-Programmirer schon bei ST die Segel, weil es schon "unglaublich kompliziert und schwierig ist".


----------



## bits'bytes (11 Mai 2010)

RobiHerb schrieb:


> ...
> Soweit ich sehe, ist das mit VAR_IN_OUT aber nur bei FB möglich, von dem ich dann eine Instanz erzeugen muss, die gerade, wenn es mehrfach (z.B. 50 mal) an verschiedenen Stellen gebraucht wird, unnötig viel Speicher verbraucht.
> 
> Deshalb die Frage nach FUN, diesen Konstrukt hält das System nur einmal im Speicher, alle benötigten Infos stecken in den Parametern, aber VAR_IN_OUT ging bei mir schief.



Meiner Meinung nach ist hier kein Unterschied zw. FUB und FUN.

Unterschied zw. FUB und FUN: 

FUN - Rückgabe Parameter, je nach Definition
FUB - keine Rückgabe

FUN - Strukturen per Pointer übergeben, alle Zwischenspeicher, welche gegebenenfalls notwendig sind um ein "Gedächtnis" der Funktion zu erhalten müssen über Übergabe Parameter definiert werden

FUB - wie FUN, wenn Aufruf wie FUN, Jedoch wenn Aufruf 
         abc_fub01 FUB ABC() 
         abc_fub02 FUB ABC()

können die FUBS als Instanz internes Gedächtnis haben.

Der Aufruf ABC(abc_fub01) und ABC(abc_fub02) darf kein internes Gedächtnis verwenden. Entsprechen demnach der FUN, jedoch ohne Rückgabe.

Grundsätzlich immer Pointer verwenden, wobei dann natürlich nur als VAR_IN deklariert, da die Ausgabe einfach durch Beschreiben der Struktur erreicht wird.

Dies ist meine Erfahrung mit B&R, bin mir nicht 100 % sicher ob das auch nach IEC Norm so ist....


----------

