Verwendung von Funktionsbausteinen

Themenpunkte:

  1. Funktionsbaustein-Instanzen nicht als VAR PERSISTENT deklarieren [++]
  2. Zurückgelieferte Fehlerinformationen einer POU auswerten [++]
  3. Auf lokale Variablen einer POU nicht von außen zugreifen [++]
  4. Keine direkte Zuweisung von Objekten [++]
  5. Keine temporären Funktionsbaustein-Instanzen [+]

Funktionsbaustein-Instanzen nicht als VAR PERSISTENT deklarieren

Funktionsbaustein-Instanzen nicht als VAR PERSISTENT deklarieren, da hierdurch die gesamte FB-Instanz in der Datei der persistenten Variablen gespeichert werden würde. Dies könnte z. B. bei Funktionsblöcken mit intern verwendeten ADS-Bausteinen oder Zeigervariablen zu Problemen führen.

Zurückgelieferte Fehlerinformationen einer POU auswerten

Wenn eine Funktion, eine Methode oder ein Funktionsbaustein Fehlerinformationen liefert, werten Sie diese immer aus.

Static Analysis:

Thematisch empfohlene Static Analysis Regeln:

Negatives Beispiel:

PROGRAM Sample_neg 
VAR
    fbFileOpen    : FB_FileOpen;      // FileOpen-FB for logger
    bFileOpenExec : BOOL;             // Execute FileOpen-FB
END_VAR
// NON COMPLIANT: error information of fbFileOpen will not be used
fbFileOpen(
    sPathName := 'C:\TestFile.txt',
    nMode     := FOPEN_MODEWRITE OR FOPEN_MODETEXT,
    ePath     := PATH_GENERIC,
    bExecute  := bFileOpenExec,
    tTimeout  := T#3S);

Positives Beispiel:

PROGRAM Sample_pos 
VAR
    fbFileOpen        : FB_FileOpen;  // FileOpen-FB for logger
    bFileOpenExec     : BOOL;         // Execute FileOpen-FB
    bFileOpenError    : BOOL;         // Error flag of FileOpen-FB
    nFileOpenErrorID  : UDINT;        // Error code of FileOpen-FB
END_VAR
// COMPLIANT: error information will be handled
fbFileOpen(
    sPathName := 'C:\TestFile.txt',
    nMode     := FOPEN_MODEWRITE OR FOPEN_MODETEXT,
    ePath     := PATH_GENERIC,
    bExecute  := bFileOpenExec,
    tTimeout  := T#3S,
    bError    => bFileOpenError,
    nErrId    => nFileOpenErrorID);
 
IF bFileOpenError THEN
    F_DoSomethingUsefulHere();        // Handle error here
END_IF

Auf lokale Variablen einer POU nicht von außen zugreifen

Auf lokale Variablen einer POU sollte nicht von außerhalb der POU zugegriffen werden.

In TwinCAT 3 sind Schreibzugriffe auf lokale Variablen von außerhalb des Programmierobjekts nicht möglich, da diese vom Compiler als Fehler ausgegeben werden. Lesezugriffe werden vom Compiler hingegen nicht abgefangen.

Um die vorgesehene Datenkapselung zu wahren, wird dringend empfohlen, auf lokale Variablen einer POU nicht von außerhalb der POU weder lesend noch schreibend zuzugreifen. Bei Bibliotheksbausteinen ist zudem nicht sichergestellt, dass die lokalen Variablen eines Funktionsbausteins bei späteren Updates der SPS-Bibliothek unverändert bleiben. Dadurch könnte das Applikationsprojekt nach dem Bibliotheksupdate nicht mehr fehlerfrei übersetzt werden.

Static Analysis:

Überprüfen mit Hilfe von Static Analysis Regel:

Negatives Beispiel:

FUNCTION_BLOCK FB_Sample
VAR
    nLocal          : INT;
END_VAR
PROGRAM MAIN
VAR
    fbSample        : FB_Sample;
    nToBeProcessed  : INT;
END_VAR
--------------------------------------------------------------------
nToBeProcessed := fbSample.nLocal;  // NON COMPLIANT: Do not access local variables from external context.

Positives Beispiel:

FUNCTION_BLOCK FB_Sample
VAR_OUTPUT
    nOutput         : INT;
END_VAR
VAR
    nLocal          : INT;
END_VAR
PROGRAM MAIN
VAR
    fbSample        : FB_Sample;
    nToBeProcessed  : INT;
END_VAR
--------------------------------------------------------------------
nToBeProcessed := fbSample.nOutput;  // COMPLIANT: Output variable is accessed from external context.

Keine direkte Zuweisung von Objekten

Einfache Datentypen (INT, BYTE, STRING, …) oder auch Strukturen werden oft direkt zugewiesen.

Instanzen von Funktionsbausteinen sollten Sie nicht mittels Zuweisungsoperator ‚:=‘ zuweisen. Bei einer solchen Zuweisung erfolgt eine Kopie des Objektes. Funktionsbausteine enthalten jedoch intern häufig Adressen, welche bei einer Zuweisung korrumpiert würden.

Um eine solche Zuweisung grundsätzlich zu verbieten, können Sie in der Definition eines Funktionsbausteins das Attribut 'no_assign' setzen.

Static Analysis:

Überprüfen mit Hilfe von Static Analysis Regel:

Keine temporären Funktionsbaustein-Instanzen

Funktionsbausteininstanzen sollten Sie nicht auf dem Stack, d.h. nicht als temporäre Variable, deklarieren. Temporäre Instanzen sind solche, die in einer Methode oder einer Funktion oder als VAR_TEMP deklariert sind, und die deshalb in jedem Abarbeitungszyklus bzw. bei jedem Bausteinaufruf neu initialisiert werden.

Funktionsbausteine haben einen Zustand, der meist über mehrere SPS-Zyklen hinweg erhalten bleibt. Eine Instanz auf dem Stack existiert nur für die Dauer des Funktionsaufrufs. Es ist daher nur selten sinnvoll, eine Instanz als temporäre Variable anzulegen. Zweitens sind Funktionsbausteininstanzen häufig groß und verbrauchen sehr viel Platz auf dem Stack, der auf Steuerungen meist begrenzt ist. Drittens kann die Initialisierung und häufig auch die Terminierung eines Funktionsbausteins ziemlich viel Zeit in Anspruch nehmen.

Static Analysis:

Überprüfen mit Hilfe von Static Analysis Regel:

Die Regel SA0167 ist auch in der lizenzfreien Variante Static Analysis Light enthalten.

Negatives Beispiel:

FUNCTION F_Sample
VAR
    fbCtrl : FB_Control;
END_VAR

Positives Beispiel:

FUNCTION F_Sample
VAR_INPUT
    fbCtrl : REFERENCE TO FB_Control;
END_VAR

 

Siehe auch: