TIA Array vom Datentyp Variant/Any/Pointer

Jasko81

Level-1
Beiträge
14
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Array vom Datentyp Variant/Any/Pointer/REF_TO

Hallo,


ich bin auf der Suche nach einer Lösung für folgende Herausforderung:
Ich bekomme auf meiner funktion per InOut eine (bekannte) Struktur übergeben.
In dieser Struktur sind Variablen für mich zu lesen, und eine zu schreiben (pro Struktur)

-> Da jede Struktur ident ist, kopiere ich mir das ganze momentan auf ein temporäres Array, arbeite damit rum & schreibs am ende wieder auf die IO-Struktur zurück.
Gefällt mir nicht - braucht Zykluszeit & die Funktion wird oft benötigt (~100 Aufrufe/Zyklus).
(Allerdings kann ich mit dem temp-Array schön mit Schleifen und indiziert arbeiten)

Da das ganze mit funktionierenden Pointern eigentlich unnötig wäre wollte ich mir ganz gerne einen Pointer auf die IO Struktur Referenzieren und den übergebenen Datenbereich gleich direkt beschreiben, ohne unnötiges hin und herkopieren.
Aber:
Weder im optimierten noch im klassischen Speicher lässt mich TIA ein brauchbares (Pointer-)Array definieren.
-> Arbeite ich ohne Array, sprich ich arbeite mit der referenz oder dem Variant funktionieren die Abfragen/Zuweisungen problemlos, allerdings verliere ich alles was ich mit einem Array gewinne..
In der Hilfe von Siemens kann ich allerdings diesbezüglich keine Einschränkungen für Array oder die zeiger (parameter-)datentypen finden, lediglich, dass ich kein Array vom datentyp Array anlegen kann.
Hab' ich hier einen generellen Denkfehler oder hat jemand einen anderen Vorschlag?
(Die Strukturen als Array übergeben würde das hässliche nur nach draussen schieben & auch unnötig Zykluszeit brauchen)


Vielen Dank für jede Hilfe :)
Jasko

CPU: 1500er
TIA Version: V15

decla_merge_4_to_1.png
 
Zuletzt bearbeitet:
Liegen diese 5 Strukturen die du als Parameter übergibst in einem Array außerhalb (z.B. in einem Global-DB) oder sind es Einzelvariablen?
Wenn in einem Array, dann könntest du das gesamte Array als Parameter übergeben, und an Pos1..5 nur die Indizes, die du dann in einem Array ablegen kannst um in einer Schleife darauf zuzugreifen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Liegen diese 5 Strukturen die du als Parameter übergibst in einem Array außerhalb (z.B. in einem Global-DB) oder sind es Einzelvariablen?

nope, leider, sonst wärs ja viel zu einfach.. :)
Die 4 Strukturen um dies in dem Beispiel oben geht(IO_PM_HS_Entry_Pos_1-4)(Die 5. Variant-Struktur war vom testen übriggeblieben und ist leider in den Screenie gerutscht), sind im prinzip die 4 Handshake strukturen von 4 Förderlementen, welche auf ein weiteres Förderelement zusammengeführt werden sollten.

Allerdings würde ich ein solches Array auch fürr jede Multiplexer-Anwendung als sehr praktisch empfinden.

Danke,
Jasko
 
Zuletzt bearbeitet:
Ich habe die V15 noch nicht verwendet, aber mit REF_TO das es seit V15 gibt sollte das hoffentlich funktionieren.
Nur in deinem Fall sind die InOut Variablen auf Strukturen ja schon Zeiger, und dann hättest du mit REF_TO ein Zeiger auf einen Zeiger, was zwar in anderen Sprachen funktioniert aber bestimmt nicht bei TIA.

Was bekommst du denn für eine Fehlermeldung in der Zeile? Funktioniert es wenn du das REF(...) weglässt?
 
Mit REF_TO auf die einzelne Struktur zu referenzieren geht wunderbar, allerdings müsste ich dadrauf indiziert zugreifen können, und der einzige Weg,
der mir bisher eingefallen war, ist eben über ein array (seit ich in optimierten Bausteinen keine Pointer mehr & damit lustige Offsets ausrechnen kann..)

Die Zeile mit der roten Zuweisung funktioniert nicht, da der Datentyp ja auf ein Array referenziert ist, damit die Zuweisung funktionieren würde, bräuchte ich ein Array von Referenzen auf eine Struktur, nur eben das lässt mir TIA in der Deklaration offensichtlich nicht zu

Danke,
Jasko
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ah ich sehs, das geht mal wieder nicht.

Als zwar unschöne Krücke könnte man sich zur Not hoffentlich eine Hilfsfunktion schreiben, welche die 4 Structs und einen Index von 1..4 übergeben bekommt, und dann per CASE die entsprechende Referenz zurückgibt. Falls es da nicht wieder eine Einschränkung gibt, dass man eine Referenz nicht als Parameter verwendet darf.
Ist zwar keine Universallösung, aber vermutlich einigermaßen performant.
 
Puh... ist zwar ein für meine Funktion komplett anderer ansatz, aber ich werd die Idee mal ausprobieren.

Danke!
Jasko
 
Habs erst beim hundertsten mal drüberlesen gesehn:
Ein Array [1..x] of REF_TO wird in der momentanen Version definitiv nicht unterstützt.. wäre toll, wenn sie das nachwerfen würden :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Werden/Müssen die Strukturen alle in einem Baustein verarbeitet? Weil es sinnvoller ist einen zu schreiben der nur eine abarbeitet und diesen dann "x" mal auf ruft.

Das Thema Serialize könnte noch für die interessant sein.
 
Die Strukturen werden alle in einem Baustein verarbeitet, ja, allerdings werden sie auch in abhängigkeit der Strukturen beschrieben, hier was rekursives zu schreiben würde wohl unser CSS sprengen, mit serialze hab ich leider auch das selbe Problem: wie mit dem kopieren der kompletten Struktur: die Daten werden als kopie abgelegt, bearbeitet & wieder rückgeschrieben, allerdings will ich ja genau das nicht, ich will auf den übergebenen Speicherbereich direkt, aber indiziert zugreifen können.
Direkt geht, wenn ich auf die IO Struktur direkt schreibe/lese, indiziert geht (momentan) nur, wenn ich per IO ein Array übergeben bekomme.

Jetzt will Siemens mit TIA eine Hochsprache simulieren, bis jetzt ist das sehr halbherzig :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Als zwar unschöne Krücke könnte man sich zur Not hoffentlich eine Hilfsfunktion schreiben, welche die 4 Structs und einen Index von 1..4 übergeben bekommt, und dann per CASE die entsprechende Referenz zurückgibt. Falls es da nicht wieder eine Einschränkung gibt, dass man eine Referenz nicht als Parameter verwendet darf.

Die Idee war gut, die Möglichkeiten zur Umsetzung sind aber nicht gegeben :)

-> Auf IO Strukturen kann man nicht referenzieren, und wenn ich in einem FC die Struktur als Input übergebe, kann ich keine Referenz darauf als Output ausgeben..

Sprich: Entweder, du hast den Datenbereich direkt und bekannt beim programmieren zur Verfügung(Globaler DB/Instanz), oder man referenziert auf den eigenen Speicherbereich.
Was genau hab' ich noch von der Referenz..?


Danke,
Jasko
 
Ok, ich habs.

Die Idee von Thomas_v2.1 war schon sehr gut:
mit einem Case-switch die Referenz auf den IO-Bereich legen (IO musste bei mir vom typ Variant sein, von aussen darf nur ein statischer Datenbereich auf die IO-Struktur aufgeschalten sein),

dann gings bei mir.

Jetzt das Überraschende:
Das kopieren der temp strukturen ist schneller als die Abarbeitung über direkten Referenzzugriff?
Ich vermute mal, dass er intern gar nicht mehr wirklich kopiert..?
Knapp über 20% ist der Baustein mit dem kopieren schneller.
Somit ist für mich die Referenz fürs erste begraben :)



Danke allen für die Unterstützung!
Jasko
decla_merge_4_to_1_variant.PNGsource_reference_option.PNGsource_reference_option_ref_direct.PNG
 
Wie viele Zugriffe auf die Daten hast du denn im folgenden Programm?
Dass der Zugriff auf direkte Temp-Variablen etwas schneller ist als Zugriff über eine Referenz leuchtet mir ja noch in gewissen Maße ein. Bei einem Arrayzugriff über Index sollte sich das aber schon wieder egalisieren.
Aber trotz komplettem Umspeichern dann noch 20% langsamer, da muss meiner Meinung nach von Siemens schon einiges extrem umständlich umgesetzt worden sein.

Genauso wie wieder die Beschränkungen, dass bei durchgereichtem InOut wieder irgendwelche Funktionen nicht möglich sind. Das schränkt alles extrem in den Möglichkeiten ein, wie bei dir jetzt wo man einen Programmteil normalerweise in eine Funktion auslagern würde, das aber aufgrund irgendwelcher unsinniger Beschränkungen nicht möglich ist.

Vielleicht kommt ja wieder ein kleines Stück in V16, und was dann noch fehlt in V17 und in V18 wird das von V16 nochmal korrigiert und hat dann neue Beschränkungen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Falls du deine umkopierten Temp-Daten später wieder auf die externen Datensätze zurückschreibst, musst du auch noch beachten, dass falls ein HMI-Gerät auf diese Daten schreibend zugreift, Schreibbefehle unter Umständen nicht erfolgreich sind, wenn diese im Speicher landen während die Funktion ausgeführt wird.
 
Wie viele Zugriffe auf die Daten hast du denn im folgenden Programm?

~100 Aufrufe der Funktion pro Zyklus

Falls du deine umkopierten Temp-Daten später wieder auf die externen Datensätze zurückschreibst, musst du auch noch beachten, dass falls ein HMI-Gerät auf diese Daten schreibend zugreift, Schreibbefehle unter Umständen nicht erfolgreich sind, wenn diese im Speicher landen während die Funktion ausgeführt wird.

Guter Tipp, Danke.

Ich geh mal davon aus, dass die schreibbefehle der HMI ins nirvana gehn? damit könnt ich leben :)

Grüsse,
Jasko
 
~100 Aufrufe der Funktion pro Zyklus
Ich meinte wie viele Zugriffe auf die Strukturvariablen innerhalb der Schleife.

Liegen deine Strukturen denn auch in einem optimierten Datenbereich? Falls nicht, dann muss nämlich bei jedem Zugriff erst die Bytereihenfolge angepasst werden was auch Zeit kostet. Das fällt beim Temp-Variablen komplett weg.

Diese Idee mit "optimierten" und "nicht optimierten" Bereichen wird vermutlich der Performacekiller schlechthin sein. Denn da kann bei einem Zugriff über einen Zeiger/Referenz dieser nicht einfach nur dereferenziert werden, sondern es muss immer auch geschaut werden, ob der Zeiger auf einen opt. oder n.opt. Bereich zeigt, um dann ggf. die Bytes zu drehen. Man kann nur erahnen was da im Hintergrund für Klimmzüge für diese zweifelhafte Funktion gemacht werden.
 
Zurück
Oben