TwinCat 2.11 (2228) persisentes Variablen Phänomen

Bl000b3r

Level-2
Beiträge
99
Reaktionspunkte
11
Zuviel Werbung?
-> Hier kostenlos registrieren
Also erstmal Hallo ^^
hab ja quasi noch nicht viel zur Hilfe hier beigetragen, habe dafür aber ein umso interessantes problem :eek:

also vorab-information:
*sitze nach feierabend aufm hotelzimmer ;)
* beckhoff support schon mehrmals kontakiert ... die einzigste service-hotline die einfach nur besetzt ist lol, wenn man jmd ranbekommt hat er keine ahnung oder man stört ihn scheinbar grad beim schaumbad, am ende heißt es nur "schicken sie es mal per email" ... danach heißt es immer die email ist nie angekommen :confused: könnt mittlerweile ausrasten, aber dafür ist ja beckhoff schon berühmt

Nutzen Steuerungen des Typs CX1020-0122 mit Twincat v2.11 (Build 2228 )

Nun zu meinem Problem:

Es gab ein ein schlechtes vorlage-projekt. das hab ich glatt-gezogen und lief wie ein schweizer uhrwerk ^^
nach dem transport zum kunden lief auch alles weiter glatt, bis ich bemerkte dass es ein problem bei peristenten variablen gibt, ich hoffe ich kanns gut beschreiben. hab auch schon andere threads zu dem thema hier gelesen daher vorne weg:

die pers.vars werden vorm stoppen der sps auf den flashspeicher geschrieben ... dies funktioniert auch bei "fast" allen variablen problemlos, bis auf genau eine ... nennen wir sie "problemkind"

das problemkind ist eine real variable, die über eine visualisierung (spidercontrol @ microbrowser) nur bei bedarf geschrieben werden kann, es handelt sich nur eine art referenz variable. die variable wird eim start der visualisierung auch nicht beschrieben sondern lediglich für die anzeige gelesen. im programm selber wird die variable nur an einer einzigen stelle für einen vergleich gelesen.

So:
Man kann die Variable über den PLC-Editor oder die Visu schreiben. Sie ist als peristente globale Variable deklariert. Wenn TwinCat aber neustartet sind alle pers.Vars korrekt vorhanden, nur das Problemkind steht auf einmal wider bei 0 !!!
Also gingen die Versuche los ... die Visualisierung wurde für alle weiteren Versuche beendet.

die variablen vor und nach dem problemkind waren alle entweder usint oder real werte ... also von oben angefangen durch nummerierte werte zu vergeben (10, 11, 12 ... usw). Die Variablen wurden erfolgreich geschrieben und Twincat anschließend über den Systemmanager neugestartet ... Die Nummerierung war noch vorhanden, nur das Problemkind stand wieder auf 0. Dieser prozess wurde weiter versucht, mit immer dem selben ergebnis.

Danach haben wir das komplette Bootprojekt in der Steuerung gelöscht. Im Twincat verzeichnis den Ordner Boot ebenfalls per Hand geleert. Alle Dateien im Projekt bis auf die *.pro & *.tsm gelöscht, das Projekt komplett neu generiert - tpy Datei neu eingelesen - die ganze prozedur ^^ Bootprojekt neu erzeugen und los gings

Die Variablen standen ja alle erstmal wieder bei 0 .. also wieder neu durchnummiert ... wieder war das problemkind nach neustart 0 ^^
Das war der Punkt wo ich die Geduld verloren und mir meinen harten reset-knopf gewünscht hab ^^ aber ein kaffee später gingen die versuche weiter.

Nun habe ich mir in einer virtuellen Maschine eine neue Demoversion von der selben TwinCat version installiert und das projekt in die demo-plc eingespielt und die selben versuche wie oben getätigt ... und lol das selbe problem ???
Da kam wieder der punkt, nur diesmal hätte ich gern schnaps statt nen kaffee gehabt lol

Brauche wohl kaum erwähnen, dass ein anderer Versuch in einer CX1020-0121 mit Twincat 2.11 aber wesentlich ältere build den selben effekt brachten.

Wie gesagt ... die Variable wird nur EINMAL in programm GELESEN (!!!) und die Visualisierung war komplett beendet - 100%ig

also habe ich angefangen allen persistenten variablen per hand feste speicherbereiche zuzuteilen, quasi per @MB... .
danach die variablen mit nem einfach zu merkenden muster beschreiben und siehe da, das problemkind wird aufeinmal gespeichert ... ABER auf einmal wird die Variable, nenn wir sie "Problemkind2", im %MB12 nicht mehr gespeichert (zur sicherheit wurden alle zugriffe auf die variable in der plc auskommentiert).
Da der support nicht reagiert und der kunde druck macht, habe ich auf MB12 erstmal eine dummy variable gelegt und das problemkind2 auf einen anderen speicherbereich gelegt. dort wird es erfolgreich gespeichert und wiederhergestellt.

Zwischeninfo: ich habe beim übersetzen die überwachung für überlappende speicherbereiche und konkurrierende zugriffe aktiviert (ohne fehlermeldung ... immer)

Danach habe ich angefangen weitere updates (ohne anlegen neuer persistenter variablen) einzuarbeiten. lief alles super bis ich merkte das aufeinmal wieder eine pers.var immer nach dem neustart 0 ist ... OMG wo ist mein kaffee ... wieder im speicherbereich verschoben, weiter gehts

dies ist aber keine lösung, weils keiner verantworten kann das ding automatisch ohne aufsicht laufen zu lassen, weil keiner weiß wann die nächste variable ausfällt ^^

Was denkt ihr woran es liegen kann ... es saßen schon 5 leute an dem projekt und konnten sich nicht erklären was da schief läuft.
Einen defekt der Hardware oder im Speicher schließe ich aus, da dass Problem auf in der Soft-PLc aufm Laptop und in der älteren Ersatzsteuerung auftrat.
Twincat selbst erkennt mit allen Zusatzoptionen beim Übersetzen 0 Fehler und 0 Warnungen.
Die Biliotheken in der SPS und auf meinem Laptop sind in der gleichen Version.

ich hatte die Vermutung das durch vielen Änderungen die im Ablauf nötig waren ein Bug beim übersetzen sich ins programm geschlichen, vlt bei der zuteilung der speicherbereiche etc ... aber als ich die einigermaßen funktionierende vorlage mal iweder eingepsielt habe gab es auch da auf einmal ein problemkind ... dessen position sich zwar scheinbar mit wachsenden oder schrupfenden programm-ausmaß verschiebt aber es gibt auf alle fälle IMMER ein problem kind

ich bin ratlos ... willkommen im beckhoff-permuda dreieck xD wo emails verschwinden und probleme aus dem nicht auftauchen ^^
 
Zuletzt bearbeitet:
also vorab-information:
*sitze nach feierabend aufm hotelzimmer ;)
* beckhoff support schon mehrmals kontakiert ... die einzigste service-hotline die einfach nur besetzt ist lol, wenn man jmd ranbekommt hat er keine ahnung oder man stört ihn scheinbar grad beim schaumbad, am ende heißt es nur "schicken sie es mal per email" ... danach heißt es immer die email ist nie angekommen :confused: könnt mittlerweile ausrasten, aber dafür ist ja beckhoff schon berühmt

Viel schlimmer als der eigentlich beschriebene Fehler scheint das Verhalten der Hotline von Beckhoff zu sein. Und dabei ist es doch gerade die Firma, die in letzter Zeit doch sehr auf den Putz haut. Lesen die hier eigentlich mit?

Frank
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn der Beckhoff-Support die letzte Hoffnung ist, steht man tatsächlich am Abgrund. Scheint personell uind fachlich nicht mit den Umsatzsteigerungen der letzten Jahre mitgewachsen zu sein.
Aber was soll ein Support-Hotliner denn zu Deinem Problem sagen? Deine Versuchsergebnisse lassen wohl eher auf einen Fehler im Anwendungsprogramm schliessen, vermutlich ein Pointer-Problem. Was passiert denn, wenn Du das Ganze mit einem leeren Programm laufen lässt?
 
Tritt denn dein Problem auch auf, wenn nu nur die persistenten Daten nimmst, das gesamte Programm aber löscht.
Damit könnte man erst einmal ermitteln, ob dein Programm vielleicht doch irgendwo über Speicheradressierung an den falschen Daten manipuliert.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Ralle:

das hab ich auch probiert ... nur die ganzen Variablendeklarationen und nur eine MAIN(PRG) mit nem Semikolon.
Dabei speichert es die persistenten Daten scheinbar problemslos, nachdem ich aber einfach wieder den Rest des Programms einspiel ist der Bug wieder da.
Aber wie schon gesat, scheinbar verschiebt sich der Bug je nachdem wieviel Programmtext enthalten ist.
Habe dann auch ALLE Zugriffe auf die betroffenen Variablen auskommentiert, so dass per Querverweis nur noch die Deklaration zu finden ist ... hat alles nix gebracht

Habe auch schonmal den Speicher für Variablen etc erhöht, ohne Erfolg

@FX64:
Das geht auf garkeinen Fall, ich würds ja gern, weils das beste wäre, aber hab doch bei industrieprojekten ne geheimhaltungspflicht
 
Kann ich nicht glauben, das es an der Größe vom enthaltenen Code abhängig ist. Wird denn wirklich nichts überschrieben? Kanidaten sind auch memcpy und POINTER TO ;-)
 
ja keine ahnung. hatte ja später noch weitere fb's eingefügt und plötzlich hat es eine weitere variable getroffen ... geschrieben werden sicher nirgends.
befehle wie memcpy und pointer to nutz ich nicht. Nutze lediglich MemSet auf eine Struktur um diese abzulöschen. aber durch die adr() und sizeof() sollte ja eigentlich ein überschreiben anderer variablen verhindern oder ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kurz zusammengefasst:
  • Auf beliebigen Speicherplätzen werden Variablen beim Schreiben der Persistenten Daten verändert
  • Hardwareunabhängig
  • Allen Code auskommentiert -> kein Fehler

Die Situation scheint verzwickt, wobei auch ich vermute, dass du irgendwie auf Speicher schreibst...
Um dir auf der Baustelle möglichst bald zu helfen folgende Vorschläge/Fragen um in einer Testumgebung zu prüfen:

  • Was passiert, wenn du statt die Steuerung auszuschalten nur das TwinCAT System (->Icon in Taskliste) stoppst
  • Versuche mal herauszufinden, ob die Anzahl Zyklen die abgearbeitet werden eine Rolle spielen. (PLC starten, und sofort stoppen, dann System stoppen) - Oder sogar den Code nur einmal mit CTRL+ F5 ablaufen lassen!
  • Nimm Scope 1 oder 2 und trace die Problemkinder. Werden diese vor der Ausschalten noch verändert?
  • Was passiert wenn du den Variablenname änderst?
Hier wären noch weitergehende Vorschläge:
  • Implementiere doch mal die Funktion CheckBounds. Und da einen globalen Zähler hochzählen lassen. (Array-Grenzen überwachen)
  • Ev. mal die ADS Kommunikation mit dem ADS überwachen, nicht das "irgendwas Fremdes" auf den Speicher zugreifft.
 
OK erstmal Danke, muss dass erstmal in Ruhe durchlesen. Waren nach Feierabend zusammen beim Griechen xD

Deine Zusammenfassung trifft es ziemlich genau.
* Ich habe aus Zeitgründen das Neustarten der Steuerung immer über den einfachen Systemstop - Systemstart bzw. einfach Neustart gemacht
* Einzelschrittbetrieb kann ich auf der richtigen steuerung nicht machen, weil twinsafe da sofort die steuerspannung raus haut xD Werde es aber morgen mal auf der Soft-Plc mitm Laptop ausprobieren
* Scopeview einfach mitlaufen zulassen ist auch ne gute idee, vlt wird ja wirklich was in den ersten zyklen geschrieben was man so nicht mitbekommt (Scope1)

*Variablenname habe ich schon geändert: Nach dem Ändern des Namens (Global also auch alle Querverweise) kann die Variable korrekt beschrieben und gespeichert werden. Das komische ist nur, als ich danach die Variable wieder umbenannt habe, d.h. den ursprünglichen namen, konnte ich die variable nicht mal mehr schreiben !!! lediglich forcen ging, aber sobald das forcen aufgehoben wurde, ging die variable wieder auf 0 zurück

Scheise, wäre einfacher wenn ichs posten könnt ^^
Werd morgen mal diverse Dinge die genannt wurden Stück für Stück ausprobieren und danach nochmal ein kommentar abgeben

btw: habe heute das 4. mal (!!!) das projektarchiv an support geschickt ... man kriegt weder eine empfangs- noch eine lesebestätigung zurück :p
 
Es gibt ja ausser MEMSET/MEMCPY noch andere FB's in den Beckhoff-Lib's, die Variablenadressen als Pointer erhalten. Such doch mal global nach "ADR(", vielleicht kommt da noch etwas zu Tage.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Je nachdem wie deine persistenten Daten strukturiert sind, würde ich mal versuchen direkt vor dem Problemkind im Speicher eine weitere persistente Variable anzulegen. Dann komplett übersetzen und prüfen ob das Problem noch da ist, bzw. sich auf die neue Variable verschoben hat.
 
Die Idee von Thomas ist ebenfalls gut. Weiterhin kann man das Projekt beim/nach dem Compile auf Speicherüberlappungen prüfen lassen, bei VarConfigs mit IOs oder direkten Adressen auch ein beliebtes Problem.
 
Zwischeninfo:

Bin auf auf Arbeit noch nicht dazugekommen euere Sachen mal zu testen. Habe aber gerade ein Weltwunder erlebt ... Der Beckhoff-Support hat mich angerufen xD und hat gemeint ich sollte mal ff ausprobieren um sicher zu gehen, dass das sps file die daten überschreibt.

ALs erstes muss ich sagen, dass ich angefangen hatte die persistenten Daten per Hand auf feste Merkerbereiche zu legen. Hatte dann einen Merkerbereich der immer wieder 0 wurde ... habe darauf eine "dummy" variable gelegt.

Der Supportmensch meinte ich sollte mal mein Projekt einspielen, Bootproject erzeugen und die Variablen beschreiben. Danach ausloggen, den Hacken bei Bootproject rausnehmen und die Steuerung neustarten. Danach versuchen einzuloggen - "Kein Programm auf Steuerung vorhanden, neue Programm laden?" - hab es dann nochmal eingespielt. Danach ist die SPS ja noch im STOP ... peristenten Variablen ALLE vorhanden :cool: ... SPS per F5 in Run versetzt ... BOOOM war die dummy-variable wieder 0

Wollts nur mal so nebenbei mitteilen ... Hab jetzt noch gut 2h freie Spitzen und werd mal alles bereinigen und nach Befehlen & Fb's Mit ADR etc. suchen ... die nadel im heuhaufen

update kommt bald :ROFLMAO:

PS: die option "überlappende speicherbereich" hab ich immer an beim übersetzen ... er bringt nur von paar ausgänge die überlappungen, aber das sind Festo Ventilinseln die nur per Byte angesprochen werden, und da ist ja jedes ventil nochmal bit genau adressiert
 
Zuletzt bearbeitet:
ich glaub ich hab den schuldigen gefunden :ROFLMAO:
habe erstmal alle Befehle mit ADR() auskommentiert und bin wieder so wie oben vorgegangen erstmal schauen und das sps in run versetzen.
Das hat wunderbar funktioniert, alle pers.Vars waren noch genauso da, wie ich sie geschrieben habe.

Also habe ich angefangen Stück für stück die einzelnen Befehle mit ADR() reinzunehmen und habe die 2 Befehle gefunden:

MEMSET :eek:

Habe eine Struktur St_Status:

Code:
Code:
[I]TYPE ST_NestStatus :
   STRUCT
         Var1: BOOL; 
         Var2: BOOL; 
         Var3: BOOL; 
         Var4: BOOL; 
        [/I][I]Var5: BOOL;
        [/I][I]Var6: BOOL;    
        [/I][I]Var7: BOOL;    
        [/I][I]Var8: BOOL;    
        [/I][I]Var9: BOOL;    
        [/I][I]Var10: BOOL;    
        [/I][I]Var11: BOOL;    
        [/I][I]Var12: BOOL;
        [/I][I]Var13: BOOL;
   END_STRUCT
END_TYPE[/I]

Das bilde ich mir eine pers. Variable als Array von 1 bis 2. Sind quasi 2 Nester wo der Bearbeitungsstatus festgehalten wird.

Code:
 St1_Nest : ARRAY [1..2] OF ST_NestStatus

So, wenn nun die Steuerspannung reingeht stehen erstmal alle Schrittketten in einem "Warteschritt" - daraus kannste GSF machen oder eben handbetrieb.

So in nun eben diesem Schritt frage ich per Ini's den Beladezustand ab

Code:
IF NOT Nest1_Beladen THEN
  MEMSET (ADR(St1_Nest[1]), 0, SIZEOF(St1_Nest[1]));
END_IF

IF NOT Nest2_Beladen THEN
  MEMSET (ADR(St1_Nest[2]), 0, SIZEOF(St1_Nest[2));
END_IF

Sehe selber gerade eben, dass es nicht gerade klug, dass sowas in jedem Zyklus durchlaufen ist xD

Ist aber denk ich sehr wahrscheinlich, dass es daran lag ... jedenfalls verlier ich auch nach dem 10. neustart keine variable
 
Und du meinst an den Zeilen lag das Problem?

Ich wäre ja neugierig und würde wenn möglich die Zeilen mal wieder reinnehmen, und wenn das Problem dann wieder da ist mal die Adressen vergleichen.
Also ob ADR(St1_Nest[1]) oder ADR(St1_Nest[2]) sich irgendwie mit ADR(Problemkind) überschneiden. Dabei bedenken dass die Strukturen 13 Bytes groß sind.

Ich erinnere mich an ein ähnliches Phänomen dass ich nach einem Änderungsladen hatte. Da hatte ich die Vermutung dass ein Zugriff mit ADR() nicht auf die neue Adresse aktualisiert wurde. Nach einem Komplettübersetzen und -laden war aber wieder alles i.O. Und das hast du ja auch schon mehrmals gemacht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@THomas:

Ja Bereinigen, Alles Übersetzen, Urlöschen, Reset ... alles was TwinCat ansich an Zurücksetz-Optionen hat wurde bereits versucht ^^

Habe auch einen herben Rückschlag ...

Habe ja heute mit Beckhoff paar Mal telefoniert (hab ne direkte Nummer von dem Mitarbeiter - die kannste bei eBay versteigern lol) ... als ich ihm die Sache mit MEMSET erklärt habe und gesagt in welchem Schritt dies aufgerufen wurde, sagte er nur "Hier steht nix von Memset" ... da hatte ich bemerkt, dass der Stand mit dem ich probiert hatte aktueller war als der den ich zu beckhoff geschickt hatte ... das pferd kann trotz zahnweh nicht auf der stelle trampeln ^^ ... ich hatte das noch nachträglich reingenommen ... hmm

also fix das projekt ausm outlook exportiert (selber stand wie beckhoff) und alles ordnungsgemäß neu eingespielt und sihe da ... das "Problemkind" lies nicht mal schreiben obwohl es nur deklaiert war ... also ich hab ich mal den hier erwähnten versuch gestartet und eine neue Integar Variable "Versuch1" vor und "Versuch2" nach dem Problemkind angelegt ...

danach ließ auch nach mehrmaligen rücksetzen und überstzungsversuchen die variable "versuch2" nicht mehr schreiben und das problemkind funktionierte astrein.


FAZIT:


Wenn eine Variable NUR deklariert ist (als persistent) und diese im gegensatz zu allen anderen nicht gespeichert wird, ich aber danach 2 weitere Variablen (nur deklariert - ohne Zugriff) vor und nach der fehlerhaften Variable anlege und der Fehler quasi eins weiter gereicht wird, heißt das doch, dass es zu 99,9% ein Fehler beim Schreiben des Speichers auf SPS Seite ist.


Der Beckhoff Mensch wills mal nach meiner Anleitung nachstellen und mich morgen nochmal anrufen ^^ Bin ich ja mal gespannt was er dazu sagt

also ich steht wieder da, wo ich schon mal vor paar tagen stand :ROFLMAO:
 
Hab mal eine Frage:

Versuche gerade mit Checkbounds Array Zugriffe außerhalb des zu entdecken ... weiß nur nicht so recht wie den handhaben bzw verstehen soll

Hab einfache ne FUNCTION erstellt

Code:
FUNCTION CHECKBOUNDS : DINT
 VAR_INPUT
 index, lower, upper : DINT;
 END_VAR
 VAR
 END_VAR
_________________________


IF index<lower THEN
 CHECKBOUNDS := lower;
 ELSIF index>upper THEN
 CheckBounds := upper;
 ELSE
 CHECKBOUNDS := index;
END_IF

Das ist doch scheinbar alles man braucht ^^ also hab ich nen Breakpoint bei "CHECKBOUNDS := lower;" und tipp Zyklus für Zyklus per Hand durch.
Nur wars das ?

Er gibt mir dann Werte wie zum Bsp:

index = 1
lower = 1
upper = 4
Checkbounds = 0

Verstehe ich das richtig, das sobald eine Bereichsüberschreitung kommt, der Checkbounds Ausgang den Index-Wert annimmt der inkorrekt war ?
 
Nein, ich würde in den IF Zweigen eine globale Variable hochzählen, jeweils für upper und lower. Da mußt Du nicht durchsteppen, das mußt dann erst wenn Fehler vorhanden sind.
 
Zurück
Oben