switch/case über pointer

maniek

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zusammen,

ich bin etwas neu bei SPS Programmierung, komme eher von C, C++, Java usw ..

1. Ich wurde gerne über VAR-Pointer oder FB-Pointer ein switch/case realisieren !?
geht das überhaupt ?

Notes: für switch/case brauche ich konstanten (hier scheitern schon meine Versuche, da ich keine "richtigen" const auf vars oder fb erzeugen konnte ...)

Teil-Fragen
1.1 mit "CONSTANT" werden nur zu die Zugriffsrechte gesteuert oder auch ob das in Ram oder Rom landet ?
1.2 wie wird switch/case intern realisiert ? vergleichbar wie in C oder C++ (intern, wg. Performance!) ? (im Op-Code sind das gewöhnlich ein paar schritte, da alles bekannt, auch beim Case von 10000 ... im zu Vergleich IF xxx THEN ...)
1.3 wo landet wo was (ram, rom usw.)!? (kann ich das irgendwo sehen ? wie compiler-list .... usw.)

2 was passiert mit "dead code" !? z.B. ich habe eine konstante tmp := 5 und mache ein vergleich wie:
IF tmp > 10 THEN
BLAA()
bleibt das in Code ? wird der Vergleich auch jedes mal Ausgeführt ? (obwohl die IF-Anweisung nie True sein kann !?)

3. Performance !? und Links-Tipps
hat jemand Links- oder Buch- Tipps die etwas MEHR in die Materie reingehen ? irgendwie finde nix ! auch angeblich ein gutes Buch habe ich es zurückgeschickt ...
Es ist mir bekannt, dass der Ursprung war ganz anders war, aber heute ist iec 61131-3 auch sehr mächtig, kann wahrscheinlich mit der eine Sprache oder Andere verglichen werden, schade nur dass so wenig Doku gibt und nur SEHR oberflächlich behandelt wird ...

Gruss und Danke !
Maniek
 
Die Doku von 3S/CODESYS (https://help.codesys.com/) ist an vielen Stellen leider wirklich dünn und teils mehrdeutig. Viele der Fragen wird Dir also nur der CODESYS Support beantworten können. Aber ich versuch mal den ersten Ansatz.
1: Keinen Schimmer, was Du meinst. Ein Pointer auf Variablen oder FBs geht und eine CASE-Anweisung auch, aber was meinst Du mit der Kombination?
1.1: Nur Zugriffsrechte.
1.2: Frage an den Support. Aber Frage an Dich, was hast Du nur vor, wenn so minimale Unterschiede in einer Anweisung relevant werden? Ich persönlich nehme das, was gerade einfacher zu implementieren ist.
1.3: Würde ich nur versuchen zu erklären, wenn der Support sich nicht einschaltet. Wichtig wäre dann aber auch ob Du noch CODESYS 2 mit statischen Speichergrenzen verwendest oder CODESYS 3 mit dynamischer Verteilung.
2: Gute Frage, Doku dazu habe ich noch nie gesehen. Gerade in CS3.5 gibt es einige Optimierungen. Wenn Du z.B. Speicherauslastung (siehe Complier Meldungen) oder Zykluszeit (Messung per Code vorher, nachher) betrachtest, ändert sich z.B. nicht, wenn Du immer die gleiche Anweisung in eine kleine oder extrem große FOR-Schleife packst. Probier es einfach aus, geht wahrscheinlich schneller, als Doku lesen, die es nicht gibt - oder nur für OEMs verfügbar ist.
3. Wenn Du was findest, dass soweit in die Tiefe geht, wäre ich auch sehr interessiert. Bis dahin kann ich Dir aber den hier empfehlen: https://stefanhenneken.net/. Sonst wirst Du ggf. auch Seminare/Webinare zum Thema bei den OEMs finden, aber ob die so in die Tiefe gehen, wage ich zu bezweifeln. Da die Nachfrage danach auch recht überschaubar sein dürfte, lohnt sich das wohl eher nicht. Ich denke an sowas hier: https://www.wago.com/at/events/seminar/at-webinar-ecockpit-programmierung-von-wago-controllern-in-st
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe mal versucht, ob man den Compiler austricksen kann. Mit Pointern oder ANY-Typ Eingänge komme ich am Compiler nicht vorbei. Mit der Funktion __VARINFO(), liefert __SYSTEM.VAR_INFO, kann ich über die Strukturvariable ByteAddress am Compiler vorbei zugreifen, aber beim Ausführen stürzt die Runtime ab.
 
Hi KLM

super Danke für Deine Antwort !!!

> 1: Keinen Schimmer, was Du meinst. Ein Pointer auf Variablen oder FBs geht und eine CASE-Anweisung auch, aber was meinst Du mit der Kombination?

ich meine eine globale variable oder globale Fb (die nicht dynamisch instanziiert wird ..da dort natürlich ändern sich die Adressen ..) davon brauche ich den pointer (der eben einmalig beim kompilat ist) dann will ich es in switch/case

wie: (sorry für etwas c syntax oder mix :)
constante var1 := 1
constante var2 := 2

ptr_var1 := ADR(var1)
ptr_var2 := ADR(var2)


dann in code
switch (input_ptr) then:
ptr_var1:
blaa1()
ptr_var2:
blaa2()

> 1.2: Frage an den Support. Aber Frage an Dich, was hast Du nur vor, wenn so minimale Unterschiede in einer Anweisung relevant werden? Ich persönlich nehme das, was gerade einfacher zu implementieren ist.

nein, ausser SPS (iec 61131-3) wo ich keine Achnung habe, sind das keine kleine Unterschiede ! (ist eher essentiell um etwas "performante" apps herzustellen )
( gerade beim protokoll verarbeitung egal ob CAN oder Ethernet, solche "Kleinigkeiten" sind essentiell !
man sucht nicht wenn man es weist wo es ist !!
)

> 1.3: Würde ich nur versuchen zu erklären, wenn der Support sich nicht einschaltet. Wichtig wäre dann aber auch ob Du noch CODESYS 2 mit statischen Speichergrenzen verwendest oder CODESYS 3 mit dynamischer Verteilung.

ich bin beim 3.10 oder 3.16 .....

> 2: Gute Frage, Doku dazu habe ich noch nie gesehen. Gerade in CS3.5 gibt es einige Optimierungen. Wenn Du z.B. Speicherauslastung (siehe Complier Meldungen) oder Zykluszeit (Messung per Code vorher, nachher) betrachtest, ändert sich z.B. nicht, wenn Du immer die gleiche Anweisung in eine kleine oder extrem große FOR-Schleife packst. Probier es einfach aus, geht wahrscheinlich schneller, als Doku lesen, die es nicht gibt - oder nur für OEMs verfügbar ist.

:)) jaa! , da haste recht, mann muss alles selber machen ! (aber das ist doch kein OpenSource Projekt ? wo seit 5 Jahren gestorben ist ....)

Danke !

P.S
dank, ich schaue mir mal __VARINFO() an ..
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zu 1.
So richtig weiß ich noch immer nicht, was Du erreichen willst, aber dafür bin ich vlt. Zu lange aus C raus.
ADR() auf eine Konstante geht jedenfalls nicht. Aber, wenn Du eine Art State Machine bauen willst, mache ich das gern mit Enums. Also etwa so:

enumStates (
eStep1 := 0,
eStep2,
eStep3
)

-----------------------------------

eState : enumStates;

-----------------------------------

CASE eState OF
enumStates.eStep1:
Bla()
enumStates.eStep2:
Bla()
....
END_CASE
 
@maniek: Ich wüsste nicht wie du die Case-Constanten mit den FB oder Var-Adressen initialisieren könntest.

Allerdings zu deinem "Optimierungswahn" (und ja - ich verwende das Wort mit Absicht).

Moderne Tools hin oder her, die Manpower die eine Firma wie 3S in den Compiler investieren kann ist lächerlich im Vergleich zu "OpenSource"-Compilern bzw. Compiler die du von den großen Firmen siehst.
Zudem ist der Einsatzbereich doch sehr speziell mit der Anforderung der OnlineÄnderung. Letztendlich muss/ist der Fokus des Compilers auf Laufzeit-Optimierung hier zweitrangig.

Wenn du dir von diversen Herstellern die Performance-Werte anschaust wenn sie native C bzw. C++ Module ausführen im Vergleich zum PLC Code dann kommst du da auf ~30% Performancegewinn (mir fällt hier spontan ein: Beckhoff, B&R).


Guga
 
Die einzelnen CASE-Segmente verwenden doch mehr oder weniger eine Konstante, da mit enumStates.eStep1 direkt auf einen nicht änderbaren numerischen Wert aus der Enumeration zugegriffen wird. Nur die Schaltvariable eState ist variable, sodass zwischen die einzelnen Schritten gewechselt werden kann.
 
Zurück
Oben