ERROR (ENUM)

TYPE ERROR :

Jeder Funktionsbaustein dieses Dokuments hat einen booleschen Ausgang xError, der anzeigt, dass eine Fehlerbedingung aufgetreten ist. In diesem Fall wird eine genauere Information mit dem Wert des Ausgangs eErrorID des Funktionsbausteins BehaviourModel angezeigt. Die Variable eErrorID speichert ein Integer-Wert, der die Fehlerursache anzeigt. Es ist notwendig, den Integer-Wert von iErrorID auf einen bereichsspezifischen Enumerationsdatentyp ERROR abzubilden.

Fehlerdomänen und Fehlercodes (ERROR (Enum) und eErrorID (output)) und ihre Organisation in verschiedenen Domänen:

Oftmals wird der Integer-Wert von eErrorID als Eingang für einen zusätzlichen Funktionsbaustein verwendet, der die Anzahl der betroffenen lokalisierten Strings in eine geeignete Sprache konvertiert. Die Werte für eine spezielle eErrorID sind applikationsabhängig. Wenn einige Bibliotheken gemeinsam verwendet werden (mehrere Domänen) kann es zu einer Überlappung der Nummern der eErrorID kommen, das bedeutet, dass die gleiche Nummer in unterschiedlichen Domänen auch unterschiedliche Fehlerbedingungen identifiziert. Aus diesem Grund muss ein Wertebereich für die eErrorID für jede Bibliothek definiert werden.

Die Fehlerbehandlung eines Funktionsbausteins sollte so ausgelegt sein, dass nur Fehlercodes zurückgeliefert werden, die in der betroffenen Bibliothek dokumentiert werden. Es ist nicht ratsam, unbehandelte Fehlercodes von Unterbibliotheken zurückzuliefern. Es wird empfohlen, fremde Fehlercodes auf den Fehlerbereich der betroffenen Bibliohtkek abzubilden.

Im nachfolgenden Beispiel wird die Beziehung zwischen zwei Bibliotheken genauer betrachtet: Jede hat einen spezifische Fehlerdomäne: Die erste Bibliothek wird „Memory Block Manager library“ bezeichnet und mit dem Namensraum MBM erstellt. Die zweite Bibliothek wird „Function Block Factory“ bezeichnet und mit dem Namensraum FBF erstellt. Jede Bibliothek definiert ihren eigenen ERROR Enumerationsdatentyp.

Die ERROR Enum der Bibliothek „Memory Block Manager“ (MBM)

1{attribute 'qualified_only'}
2TYPE ERROR : (
3    NO_ERROR := 0, // The defined operation was executed successfully
4    NO_MEMORY := 10 // The memory pool has no further capacity
5    HANDLE_INVALID := 20, // The object was not created properly or has been already released
6    WRONG_ALIGNMENT := 30, // The structure description aligns not properly to the block specification
7    (*...*)
8END_TYPE

Die ERROR Enum der Bibliothek „Function Block Factory“ (FBF)

1{attribute 'qualified_only'}
2TYPE ERROR : (
3    NO_ERROR := 0, // The defined operation was executed successfully
4    TIMEOUT := 1, // The specified operation time was exceeded
5    INVALID_PARAM := 10, // One or more function parameters have no valid value
6    NO_MEMORY := 20, // The extension of memory pool is not possible
7    (*...*)
8END_TYPE
  • Die beiden Bibliotheken sind getrennt über den Namensraum (in diesem Beispiel FBF und MBM).

  • Jede ERROR Enum-Deklaration sollte zwei vordefinierte Fehlercodes berücksichtigen.

    • NO_ERROR ⇒ 0 (Zero)

    • TIME_OUT ⇒ 1 (One)

  • Wenn der Fehlercode TIME_OUT keine Verwendung in einer spezifischen Domäne hat, sollte der Wert nicht für einen anderen Fehlercode wiederverwendet werden.

  • Jeder Fehlercode benötigt eine kurze Beschreibung über den Hintergrund seiner Fehlerbedingung.

  • Ein Enumerationsdatentyp sollte mit seinem eigenen Namensraum {attribute 'qualified_only'}) getrennt von anderen Enumerationsdatentypen sein. FBF.ERROR.NO_MEMORY hat eine völlig andere Bedeutung als MBM.ERROR.NO_MEMORY..

Die Zusammenarbeit mit unterlagerten Bibliotheken erfordert es, unterschiedliche Fehlerdomänen auf die eine lokale Domäne abzubilden. Das nachfolgende Beispiel zeigt die mögliche Gestaltung einer Fehlercode-Mappingfunktion. Sie behandelt die Fehlercodes (von CS.ERROR und CO.ERROR) zweier Unterbibliotheken und versucht, diese auf die lokale Error-Enumeration (CANOPEN_KERNEL_ERROR) abzubilden (alle Enumerationsdatentyps deses Beispiels haben den Datentyp INT).

Beispiel einer Fehlercode-Mappingfunktion „MapError“

 1FUNCTION MapError : CANOPEN_KERNEL_ERROR
 2VAR_INPUT
 3       iErrorID : INT;
 4END_VAR
 5
 6MapError := CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_UNKNOWN_ERROR;
 7IF iErrorID = CS.ERROR.NO_ERROR THEN
 8    MapError := CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_NO_ERROR;
 9ELSIF iErrorID > CS.ERROR.FIRST_ERROR AND iErrorID < CS.ERROR.LAST_ERROR THEN
10    CASE iErrorID OF
11        CS.ERROR.TIME_OUT           : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_TIMEOUT;
12        CS.ERROR.REQUEST_ERROR      : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_REQUEST_ERROR;
13        CS.ERROR.WRONG_PARAMETER    : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_WRONG_PARAMETER;
14        CS.ERROR.NODEID_UNKNOWN     : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_NODEID_UNKNOWN;
15        CS.ERROR.SDOCHANNEL_UNKNOWN : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_SDOCHANNEL_UNKNOWN;
16    ELSE
17        MapError := CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_OTHER_ERROR;
18    END_CASE
19ELSIF iErrorID > CO.ERROR.FIRST_ERROR AND iErrorID < CO.ERROR.LAST_ERROR THEN
20    CASE iErrorID OF
21        CO.ERROR.TIME_OUT       : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_TIMEOUT;
22        CO.ERROR.NO_MORE_MEMORY : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_NO_MORE_MEMORY;
23        CO.ERROR.WRONG_PARAMETER: MapError := CANOPEN_KERNEL_ERROR.CANOPEN_WRONG_PARAMETER;
24        CO.ERROR.NODEID_UNKNOWN : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_NODEID_UNKNOWN;
25        CO.ERROR.NETID_UNKNOWN  : MapError := CANOPEN_KERNEL_ERROR.CANOPEN_NETID_UNKNOWN;
26    ELSE
27        MapError := CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_OTHER_ERROR;
28    END_CASE
29END_IF

Es wird angenommen, dass CS.ERROR.NO_ERROR den gleichen Wert hat wie CO.ERROR.NO_ERROR und der übrige Wertebereich von CS.ERROR und CO.ERROR getrennt ist.

Attributes:
qualified_only
Ein-/Ausgänge:

Name

Initialwert

NO_ERROR

0

TIME_OUT

1

WRONG_TRANSITION

-1

WRONG_CONFIGURATION

-2