Parameterlisten sind eine interessante Variante, Parameter an SPS-Bibliotheken zu übergeben. Genaugenommen handelt es sich um globale Konstanten (VAR_GLOBAL CONSTANT), deren Initialisierungswerte im Library Manager editierbar sind.
Bei der Deklaration von Arrays müssen dessen Grenzen Konstanten sein. Zum Zeitpunkt der Compilierung muss bekannt sein, wie groß das Array anzulegen ist. Der Versuch die Arraygrenzen durch eine Variable zu definieren, wird mit einer entsprechenden Fehlermeldung abgelehnt.
PROGRAM MAIN VAR nUpperBound : INT := 5; aTest : ARRAY [1..nUpperBound] OF INT; END_VAR // Compiler error: Border 'nUpperBound' of array is no constant value
Erst die Verwendung von Konstanten löst das Problem.
PROGRAM MAIN VAR aTest : ARRAY [1..nUpperBound] OF INT; END_VAR VAR CONSTANT nUpperBound : INT := 5; END_VAR
Gerade in SPS-Bibliotheken kann dieses zu Problemen führen. Soll durch ein Array z.B. ein Datenpuffer abgebildet werden, so ist nicht unbedingt zum Zeitpunkt der Bibliotheksentwicklung bekannt, wie groß dieser Datenpuffer in den jeweiligen Anwendungen zu sein hat.
Abhilfe schafft hier eine Parameterliste, die bei der Erstellung einer SPS-Bibliothek eingefügt wird.
Eine Parameterliste kann an beliebiger Stelle des SPS-Projektes (das SPS-Projekt, aus der die SPS-Bibliothek entsteht) hinzugefügt werden. Üblicherweise werden Parameterlisten bei den globalen Variablenlisten (GVLs) angelegt.
Deklariert werden die Parameter wie konstante, globale Variablen.
{attribute 'qualified_only'} VAR_GLOBAL CONSTANT cUpperBound : INT := 3; cString : STRING := 'Hello'; cIntArray : ARRAY [1..cUpperBound] OF INT := [1, 2, 3]; cStructArray : ARRAY [1..3] OF ST_Test := [3( (nValue := 1, fValue := 3.1, wsValue := "abc") )]; cEnum : E_Test := E_Test.eValue02; cStruct : ST_Test := (nValue := 1, fValue := 3.1, wsValue := "abc"); END_VAR
Durch Initialisierungswerte können die Variablen vorinitialisiert werden. Auch komplexere Variablenstrukturen können so mit Werten initialisiert werden.
In der Anwendung, in der die Bibliothek eingebunden wurde, können diese Parameter im Library Manager editiert werden. Der Library Manager wird durch einen Doppelklick auf der jeweiligen Bibliotheks-Referenz geöffnet.
Die Felder in der Spalte Value (editable) können jetzt beliebig verändert werden. Die so veränderbaren Konstanten können innerhalb der jeweiligen SPS-Bibliothek oder auch in der Anwendung, die diese referenziert, verwendet werden.
FUNCTION F_AddArrayValues : INT VAR_INPUT aTest : REFERENCE TO ARRAY[1..Param.cUpperBound] OF INT; END_VAR VAR nIndex : INT; END_VAR FOR nIndex := 1 TO Param.cUpperBound DO F_AddArrayValues := F_AddArrayValues + aTest[nIndex]; END_FOR
Abgespeichert werden die geänderten Initialisierungswerte in der jeweiligen SPS-Projektdatei (*.plcproj). Jede Anwendung, die eine Bibliothek mit einer Parameterliste referenziert, besitzt somit seine eigenen Werte. Die Bibliothek an sich bleibt unverändert.
Die so eingestellten Werte überleben auch einen SPS-Reset, sowohl einen Kaltreset, als auch das Zurücksetzen auf die Ursprungswerte. Zurückgesetzt werden die Werte erst dann, wenn die Bibliothek entfernt und wieder eingefügt wird. Somit können Parameterlisten auch zur Übergabe von allgemeinen Parametern genutzt werden.
Alle Parameter einer Parameterliste sind i.d.R. per ADS erreichbar. Die Tatsache, dass Parameter immer mit CONSTANT deklariert werden müssen, verhindert nicht, dass diese per ADS beschreibbar sind.
Dient ein Parameter als Arraygrenze, so wird eine Änderung dieser Variablen schwerwiegende Folgen haben. Insbesondere dann, wenn der Wert des Parameters vergrößert wird.
aTest : ARRAY [1..MyLibrary.Param.cUpperBound] OF INT;
Auch wenn der Parameter zur Laufzeit des SPS-Programms vergrößert wird, so behält das Array seine ursprüngliche Größe bei. Wird dieser Parameter aber auch in Schleifen eingesetzt, so können Zugriffe außerhalb der erlaubten Arraygrenzen entstehen.
FOR nIndex := 1 TO MyLibrary.Param.cUpperBound DO aTest[nIndex] := nValue; END_FOR
Um dieses zu verhindern, kann mit dem Attribut tc_no_symbol die ADS-Symbolerzeugung verhindert werden. Ein Zugriff per ADS über den Symbolnamen ist dann für diesen Parameter nicht mehr möglich.
VAR_GLOBAL CONSTANT {attribute 'tc_no_symbol'} cUpperBound : INT := 5; END_VAR
Hallo Stefan,
danke für die Erklärung. Aber eine Frage habe ich noch, wenn die Parameter doch schon als CONSTANT deklariert sind, wozu benötige ich dann noch das Attribut tc_no_symbol? Beschreiben kann ich die Parameter ja eh nicht?!
Viele Grüße
David
Hallo David,
das Schlüsselwort CONSTANT dient dem Compiler direkte Zuweisungen auf diese Variable schon beim Compilieren durch eine Fehlermeldung zu verhindern. Indirekte Zugriffe z.B. per MEMCPY sind aber weiterhin möglich. Zur Laufzeit des Programms findet keine Überprüfung statt. So sind auch Zugriffe von ‚Außen‘ per ADS auf die SPS-Variable möglich. Dieses ist möglich, weil auch für Konstante Variablen ein Symbol angelegt wird. Über dieses Symbol kann auf die Variable per ADS zugegriffen werden. Das Attribut tc_no_symbol unterdrückt das Anlegen des Symbols und somit kann per ADS nicht mehr auf die Variable zugegriffen werden. Von Außen ist die Variable nicht mehr sichtbar.
Ich hoffe, meine Erklärung hat dir weitergeholfen.
Gruß
Stefan