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
undMBM
).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 alsMBM.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