TIA Stringverarbeitung

Zuviel Werbung?
-> Hier kostenlos registrieren
Wir haben hier 2 Probleme:
(1) der TIA-SCL-Compiler behandelt bei der S7-1500 Zugriffe auf Strings hinter das aktuelle Ende des Strings wie Zugriffe auf nicht existierenden Speicher (mindestens bei optimiertem Speicher). Die Zugriffe lösen aber anscheinend keine Fehler aus, sie gehen einfach nur ins Leere. Lesezugriffe liefern (anscheinend immer?) '$00'
(2) bestimmte Schreibzugriffe in einen String hinter das aktuelle Ende des Strings verändern die aktuelle Stringlänge

Problem (2) darf nicht sein, ich halte das für einen Bug.

Problem (1) könnte man durch entsprechende Dokumentation zu einem Feature machen, dann müsste man damit leben und ggf. früher funktionierenden Code umschreiben. Ist dieses Verhalten so dokumentiert? Gibt es beim Migrieren von classic-SCL zu S7-1500-SCL oder beim Compilieren in TIA entsprechende Warnungen/Fehlermeldungen? Bei Zugriff auf indiziert adressierte Zeichen in Strings müsste man nun sicherstellen daß zuvor die aktuelle Stringlänge hinter die Zugriffsstelle zeigt.

? Gibt es in der verwendeten TIA-Version eine neue Definition des Datentyps STRING für S7-1500, eventuell nur gültig in "optimiertem" Speicher? Steht da irgendwo, daß der Speicher hinter dem aktuellen Ende des Strings nicht existiert und/oder daß man darauf nicht zugreifen darf/kann? Und wenn man es trotzdem macht, daß man da '$00' erhält bzw. ein hineinschreiben "ins Leere" geht?
Wieso läßt der Compiler ohne Warnung indizierte Zugriffe auf die Zeichen des Strings zu, obwohl er sogar sehen kann, daß die Zugriffe hinter das aktuelle String-Ende gehen? Meine Meinung: weil sie grundsätzlich zulässig sind.

? Wie kann man die aktuelle Stringlänge vergrößern? Anscheinend nur durch Anhängen eines Strings - das erfordert nun (im Hintergrund) vermutlich immer ein Kopieren des gesamten Strings. "Früher" war das nicht nötig und deshalb effizienter

? Wenn der Speicher hinter der aktuellen Stringlänge nicht mehr existiert, welchen Sinn hat dann noch die deklarierbare maximale Stringlänge?

Harald
 
Ja, der Test mit einem String der Länge 0 kam nur zufällig zustande, ich wollte mal sehen, ob man einfach die angezeigt Zeichenzahl verringern kann, indem man den Startstring kürzer angibt.
in der Theorie solte das keine Probleme machen, da der String ja länger definiert und somit der Speicherplatz zumindest vorhanden ist.
Mir ist schon klar, dass man da normalerweise nichts hineinschreiben sollte und die Länge korrekt setzen muß um auch korrekte Ergebnisse zu haben.
Man kann auch einen String der Länge 4 nehmen und an Stelle 1-7 etwas hineinschreiben, auch dann verlängert sich der String um eine Stelle.
Das Verhalten von TIA ist hier sicher nicht korrekt und ich denke auch nicht gewollt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie ist das eigentlich wenn man in einen String der Länge 4 in das 2. Zeichen eine '$00' schreibt und danach mit der LEN-Funktion die Länge abfragt - ergibt das immer noch 4 oder 1 oder was?


Sent from Harald's Mobile
 
hallo zusammen,

ich habe mir das noch mal angesehen und konnte es genau so nachvollziehen wie der TE es geschildert hat.
Ein Blick in die Hilfe brachte Klarheit :)
Am Ende der aktuellen länge einfügen ist ein impliziter concat, nicht am ende sondern weiter danach nimmt das System nicht an.
string.jpg

Wie ist das eigentlich wenn man in einen String der Länge 4 in das 2. Zeichen eine '$00' schreibt und danach mit der LEN-Funktion die Länge abfragt - ergibt das immer noch 4 oder 1 oder was?
Sent from Harald's Mobile
Das ändert nichts an der aktuellen länge, sie bleibt da wo sie war, so kam es zumindest bei meinem test raus.

So wie ich es gesehen habe ist das verhalten wie beschrieben dokumentiert.
Ein anhängen würde ich immer nur per concat machen oder indiziert in einen zuvor definierten String.

VG
Red-Cali
 
Ein Blick in die Hilfe brachte Klarheit :)
Am Ende der aktuellen länge einfügen ist ein impliziter concat, nicht am ende sondern weiter danach nimmt das System nicht an.
Anhang anzeigen 43050
Aus welcher TIA-Version stammt Dein Hilfe-Zitat? Seit welcher TIA-Version gilt dieses Verhalten? Für welche CPUs gilt das Verhalten? Gilt dies auch für Strings in Speicher mit Standard-Zugriff?

PS: Woher kommt eigentlich die Idee zu diesem Siemens-speziellen "impliziten CONCAT", was in keiner mir bekannten Hochsprache üblich ist?

PPS: Kann man die TIA-Hilfe eigentlich ernst nehmen? Welchen Datentyp haben die einzelnen Zeichen eines STRING in dem TIA: CHAR oder BYTE?
On read access to the character string, you receive the character '$00' [...]

MyDB.mystring[6] := CHAR_TO_BYTE('!');
Wozu ist im Hilfe-Beispiel das explizite CHAR_TO_BYTE? :confused:

Harald
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich hab das aus der TIA V15 Hilfe, da hab ich es getestet.
Wie es sich in anderen TIA Versionen verhalten kann ich nicht sagen, das müsste man dann nachschauen
Da die Hilfe nichts von Optimiert oder Standard sagt würde ich denken das es sich für beide varianten gleich verhält?

Gruß
Bastian
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe mal gezielt nach der Dokumentation dieses merkwürdigen Verhaltens gesucht.
Das Verhalten gibt es anscheinend seit V13 SP1, im TIA-Step7-Systemhandbuch dokumentiert ist es erst seit V14. Diese "unwichtigen" Neuerungen werden bei keiner TIA-Version in "Was ist Neu" bzw. "Readme" erwähnt. Lediglich im Online-Hilfesystem von V13 SP1 wird (vermutlich erstmalig) erwähnt
Online-Hilfesystem V13 SP1 schrieb:
Fehler entstehen, wenn Sie zur Laufzeit auf ein Zeichen zugreifen, das außerhalb der STRING-Länge liegt. Bei lesendem Zugriff auf den STRING erhalten Sie das Zeichen '$00' oder '$0000', ein schreibender Zugriff in den STRING wird nicht ausgeführt. Wenn die Anweisung über den Freigabeausgang ENO verfügt, wird ENO auf den Signalzustand FALSE gesetzt.
Das ebenfalls schon vorhandene "implizite CONCAT" wird nicht erwähnt.

Die Erklärung mit dem ENO:=FALSE stimmt allerdings nicht: wird in KOP mit einer MOVE-Box ein Schreiben hinter das aktuelle String-Ende versucht, dann wird das Schreiben zwar nicht ausgeführt, ENO des MOVE bleibt aber TRUE. (zumindest in PLCSIM V13 SP1)

Das Verhalten gilt für S7-1200 und S7-1500, für "optimierten" und für Standard-Speicher (jeweils mit PLCSIM V13 SP1 getestet).

Wozu dieses merkwürdige Verhalten eingeführt wurde? :confused: Ich sehe dafür keinen zwingenden Grund.
War es vielleicht ursprünglich ein Bug und muß nun aus Kompatibilitätsgründen beibehalten werden?


In der V12 Onlinehilfe und Systemhandbuch stand noch folgendes:
Online Hilfesystem (V12) schrieb:
Einzelne Zeichen eines STRINGs adressieren
Überwachung von STRING-Zugriffen zur Laufzeit

Wenn zur Laufzeit ein STRING geschrieben wird, der die definierte Länge der STRING-Variablen überschreitet, kann es zu unerwünschten Reaktionen im Programm kommen. Die verschiedenen CPU-Familien reagieren unterschiedlich auf Überschreitungen der STRING-Länge.

S7-1200/1500
Das Überschreiten der STRING-Länge wird überwacht. Sie können wählen, ob Sie auf Überschreitungen mit der globalen Fehlerabehandlung der CPU oder mit einer eigenen lokalen Fehlerbehandlung reagieren wollen.
Ab V13 gibt es diese Erklärung nicht mehr. Vielleicht wurde das nie richtig bugfrei realisiert oder man ließ es dann einfach so umgemodelt wie es jetzt ist?

STEP 7 Professional Systemhandbuch (V14 schrieb:
Einzelne Zeichen eines STRINGs oder WSTRINGs adressieren (S7-1200, S7-1500)

Fehlerbehandlung bei (W)STRING-Zugriffen

Zugriffsfehler entstehen, wenn Sie zur Laufzeit auf ein Zeichen zugreifen, das außerhalb der STRING-Länge liegt. Bei lesendem Zugriff auf den STRING erhalten Sie das Zeichen '$00' oder '$0000', ein schreibender Zugriff in den STRING wird nicht ausgeführt. Wenn die Anweisung über den Freigabeausgang ENO verfügt, wird ENO auf den Signalzustand FALSE gesetzt. Die CPU geht nicht in STOP.
Eine Ausnahme besteht nur, wenn das Zeichen direkt hinter die tatsächliche Länge des STRINGs geschrieben wird.
[...]
Das folgende Beispiel zeigt den genannten Ausnahmefall: Das Zeichen wird direkt hinter den STRING in das 6. Zeichen geschrieben. Das Ergebnis der Zuweisung ist 'hello!'.

SCL
MyDB.mystring := 'hello';
MyDB.mystring[6] := CHAR_TO_BYTE('!');
Wozu ist im Hilfe-Beispiel das explizite CHAR_TO_BYTE? :confused:
Das Programmbeispiel funktioniert so natürlich nicht, der Compiler (V13 SP1) gibt die Fehlermeldung: "Eine implizite Konvertierung von Datentyp 'Byte' nach 'Char' ist nicht möglich." - weil die einzelnen Zeichen eines (W)STRING vom Datentyp (W)CHAR sind, und deshalb ein (W)CHAR zugewiesen werden muß und kein BYTE.


Der Witz: der für den String deklarierte/reservierte Speicher hinter dem aktuellen String-Ende existiert und mit der Beobachtungstabelle kann hinter dem aktuellen String-Ende geschrieben und gelesen werden. ("optimierter" und Standard-Speicher) Die nicht-Zugreifbarkeit hinter das aktuelle String-Ende aus dem Programm ist eine "willkürliche" Festlegung.

Übrigens: Ein (KOP- oder SCL-) Programm beobachten zeigt bei nicht ausgeführtem Schreiben nicht '$00' sondern den Wert der schon an der Stelle steht (dessen Lesen aber sonst verhindert wird). Was zu schönen Verwirrungen führen kann ;)


Noch ein Verhalten was anscheinend nirgends erwähnt wird:
Wird beim Zugriff auf einen String festgestellt daß die Istlänge > Maxlänge ist, dann wird die Istlänge auf 0 gesetzt.

Harald
 

Anhänge

  • SCL_LEN.png
    SCL_LEN.png
    18,9 KB · Aufrufe: 20
Zurück
Oben