Objekt Methode
Symbol:
Methoden sind eine Erweiterung der Norm IEC 61131-3 und ein Mittel der objektorientierten Programmierung, das der Datenkapselung dient. Eine Methode enthält eine Deklaration und eine Implementierung. Eine Methode ist jedoch im Gegensatz zu einer Funktion kein unabhängiger Programmierbaustein, sondern einem Funktionsbaustein oder Programm untergeordnet. Eine Methode kann auf alle gültigen Variablen des übergeordneten Programmierbausteins zugreifen.
Sie können eine Methode unterhalb eines Programms oder eines Funktionsbausteins hinzufügen. Verwenden Sie dafür den Befehl Projekt > Objekt hinzufügen > Methode, dann öffnet sich der Dialog Methode hinzufügen.
Zur Organisation von Methoden können Sie Schnittstellen verwenden. Für weitere Informationen siehe: Implementieren einer Schnittstelle
Wenn Sie eine Methode, die unterhalb eines Programmierbausteins ist, kopieren und unter einer Schnittstelle einfügen, oder die Methode dahin verschieben, wird automatisch die enthaltene Implementierung entfernt. |
Hinweise zu Methoden
- Alle Daten einer Methode sind temporäre Daten und nur während der Ausführung einer Methode gültig (Stack-Variablen). Das bedeutet, dass TwinCAT alle Variablen und Funktionsbausteine, die Sie in einer Methode deklariert haben, bei jedem Aufruf der Methode neu initialisiert.
- Methoden können ebenso wie Funktionen einen Rückgabewert zurückliefern.
- Gemäß der Norm IEC 61131-3 können Methoden ebenso wie normale Funktionen zusätzliche Ein- und Ausgänge besitzen. Die Ein- und Ausgänge weisen Sie beim Methodenaufruf zu.
- Ab TwinCAT 3.1.4026: Eingänge ohne explizit vorgegebenen Initialwert müssen beim Aufruf der Methode zugewiesen werden. Eingänge mit explizit vorgegebenem Initialwert können optional zugewiesen werden oder beim Aufruf der Methode unbeachtet bleiben.
- Im Implementierungsteil einer Methode ist der Zugriff auf die Funktionsbausteininstanz- oder Programmvariablen erlaubt.
- Um auf die eigene Instanz zu verweisen, verwenden Sie den THIS-Zeiger.
- Sie können auf VAR_TEMP-Variablen des Funktionsbausteins in einer Methode nicht zugreifen.
- Sie können VAR_INST-Variablen deklarieren, für welche bei erneuten Methodenaufrufen keine Neuinitialisierung stattfindet (siehe auch Kapitel Instanzvariablen).
- Durch Verwendung des Rückgabetyps „REFERENCE TO <structured type>“ können Sie direkt beim Aufruf der Methode auf ein einzelnes Element des strukturierten Datentyps, welcher von der Methode zurückgeliefert wird, zugreifen. Weitere Informationen dazu finden Sie im Abschnitt „Zugriff auf ein einzelnes Element eines strukturierten Rückgabetyps beim Methoden-/Funktions-/Eigenschaftenaufruf“.
- Auf VAR_IN_OUT-Variablen des Funktionsbausteins kann in einer Methode prinzipiell zugegriffen werden. Da dieser Zugriff potenziell riskant ist, sollte er mit Bedacht ausgeführt werden. Weitere Informationen dazu finden Sie im Abschnitt „Zugriff auf VAR_IN_OUT-Variablen des Funktionsbausteins in einer Methode/Transition“.
- Methoden, die in einer Schnittstelle definiert sind, dürfen nur Eingabe-, Ausgabe- und VAR_IN_OUT-Variablen definieren, aber keine Implementierung enthalten.
Beispiel:
Der Code im folgenden Beispiel bewirkt, dass TwinCAT den Rückgabewert und die Ausgänge der Methode auf lokal deklarierte Variablen schreibt.
Deklarationsteil der Methode „Method1“ des Funktionsbausteins FB_Sample:
METHOD Method1 : BOOL
VAR_INPUT
nIn1 : INT;
bIn2 : BOOL;
END_VAR
VAR_OUTPUT
fOut1 : REAL;
sOut2 : STRING;
END_VAR
// <method implementation code>
Programm MAIN:
PROGRAM MAIN
VAR
fbSample : FB_Sample;
bReturnValue : BOOL;
nLocalInput1 : INT;
bLocalInput2 : BOOL;
fLocalOutput1 : REAL;
sLocalOutput2 : STRING;
END_VAR
bReturnValue := fbSample.Method1(nIn1 := nLocalInput1,
bIn2 := bLocalInput2,
fOut1 => fLocalOutput1,
sOut2 => sLocalOutput2);
Objekt Methode anlegen
- 1. Selektieren Sie im Projektmappen-Explorer im SPS-Projektbaum einen Funktionsbaustein oder ein Programm.
- 2. Wählen Sie im Kontextmenü den Befehl Hinzufügen > Methode…
- Der Dialog Methode hinzufügen öffnet sich.
- 3. Geben Sie einen Namen ein und wählen Sie einen Rückgabetyp sowie die Implementierungssprache und optional einen Zugriffsmodifizier aus
- 4. Klicken Sie auf Öffnen.
- Das Objekt wird zum SPS-Projektbaum hinzugefügt und im Editor geöffnet. Der Editor besteht aus dem Deklarationseditor im oberen Teil und dem Implementierungsteil im unteren Teil.
Dialog Methode hinzufügen
Name | Name der Methode Die Standardmethoden FB_Init und FB_Exit werden in einer Auswahlliste angeboten, wenn sie nicht bereits unterhalb des Bausteins eingefügt sind. Wenn es sich um einen abgeleiteten Funktionsbaustein handelt, bietet die Auswahlliste außerdem alle Methoden des Basisbausteins an. |
Rückgabetyp | Typ des Wertes, der zurückgegeben wird |
Implementierungssprache | Auswahlliste für die Implementierungssprache |
Zugriffsmodifizierer
Zugriffsmodifizierer | Regelt den Zugriff auf die Daten
Zusätzlich zu diesen Zugriffsmodifizierern können Sie manuell den Modifizierer FINAL zu einer Methode hinzufügen:
|
Abstrakt | : Kennzeichnet, dass die Methode keine Implementierung hat und die Implementierung durch den abgeleiteten FB bereitgestellt wird. Hintergrundinformationen zu dem Schlüsselwort ABSTRACT finden Sie unter ABSTRACT-Konzept. |
Methoden mit einem anderen Zugriffsmodifizierer als PUBLIC werden im Projektmappen-Explorer im SPS-Projektbaum mit einem Signalsymbol gekennzeichnet:
Zugriffsmodifizierer | Objektsymbol | Signalsymbol |
---|---|---|
PRIVATE | (Schloss) | |
PROTECTED | (Stern) | |
INTERNAL | (Herz) |
Wenn Sie eine Methode von einer POU zu einer Schnittstelle kopieren oder verschieben, löscht TwinCAT die enthaltenen Implementierungen automatisch. |
Spezielle Methoden für einen Funktionsbaustein
FB_init | Deklarationen automatisch implizit. Auch explizite Deklaration möglich. Enthält Initialisierungscode für den Funktionsbaustein, wie im Deklarationsteil des Funktionsbausteins definiert ist. |
FB_reinit | Explizite Deklaration notwendig. Aufruf, nachdem die Instanz des Funktionsbausteins kopiert wurde (wie während eines Online-Change), und reinitialisiert das neue Instanzmodul. |
FB_exit | Explizite Deklaration notwendig. Aufruf für jede Instanz des Funktionsbausteins vor einem erneuten Download oder einem Reset oder während eines Online-Change für alle verschobenen oder gelöschten Instanzen. |
Eigenschaften und Schnittstelleneigenschaften | Bestehen jeweils aus einer Set- und/oder Get-Accessor-Methode. |
Methode aufrufen
Syntax:
<return value variable> := <POU name>.<method name>(<method input name> := <variable name> (, <further method input name> := <variable name> )* );
Beim Methodenaufruf weisen Sie an die Eingabevariablen der Methode Übergabeparameter zu. Beachten Sie dabei die Deklaration. Es genügt, wenn Sie die Namen der Eingangsvariablen angeben, ohne deren Reihenfolge in der Deklaration zu beachten.
Beispiel:
Der Code im folgenden Beispiel bewirkt, dass TwinCAT den Rückgabewert und die Ausgänge der Methode auf lokal deklarierte Variablen schreibt.
Deklarationsteil der Methode „Method1“ des Funktionsbausteins FB_Sample:
METHOD Method1 : BOOL
VAR_INPUT
nIn1 : INT;
bIn2 : BOOL;
END_VAR
VAR_OUTPUT
fOut1 : REAL;
sOut2 : STRING;
END_VAR
// <method implementation code>
Programm MAIN:
PROGRAM MAIN
VAR
fbSample : FB_Sample;
bReturnValue : BOOL;
nLocalInput1 : INT;
bLocalInput2 : BOOL;
fLocalOutput1 : REAL;
sLocalOutput2 : STRING;
END_VAR
bReturnValue := fbSample.Method1(nIn1 := nLocalInput1,
bIn2 := bLocalInput2,
fOut1 => fLocalOutput1,
sOut2 => sLocalOutput2);
Rekursiver Methodenaufruf
Innerhalb der Implementierung kann eine Methode sich selbst aufrufen: entweder direkt mit Hilfe des THIS-Pointers oder mit Hilfe einer lokalen Variablen für den zugeordneten Funktionsbaustein.
- Direkter Aufruf der betroffenen Funktionsbausteininstanz mit dem THIS-Pointer:
<Variable für Rückgabewert> := THIS^.<Methodenname> ( <Parameter> );
- Aufruf über eine lokale Variable der Methode, die temporär den betroffenen Funktionsbaustein instanziiert:
<Variable für Rückgabewert> := <FB-Instanz>.<Methodenname> ( <Parameter> );
Bei einem rekursiven Aufruf wird eine Compilerwarnung ausgegeben. Wenn die Methode mit dem Pragma {attribute 'estimated-stack-usage' := '<estimated stack size in bytes>'}
versehen ist, wird die Compilerwarnung unterdrückt.
Unter Attribut 'estimated-stack-usage' finden Sie ein Implementierungsbeispiel.
Um Methoden rekursiv aufzurufen, genügt es nicht, nur den Methodennamen anzugeben. Wenn nur der Methodenname angegeben ist, wird ein Compilerfehler ausgegeben („Programmname, Funktion oder Funktionsbaustein-Instanz erwartet statt …“).
Zugriff auf ein einzelnes Element eines strukturierten Rückgabetyps beim Methoden-/Funktions-/Eigenschaftenaufruf
Um direkt bei einem Methoden-, Funktions- oder Eigenschaftenaufruf auf ein einzelnes Element des strukturierten Datentyps, welcher von der Methode/Funktion/Eigenschaft zurückgeliefert wird, zugreifen zu können, kann folgende Umsetzung verwendet werden. Ein strukturierter Datentyp ist beispielsweise eine Struktur oder ein Funktionsbaustein.
- Der Rückgabetyp der Methode/Funktion/Eigenschaft wird als „REFERENCE TO <structured type>“ definiert (anstelle von lediglich „<structured type>“).
- Bei einem solchen Rückgabetyp ist zu beachten, dass – falls beispielsweise eine FB-lokale Instanz des strukturierten Datentyps zurückgeliefert werden soll – der Referenzoperator REF= anstatt des „normalen“ Zuweisungsoperators := verwendet werden muss.
Die Erklärungen und das Beispiel dieses Abschnitts beziehen sich auf den Aufruf einer Eigenschaft. Sie sind aber genauso auf andere Aufrufe übertragbar, die Rückgabewerte liefern (z. B. Methoden oder Funktionen).
Beispiel
Deklaration der Struktur ST_Sample (strukturierter Datentyp):
TYPE ST_Sample :
STRUCT
bVar : BOOL;
nVar : INT;
END_STRUCT
END_TYPE
Deklaration des Funktionsbausteins FB_Sample:
FUNCTION_BLOCK FB_Sample
VAR
stLocal : ST_Sample;
END_VAR
Deklaration der Eigenschaft FB_Sample.MyProp mit dem Rückgabetyp „REFERENCE TO ST_Sample“:
PROPERTY MyProp : REFERENCE TO ST_Sample
Implementierung der Get-Methode von der Eigenschaft FB_Sample.MyProp:
MyProp REF= stLocal;
Implementierung der Set-Methode von der Eigenschaft FB_Sample.MyProp:
stLocal := MyProp;
Aufruf der Get- und Set-Methoden im Hauptprogramm MAIN:
PROGRAM MAIN
VAR
fbSample : FB_Sample;
nSingleGet : INT;
stGet : ST_Sample;
bSet : BOOL;
stSet : ST_Sample;
END_VAR
// Get - single member and complete structure possible
nSingleGet := fbSample.MyProp.nVar;
stGet := fbSample.MyProp;
// Set - only complete structure possible
IF bSet THEN
fbSample.MyProp REF= stSet;
bSet := FALSE;
END_IF
Durch die Deklaration des Rückgabetyps der Eigenschaft MyProp als „REFERENCE TO ST_Sample“ und durch die Verwendung des Referenzoperators REF= in der Get-Methode dieser Eigenschaft, kann direkt beim Aufruf der Eigenschaft auf ein einzelnes Element des zurückgelieferten strukturierten Datentyps zugegriffen werden.
VAR
fbSample : FB_Sample;
nSingleGet : INT;
END_VAR
nSingleGet := fbSample.MyProp.nVar;
Wenn der Rückgabetyp nur als „ST_Sample“ deklariert wäre, müsste die von der Eigenschaft zurückgelieferte Struktur zunächst einer lokalen Strukturinstanz zugewiesen werden. Die einzelnen Strukturelemente könnten dann anhand der lokalen Strukturinstanz abgefragt werden.
VAR
fbSample : FB_Sample;
stGet : ST_Sample;
nSingleGet : INT;
END_VAR
stGet := fbSample.MyProp;
nSingleGet := stGet.nVar;
Zugriff auf VAR_IN_OUT-Variablen des Funktionsbausteins in einer Methode/Transition/Eigenschaft
Auf die VAR_IN_OUT-Variablen eines Funktionsbausteins kann in einer Methode, einer Transition oder einer Eigenschaft des Funktionsbausteins prinzipiell zugegriffen werden. Bei einem solchen Zugriff ist folgendes zu beachten:
- Wird der Rumpf oder eine Aktion des Funktionsbausteins von außerhalb des FBs aufgerufen, stellt der Compiler sicher, dass bei diesem Aufruf die VAR_IN_OUT-Variablen des Funktionsbausteins zugewiesen werden.
- Bei dem Aufruf einer Methode, Transition oder Eigenschaft des Funktionsbausteins ist dies nicht der Fall, da die VAR_IN_OUT-Variablen des FBs nicht innerhalb eines Methoden-, Transitions- oder Eigenschaftenaufrufs zugewiesen werden können. Es könnte daher gegebenenfalls ein Zugriff auf die VAR_IN_OUT-Variablen stattfinden, indem die Methode/Transition/Eigenschaft aufgerufen wird, bevor die VAR_IN_OUT-Variablen einer gültigen Referenz zugewiesen wurden. Da dies einem ungültigen Zugriff während der Laufzeit entsprechen würde, ist es potentiell riskant, auf die VAR_IN_OUT-Variablen des FBs in einer Methode, einer Transition oder einer Eigenschaft zuzugreifen.
Aus diesem Grund wird bei einem Zugriff auf die VAR_IN_OUT-Variablen des FBs in einer Methode, einer Transition oder einer Eigenschaft folgende Warnung mit der ID C0371 ausgegeben:
„Warning: Access to VAR_IN_OUT <Var> declared in <POU> from external context <Method/Transition/Property>”
Eine adäquate Reaktion auf diese Warnung ist beispielsweise die Überprüfung der VAR_IN_OUT-Variablen innerhalb der Methode/Transition/Eigenschaft, bevor auf sie zugegriffen wird. Diese Überprüfung ist mithilfe des Operators __ISVALIDREF möglich, mit dem geprüft werden kann, ob eine Referenz auf einen gültigen Wert verweist. Ist diese Prüfung vorhanden, kann zum einen davon ausgegangen werden, dass sich der Anwender des Risikos bewusst ist, das potentiell vorhanden ist, wenn auf die VAR_IN_OUT-Variablen des FBs in einer Methode/Transition/Eigenschaft zugegriffen wird. Zum anderen liegt durch die Überprüfung der Referenz ein angemessener Umgang mit diesem Risiko vor. Somit kann die Warnung für diesen überprüften Bereich mittels Attribut 'warning disable' unterdrückt werden.
Die dazugehörige Beispielimplementierung einer Methode ist im Folgenden dargestellt.
Funktionsbaustein FB_Sample:
FUNCTION_BLOCK FB_Sample
VAR_IN_OUT
bInOut : BOOL;
END_Var
Methode FB_Sample.MyMethod:
METHOD MyMethod
VAR_INPUT
END_VAR
// The warning can be disabled here as the user is aware of the risk that the reference may not be valid by checking its validity
{warning disable C0371}
// Checking the VAR_IN_OUT reference, leave the current method in case of invalid reference
IF NOT __ISVALIDREF(bInOut) THEN
RETURN;
END_IF
// Access to VAR_IN_OUT reference (only if the reference was confirmed as valid before)
bInOut := NOT bInOut;
// The warning may be restored at the end of the access area
{warning restore C0371}
Siehe auch: