TC3 überschreiben von const Variablen

msauerpb

Level-1
Beiträge
200
Reaktionspunkte
7
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich eine Variable coEventListLength als const definiert.

Code:
{attribute 'qualified_only'}
VAR_GLOBAL
    EventList                       : ARRAY [0..GVL_EVENT.coEventListLength] OF ST_EVENT;   // Diese Liste enthält die Aktuellen Fehler    
    NewEventUpdateList              : BOOL;
    ClearProfiErrArray              : BOOL := FALSE;
END_VAR

{attribute 'qualified_only'}
VAR_GLOBAL CONSTANT
    coEventListLength               : UINT := 30;                       // Länge der Log Liste
END_VAR

Diese wird an mehreren Stellen gelesen.

Das System, CS5130 mit TC 3.1, wird über Profibus von einer Sinumerik Anlage gesteuert. Eines von den ProfiBus Signalen ist ein Reset Signal, das der Master schickt. Mit diesem Reset Signal werde in dem CX Fehlerflags und ähnliches zurück gesetzt.
Dabei ist mir jetzt aufgefallen, dass die const Variable coEventListLength auch auf 0 gesetzt wird. Jedenfalls steht in der Online View nach betätigen der Anlagenresettaste dort auf einmal eine 0. Wenn ich nochmal ein Reset schicke, steht dann dort wieder 30 drinnen.

Das dürfte doch eigentlich gar nicht sein, dass sich der Wert einer Const Variable ändert, oder sehe ich das falsch? Hat einer von Euch eine Idee was da passieren könnte?

Danke für Eure Hilfe

gruss
martin
 
Das System, CS5130 mit TC 3.1, wird über Profibus von einer Sinumerik Anlage gesteuert. Eines von den ProfiBus Signalen ist ein Reset Signal, das der Master schickt. Mit diesem Reset Signal werde in dem CX Fehlerflags und ähnliches zurück gesetzt.
Dabei ist mir jetzt aufgefallen, dass die const Variable coEventListLength auch auf 0 gesetzt wird. Jedenfalls steht in der Online View nach betätigen der Anlagenresettaste dort auf einmal eine 0. Wenn ich nochmal ein Reset schicke, steht dann dort wieder 30 drinnen.

Das dürfte doch eigentlich gar nicht sein, dass sich der Wert einer Const Variable ändert, oder sehe ich das falsch? Hat einer von Euch eine Idee was da passieren könnte?
Das kann schon passieren, aber nicht auf normalem Wege. Das klingt für mich so, als ob der Speicher überschrieben wird, z.B. durch Indexüberschreitung bei einem Arrayzugriff. Füge mal vor der Konstanten Dummy Konstanten vom selben Typ mit verschiedenen Werten ein und beobachte die Reaktion dieser Variablen mal.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Eines von den ProfiBus Signalen ist ein Reset Signal, das der Master schickt. Mit diesem Reset Signal werde in dem CX Fehlerflags und ähnliches zurück gesetzt.
Werden die Variablen[SUP]1[/SUP]) durch den Reset ebenfalls grundsätzlich "gelöscht" oder neu initialisiert, also ggfs mit einem von 0 abweichenden Wert beschrieben?
Das "StromstossRelaisVerhalten" der Konstanten beim Auftreten des Reset ist schon sehr merkwürdig. :confused:

Mit dem Reset werden doch wohl nicht direkt durch das "BetriebsSystem" die FehlerFlags gelöscht. Für diesen Zweck wurde vermutlich im Programm etwas hinzugefügt.
Was? Und warum?

[SUP]1[/SUP]) vielleicht wären Variablen die konstanteren Konstanten? (Umkehrschluss des MurphyGesetzes "alle Konstanten sind variabel") ;)
 
Zuletzt bearbeitet:
Wenn der Compiler funktioniert wie alle anderen, dann arbeitet er von oben nach unten.
Darum würde ich die Konstante an den Anfangen geben. Ansonsten ist die nicht initialisiert wenn sie verwendet wird.

Grüße
 
Wenn der Compiler funktioniert wie alle anderen, dann arbeitet er von oben nach unten.
Darum würde ich die Konstante an den Anfangen geben. Ansonsten ist die nicht initialisiert wenn sie verwendet wird.
:confused: Ist das nicht sowieso selbstverständlich?
Bei - insbesondere lokalen - Variablen hat man ja die "Freiheit", mal zu vergessen, dass die Variablen zuerst mit einem sinnvollen Inhalt gefüllt werden müssen, ehe man darauf zugreifen darf.
Aber hier irgendwo eine Parallele zu Konstanten zu sehen, überschreitet meine VorstellungsKraft. Auch Konstanten können doch lokal oder global definiert werden und sind nur in ihrem GeltungsBereich verwendbar. Versuche ich, eine Konstante an einer Stelle im Programm zu lesen, an der sie unbekannt ist, so bleibt das dem Compiler nicht verborgen. Dort wo die Konstanten bekannt sind, müssen sie auch nach einem Reset (was immer das sein mag) sowie nach dem Aus- und WiederEin-Schalten der PLC, an den Stellen, an denen sie gelesen werden, einfach bekannt und verfügbar sein.
Das erklärt auch nicht, warum die Konstanten nach einem Reset abwechselnd gelöscht bzw. mit dem richtigen Inhalt gefüllt sind.
Ich vermute im hiesigen Fall eigentlich keine Macke des Compilers. Es wird wohl so sein, dass das AnwenderProgramm selbst das "ResetSignal" auswertet und "unsauber" reagiert.
 
Ich hab das jetzt mal mit Dummy Variablen davor und dahinter ausprobiert. Meine Probleme Variable wird immer auf 0 gesetzt. Die 3 Dummys dagegen bleiben wie sie sind.

gruss
martin
 
Dann such mal nach Verwendungen von der Variable, irgendwo muss mit der Adresse von dieser ein Pointer gefüttert werden, anders kann man Kontanten, außer bei falschen Speicherzugriffen, nicht überschreiben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
:confused: Ist das nicht sowieso selbstverständlich?
Bei - insbesondere lokalen - Variablen hat man ja die "Freiheit", mal zu vergessen, dass die Variablen zuerst mit einem sinnvollen Inhalt gefüllt werden müssen, ehe man darauf zugreifen darf.
Aber hier irgendwo eine Parallele zu Konstanten zu sehen, überschreitet meine VorstellungsKraft. Auch Konstanten können doch lokal oder global definiert werden und sind nur in ihrem GeltungsBereich verwendbar. Versuche ich, eine Konstante an einer Stelle im Programm zu lesen, an der sie unbekannt ist, so bleibt das dem Compiler nicht verborgen. Dort wo die Konstanten bekannt sind, müssen sie auch nach einem Reset (was immer das sein mag) sowie nach dem Aus- und WiederEin-Schalten der PLC, an den Stellen, an denen sie gelesen werden, einfach bekannt und verfügbar sein.
Das erklärt auch nicht, warum die Konstanten nach einem Reset abwechselnd gelöscht bzw. mit dem richtigen Inhalt gefüllt sind.
Ich vermute im hiesigen Fall eigentlich keine Macke des Compilers. Es wird wohl so sein, dass das AnwenderProgramm selbst das "ResetSignal" auswertet und "unsauber" reagiert.

Mein "Reset" Signal setzt nur Variablen zurück, die Fehlerzustände gespeichert haben und keine Direkten CPU Register.

Diese konstante Variable in als VAR_GLOBAL CONSTANT in einer GVL definiert.

gruss
martin
 
Wähl mal in den Projekteigenschaften/Übersetzen "Konstanten ersetzen" an. Wenn es dann icht mehr passiert, s. #2 von oliver.tonn.

Genau damit passiert es nicht mehr. Was macht diese Option?

Gibt es in TC auch ein Variable Dump oder Memory Fenster, wo ich die Adressen der Variablen rausfinden kann? Ich habe da nichts gefunden? Bzw. wie kann ich denn danach suchen, ob diese Adresse an einer anderen Stellen beschrieben wird?

Danke für Eure Hilfe.

gruss
martin
 
Zuletzt bearbeitet:
Mit der Option werden Konstanten nicht wie Variablen im Speicher abgelegt, sondern ihre Werte vom Compiler direkt ins Programm eingetragen.

Also wird die Variable wohl mehr oder weniger gezielt überschrieben. Kannst Du Breakpoints setzen, um den Resetvorgang schrittweise zu beobachten?
 
Dann such mal nach Verwendungen von der Variable, irgendwo muss mit der Adresse von dieser ein Pointer gefüttert werden, anders kann man Kontanten, außer bei falschen Speicherzugriffen, nicht überschreiben.

Das war der richtige Weg. Hatte in einem Array ein Bufferoverflow und habe über das Ende hinausgeschrieben. Das Array war in der selben GVL definiert wie die Konstante. Nachdem ich das behoben hatte, gibts keine Probleme mehr.

Danke für Eure Hilfe.

gruss
martin
 
Die Antwort kommt zwar sehr spät, aber ich bin gerade selber auf der Suche nach der Lösung für ein Problem und bin über diesen Thread gestolpert und vielleicht hilft das Folgende Dir bei der Vermeidung solcher Probleme.
Wie Du ja selber festgestellt hast kann man bei Nutzung von Variablen als Index bei Arrays über das Ende oder den Anfang hinaus zugreifen, ohne das es eine Warnung gibt. Um dies zu verhindern oder genauer um die Folgen davon abzumildern gibt es POUs für implizite Prüfungen, fügt man da das Passende POU hinzu wird dieses POU bei jedem Arrayzugriff automatisch aufgerufen und verhindert das.
 
Zuletzt bearbeitet:
Zurück
Oben