Exceptionhandling in IEC Applikationen mit CODESYS

Verwenden des try/catch-Blocks zum Abfangen von Ausnahmen

Exceptions sollten meiner Meinung nach, nur für wirklich unerwartete Probleme verwendet werden, und nicht um einen „normalen“ Fehler zu erkennen. In diesem Artikel möchte ich euch zeigen für welche Fälle es Sinn macht und wie Ihr die Operatoren Anwenden könnt. Normalerweise würde ich sagen, dass die Fehler innerhalb eines Funktionsbausteins, an einen ErrorHandler geroutet werden. D.H. beim Erstellen eurer Bausteine solltet Ihr immer die Fehlerbearbeitung mit bedenken. So kann euer übergeordneter Programmteil entsprechend auf den Fehler reagieren und Maßnahmen, schlimmstenfalls ein sicheres Abschalten der Maschine, durchführen.

Auf der anderen Seite gibt es nun innerhalb des Funktionsbausteins oder des Programms Fehlerhaften Code oder Routinen die Exceptions auslösen. Mit der oben genannten Methode können wir diese Art von Fehler natürlich nicht behandeln. Unter anderem kann das bei überschreiten von Array-Grenzen passieren, oder wenn Ihr ins Dateisystem der SPS schreibt und keinen Zugriff habt. In diesem Fall wirft das Zielsystem, zum Beispiel, die Exception „Zugriffsverletzung“.

Lösung try/catch Block

Platziert die Codeabschnitte, die möglicherweise Exceptions auslösen, in einem _TRY-Block, und platziert den Code, der die Ausnahmen behandelt, in einem _CATCH-Block.

Das folgende Beispiel verwendet einen _TRY/_CATCH-Block, um eine mögliche Ausnahme abzufangen. Dabei wird der Programmablauf nicht gestoppt, sondern die Befehle im _CATCH-Block bearbeitet. Die mSaveRawData-Methode speichert, einen Datensatz, in die example.txt-Datei auf dem Zielsystem. Die gesamte Anweisung zum Speichern der Zeichenfolge wird in einen _TRY-Block aufgerufen. Dem _TRY-Block folgt ein _CATCH-Block, der alle Ausnahmen abfängt.

Sollte die mSaveRawData-Methode eine Ausnahme produzieren, werden zuerst die Anweisung unter _CATCH und danach die Anweisung unter _FINALLY ausgeführt.

//Variable deklarieren
VAR
    exceptionCode : __SYSTEM.ExceptionCode;
    path:STRING;
END_VAR

//Funktionsbaustein code
__TRY
   bSaved := mSaveRawData(data, path);
__CATCH(exceptionCode)
   mHandleExc(exceptionCode);
__FINALLY
   mClearRawDataFilter(); //Im Finally abschnitt können wir unsere Daten bereinigen.
__ENDTRY

Auf der Homepage von Microsoft gibt ein paar Vorschläge dazu, wann Ihr einen Code in einem try-Block platzieren solltet. Die Beispiele sind für .NET. Die bewährte Methoden, lassen sich allerdings, analog zu CODESYS übertragen.

Datentyp __System.ExceptionCode

Im Beispiel oben habt Ihr wahrscheinlich schon gesehen, dass ich eine variable vom Typ „_System.ExceptionCode“ deklariert habe. In diesem Datentyp findet Ihr alle unterstützten Exceptions.

TYPE ExceptionCode :
(
RTSEXCPT_UNKNOWN  := 16#FFFFFFFF,
RTSEXCPT_NOEXCEPTION  := 16#00000000,
RTSEXCPT_WATCHDOG  := 16#00000010,
RTSEXCPT_HARDWAREWATCHDOG  := 16#00000011,
RTSEXCPT_IO_CONFIG_ERROR  := 16#00000012,
RTSEXCPT_PROGRAMCHECKSUM  := 16#00000013,
RTSEXCPT_FIELDBUS_ERROR  := 16#00000014,
RTSEXCPT_IOUPDATE_ERROR  := 16#00000015,
RTSEXCPT_CYCLE_TIME_EXCEED  := 16#00000016,
RTSEXCPT_ONLCHANGE_PROGRAM_EXCEEDED  := 16#00000017,
RTSEXCPT_UNRESOLVED_EXTREFS   := 16#00000018,
RTSEXCPT_DOWNLOAD_REJECTED                := 16#00000019,
RTSEXCPT_BOOTPROJECT_REJECTED_DUE_RETAIN_ERROR        := 16#0000001A,
RTSEXCPT_LOADBOOTPROJECT_FAILED            := 16#0000001B,
RTSEXCPT_OUT_OF_MEMORY                    := 16#0000001C,
RTSEXCPT_RETAIN_MEMORY_ERROR            := 16#0000001D,
RTSEXCPT_BOOTPROJECT_CRASH                := 16#0000001E,
RTSEXCPT_BOOTPROJECTTARGETMISMATCH        := 16#00000021,
RTSEXCPT_SCHEDULEERROR                    := 16#00000022,
RTSEXCPT_FILE_CHECKSUM_ERR                := 16#00000023,
RTSEXCPT_RETAIN_IDENTITY_MISMATCH        := 16#00000024,
RTSEXCPT_IEC_TASK_CONFIG_ERROR            := 16#00000025,
RTSEXCPT_APP_TARGET_MISMATCH            := 16#00000026,
RTSEXCPT_ILLEGAL_INSTRUCTION            := 16#00000050,
RTSEXCPT_ACCESS_VIOLATION                := 16#00000051,
RTSEXCPT_PRIV_INSTRUCTION                := 16#00000052,
RTSEXCPT_IN_PAGE_ERROR                    := 16#00000053,
RTSEXCPT_STACK_OVERFLOW                    := 16#00000054,
RTSEXCPT_INVALID_DISPOSITION            := 16#00000055,
RTSEXCPT_INVALID_HANDLE                    := 16#00000056,
RTSEXCPT_GUARD_PAGE                        := 16#00000057,
RTSEXCPT_DOUBLE_FAULT                    := 16#00000058,
RTSEXCPT_INVALID_OPCODE                    := 16#00000059,
RTSEXCPT_MISALIGNMENT                    := 16#00000100,
RTSEXCPT_ARRAYBOUNDS                    := 16#00000101,
RTSEXCPT_DIVIDEBYZERO                    := 16#00000102,
RTSEXCPT_OVERFLOW                        := 16#00000103,
RTSEXCPT_NONCONTINUABLE                    := 16#00000104,
RTSEXCPT_PROCESSORLOAD_WATCHDOG            := 16#00000105,
RTSEXCPT_FPU_ERROR                        := 16#00000150,
RTSEXCPT_FPU_DENORMAL_OPERAND            := 16#00000151,
RTSEXCPT_FPU_DIVIDEBYZERO                := 16#00000152,
RTSEXCPT_FPU_INEXACT_RESULT                := 16#00000153,
RTSEXCPT_FPU_INVALID_OPERATION            := 16#00000154,
RTSEXCPT_FPU_OVERFLOW                    := 16#00000155,
RTSEXCPT_FPU_STACK_CHECK                := 16#00000156,
RTSEXCPT_FPU_UNDERFLOW                    := 16#00000157,
RTSEXCPT_VENDOR_EXCEPTION_BASE            := 16#00002000
RTSEXCPT_USER_EXCEPTION_BASE            := 16#00010000
) UDINT ;
END_TYPE

Fehler finden trotz Exceptionhandling

Dadurch dass wir die_TRY/_CATCH-Blöcke einsetzten, wird unser Applikationscode im Falle einer Exception nicht mehr angehalten. Denn in diesem Fall, soll natürlich der Code im _CATCH Blog für die weitere Bearbeitung, herangezogen werden. Wollt Ihr die Exception nun lokalisieren, könnt Ihr den Befehl ‘Ausführung an behandelten Exceptions anhalten’ verwenden.

Der Befehl ist standardmäßig deaktiviert, kann aber über Tools ⇒ Anpassen hinzugefügt werden. Dazu sind folgende Schritte notwendig:

Befehl hinzufügen: Ausführung an behandelten Exceptions anhalten
Befehl hinzufügen: Ausführung an behandelten Exceptions anhalten

Nachdem wir den Befehl in das Menü Online konfiguriert haben und ihn dort aufrufen (funktioniert nur im Onlinebetrieb), können wir damit leicht die Ausnahme lokalisieren. Der Befehl bearbeitet die gerade aktive Applikation. Das ist wichtig zu wissen wenn Ihr mehrere Applikationen in einem Projekt habt.

Exceptionhandling in CODESYS
Exceptionhandling

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website benutzt Cookies und Google Analytics. Wenn du die Website weiter nutzt, gehen wir von deinem Einverständnis aus Weitere Informationen

Die Cookie-Einstellungen auf dieser Website sind auf "Cookies zulassen" eingestellt, um das beste Surferlebnis zu ermöglichen. Wenn du diese Website ohne Änderung der Cookie-Einstellungen verwendest oder auf "Akzeptieren" klickst, erklärst du sich damit einverstanden.

Schließen