Speicheradresse in UDINT an einer REFRENCE TO übergeben

BitShift

Level-2
Beiträge
32
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo allerseits

Wir haben da ein Programm eines nicht Codesys Systems und wir konnten einen Grossteil der Datenstrukturen und des ST-Codes relativ einfach in Codesys 3.5 SP19 Patch 6 importieren (hineinkopieren) kompilieren und auf eine Codes RT laden. Und es funktioniert! Das Original-System speichert in Teilen der Software via ADR(<struct>) die Speicheradressen von Strukturen in UDINT Variablen um damit dann bei Bedarf mit einem entsprechenden Operator eine REFERENCE TO Variable zu «initialisieren». Ich finde nichts Vergleichbares in Codesys. Eine Alternative wäre ADR(<struct>) an eine POINTER TO Variable zu schreiben und damit später eine REFERENCE TO POINTER TO Variable zu «initialisieren». Das funktioniert auch, bedeutet aber enorm viel Aufwand.

Kann man mit Codesys eigene Operatoren programmieren? Wenn ja, wo wäre das Dokumentiert (finde leider nichts – sorry).

Liesse sich das allenfalls via Integration eines C-Modules lösen, damit man z.B. einen eigenen REF= Operator z.B. myREF machen könnten? <REFERENCE TO> myREF <UDINT>

Oder sieht jemand eine andere Lösung?

THX, BitShift
 
Habe gerade kein natives Codesys zur Hand, aber in TwinCAT (Basiert ja auf Codesys) geht das Folgende ohne Fehlermeldung:
Code:
PROGRAM MAIN
VAR
    udiTest01    : UDINT;
    stTest01    : ST_Test;
END_VAR

udiTest01    := ADR(stTest01);
Ist Euer Codesys System zufällig ein 64 Bit System? Dann kann das auch nicht gehen, dann müsstet Ihr eine ULINT Variable nehmen.
Oder habe ich Euer Problem jetzt missverstanden?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
SIZEOF(ADR(stTest01)); ergibt 4 (4 Byte) also 32 Bit.

Ja, dein Beispiel funktioniert bei mir definitiv auch. Die Frage ist aber, wie initialisiere ich jetzt eine REFERENCE TO Variable mit udiTest01?

myRef : REFERENCE TO ST_Test;

myRef MAGIEOPERATOR udiTest01; // ???
 
"Warum der Umweg über ein UDINT?"

Weil im alten (bestehenden) System tausende Zeilen von Code so geschrieben sind und dieser Code möglichst gleich übernommen werden sollte.

Ein Workaround ist:

myPointer : POINTER TO StructType;

myReference : REFERENCE TO POINTER TO StructType;

myPointer := ADR(myStruct);

myReference REF= myPointer;

So muss man das Programm nicht anpassen aber dennnoch in vielen POU und Variablenlisten die Datentypen anpassen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verstehe nur Bahnhof.
Füge doch bitte mal ein Beispiel des alten Codes in Code Tags hier ein.
Wenn ich das richtig verstehe wird dem UDINT die Adresse einer Variablen zugewiesen und diese soll dann einer Referenz zugewiesen werden, aber das ist ja kein initialisieren, eine Initialisierung findet ja bei der Deklaration statt und da kann keine Variable verwendet werden, der erst eine Adresse zugewiesen werden muss.
 
Mal so aufs Blaue hinaus:
Code:
TYPE uniRefr :
UNION
   Adrs:UDINT;
   Refr:REFERENCE TO StructType;
END_UNION
END_TYPE

FUNCTION GetStructRef : REFERENCE TO StructType;
VAR_INPUT
   Adrs:UDINT;
END_VAR
VAR
   Refr:uniRefr;
END_VAR

Refr.Adrs:=Adrs;
GetStructRef:=Refr.Refr;
 
Ich denke, das war wirklich aufs Blaue hinaus. Das Ergebnis der Funktion kriegst Du dann ja auch wieder nicht in Deine REFERENCE.
Aber Du könntest Deine UDINTS durch die uniRefr ersetzen und dann direkt über MyuniRefr.Refr auf die Struktur zugreifen.
Trotzdem bedenklich, denn wenn Du es schaffst, einer REFERENCE eine beliebige Adresse zuzuweisen, geht die Typsicherheit der REFERENCEs verloren.
 
Zurück
Oben