Exception Handling
Bei der Abarbeitung des aus MATLAB® oder Simulink® autogenerierten C++-Codes in TwinCAT kann es zur Laufzeit zu Floating Point Exceptions kommen, wenn zum Beispiel ein bei der Programmierung unerwarteter Wert in eine Funktion übergeben wird. Die Behandlung von solchen Exceptions wird im Folgenden beschrieben.
Was ist eine Floating Point Exception?
Eine Floating Point Exception tritt dann auf, wenn eine arithmetisch nicht exakt ausführbare Rechenoperation in der Floating Point Unit der CPU beauftragt wird. IEEE 754 definiert diese Fälle: inexact, underflow, overflow, divide-by-zero, invalid-operation. Tritt einer dieser Fälle auf, wird ein Status Flag gesetzt, welches auf die nicht exakt ausführbare Rechenoperation hinweist. Es wird des Weiteren definiert, dass jede Rechenoperation ein Ergebnis liefern muss, und zwar ein solches, das in der Mehrzahl der Fälle dazu führt, dass man die Exception ignorieren kann.
Beispielsweise ergibt eine Division durch Null +inf oder -inf. Wird im weiteren Code ein Wert durch inf geteilt, ergibt dies Null, sodass keine Folgeprobleme zu erwarten sind. Wird inf allerdings multipliziert, oder werden andere Rechenoperationen mit inf ausgeführt, sind dies invalid operations, deren Ergebnis als Not-a-Number (NaN) dargestellt wird.
Wie reagiert die TwinCAT-Laufzeit bei Exceptions?
![]() | TwinCAT C++ Debugger nicht aktiv Folgende Ausführungen gelten nur für den Fall, dass der C++ Debugger nicht auf dem TwinCAT-Laufzeitsystem aktiviert ist. Bei aktiviertem C++ Debugger werden Exceptions vom Debugger abgefangen und können behandelt werden, siehe Debugging. |
Standardverhalten
Default-Einstellung in TwinCAT ist, dass bei „divide-by-zero“ und „invalid-operation“ die Ausführung des Programms gestoppt wird und TwinCAT eine Fehlermeldung ausgibt.
Task-Einstellung: Floating Point Exceptions
Diese Default-Einstellung lässt sich auf Ebene einer jeden TwinCAT Task verändern. Wird die Checkbox „Floating Point Exception“ deaktiviert, führt eine Exception nicht zu einem TwinCAT-Stopp und es wird keine Fehlermeldung ausgegeben. Diese Einstellung ist dann gültig für alle Objekte, die durch diese Task aufgerufen werden. In der Folge müssen Sie in der Applikation darauf achten, dass NaN- und inf-Werte entsprechend im Programmcode behandelt werden.
Prüfen auf NaN und Inf
Wird beispielsweise ein NaN per Mapping an ein TwinCAT-Objekt weitergegeben, welches Floating Point Exceptions aktiviert hat, führt eine Rechenoperation mit NaN in diesem Objekt zu einer Exception und in der Folge zu einem TwinCAT-Stopp. Daher muss direkt nach dem Mapping auf NaN bzw. inf geprüft werden. In der SPS stehen dazu entsprechende Funktionen in der Bibliothek Tc2_Utilities zur Verfügung, bspw. LrealIsNaN.
Try-Catch-Anweisung
Eine weitere Möglichkeit zum Umgang mit Exceptions ist die Einbettung in eine Try-Catch-Anweisung. In der SPS stehen dazu die Anweisungen __TRY, __CATCH, __FINALLY, __ENDTRY zur Verfügung. Sind auf der aufrufenden Task Floating Point Exceptions aktiviert und tritt innerhalb des Try-Catch eine Exception auf, so wird diese im Catch-Zweig gefangen und kann behandelt werden. Entsprechend werden bei dieser Vorgehensweise keine Variablen auf inf oder NaN gesetzt. Wichtig ist aber zu bemerken, dass der Code in Try-Zweig nur bis zu der Stelle der Exception durchlaufen wird und dann ein Sprung zum Catch-Zweig erfolgt. Im Applikationscode ist entsprechend zu beachten, dass interne Zustände im Try-Zweig ggf. nicht konsistent sind.
Dump Files
Ab TwinCAT 3.1.4024.22 (XAR) können zur Laufzeit Dump Files im Falle von Exceptions im TcCOM-Objekt erstellt werden.
Präzisierung des Verhaltens bei Exceptions auf Objekt-Ebene
Neben der Möglichkeit, das Verhalten bei Exceptions auf Task-Ebene zu beeinflussen, kann auch das Verhalten auf Ebene eines TwinCAT-Objekts, d. h. des generierten TcCOM oder des generierten SPS-Funktionsbausteins (PLC-FB), präzisiert werden.
Auf Objektebene ist mit dem TwinCAT Target for Simulink® eine Fülle an Möglichkeiten realisierbar. Im Grunde basieren aber alle im Folgenden dargelegten Optionen auf oben genannten Prinzipien.
Definition des Objekt-Verhaltens bei auftretenden Exceptions
Es stehen insgesamt 9 unterschiedliche Einstellungen zur Verfügung.
- CallerExceptions (default): Exceptions werden so ausgelöst, wie an der aufrufenden Task konfiguriert.
- ThrowExceptions: Exceptions im TwinCAT-Objekt werden in jedem Fall ausgelöst, unabhängig davon, wie die Task konfiguriert ist.
- Eine Exception verursacht eine TwinCAT Fehlermeldung und einen TwinCAT Stopp
- SuppressExceptions: Exceptions werden nicht ausgelöst, unabhängig davon wie die Task konfiguriert ist.
- Eine Exception verursacht keinen TwinCAT-Stopp.
- Ausgänge oder interne Zustände können NaN oder inf sein.
- LogExceptions: Exceptions werden ausgelöst, führen aber nicht zu einem TwinCAT-Stopp.
- Eine Exception verursacht keinen TwinCAT-Stopp.
- Ausgänge oder interne Zustände können NaN oder inf sein.
- Der Ausgang ExecutionInfo wird mit Informationen über eine Exception im aktuellen Zyklus gefüllt. Treten mehrere Exceptions in einem Zyklus auf, wird nur die erste Exception am Ausgang angezeigt. Beim erneuten Aufruf des TwinCAT-Objekts werden die Informationen zurückgesetzt.
- LogAndHold: Exceptions werden ausgelöst. Die Ausführung des TwinCAT-Objekts wird gestoppt.
- Eine Exception verursacht keinen TwinCAT-Stopp.
- Ausgänge oder interne Zustände können NaN oder inf sein.
- Der Ausgang ExecutionInfo wird mit Informationen über eine Exception im aktuellen Zyklus gefüllt. Treten mehrere Exceptions in einem Zyklus auf, wird nur die erste Exception am Ausgang angezeigt. Beim erneuten Aufruf des TwinCAT-Objekts werden die Informationen zurückgesetzt.
- Die Ausführung des TwinCAT-Objekts wird nach Auftreten einer Exception gestoppt. TwinCAT selbst bleibt im Run-Modus. Ausführung wieder Starten: ReleaseObjectStop.
- LogAndCatch: Exceptions werden mit try-catch im TwinCAT-Objekt gefangen. Die Ausführung des TwinCAT-Objekts wird gestoppt.
- Eine Exception verursacht keinen TwinCAT-Stopp.
- Ausgänge oder interne Zustände können keine NaN oder inf enthalten.
- Der Ausgang ExecutionInfo wird mit Informationen über eine Exception im aktuellen Zyklus gefüllt.
- Die Ausführung des Codes endet an der Stelle der Exception. Von dort wird in den Catch-Zweig gesprungen, d. h. interne Zustände können inkonsistent sein.
- Die Ausführung des TwinCAT-Objects wird nach Auftreten einer Exception gestoppt. TwinCAT selbst bleibt im Run-Modus. Ausführung wieder Starten: ReleaseObjectStop.
- LogAndDump, LogHoldAndDump und LogCatchAndDump
- Verhalten wie LogExceptions
- Zusätzlich wird ein Dump File auf dem Laufzeitsystem im TwinCAT Ordner Boot abgelegt. Weiteres zu Dump Files siehe Ende des Kapitels.
![]() | Versionsempfehlung für 64bit-Zielsysteme Bei Verwendung der Einstellungen „LogExceptions“, „LogAndHold“, „LogAndDump“, LogHoldAndDump“ wird die Nutzung einer XAR-Version von mindestens 3.1.4024.35 und TE1400-Version von mindestens 2.4.2.0 empfohlen. |
<< Einstellung für TcCOM >>
Das Verhalten eines TcCOM-Objekts bei auftretenden Exceptions können Sie unter TC TcCOM General in den Code Generation Settings in Simulink® definieren. Das Verhalten ist dabei getrennt für die Initialisierungsphase des TcCOM und für die Laufzeitphase (update phase) zu definieren.

Sollten Sie mit einem bereits kompilierten TcCOM in TwinCAT arbeiten, können Sie auch nachträglich die Einstellungen auf der Objekt-Instanz verändern. Nutzen Sie dazu den Reiter Parameter (init) und wählen Sie Show hidden Parameters.

<< Einstellung für PLC-FB >>
Die Einstellungen für den PLC-FB (SPS-Funktionsbaustein FB_<ModelName> in der SPS-Bibliothek) sind unabhängig von den Einstellungen zum TcCOM-Objekt unter TC PlcFb General vorzunehmen. Eine nachträgliche Anpassung der Exception-Optionen bei Verwendung des Funktionsbausteins in TwinCAT ist nicht vorgesehen.
Beachten Sie, dass der andere SPS-Funktionsbaustein FB_<ModelName>_TcCOM ein Wrapper für ein TcCOM-Objekt ist und somit bei dessen Verwendung die Exception-Einstellungen aus dem Bereich TcCOM gültig sind.

Optionaler ExecutionInfo Output
Werden auf Objektebene Exceptions behandelt, ist es sinnvoll, entsprechende Informationen über aufgetretene Exceptions am Objektausgang zugänglich zu machen. So kann an diesem Ausgang abgefragt werden, ob eine Exception aufgetreten ist, was für eine Exception es war, ob ein Dump File geschrieben wurde etc.
<< Einstellung für TcCOM >>
Für das TcCOM-Objekt können Sie einen zusätzlichen Ausgang „ExecutionInfo“ aktivieren über den Eintrag TC TcCom Interface.

Der Ausgang ExecutionInfo ist eine Struktur mit folgenden Einträgen:
ExecutionInfo Struktur
Eintrag | Datentyp | Bedeutung |
---|---|---|
CycleCount | ULINT | Aktueller Cycle Count (unabhängig von einer Exception) |
ExceptionCount | ULINT | Anzahl der bislang aufgetretenen Exceptions |
ActException | TcMgSdk.ExceptionInfo | Näherer Erläuterung zur aktuellen Exception (nur erste Exception im aktuellen Zyklus) |
TcMgSdk.ExceptionInfo
Eintrag | Datentyp | Bedeutung |
---|---|---|
ExceptionCode | DINT | Exception code |
TmxName | STRING(127) | Name des tmx-Treibers, der die Exception geworfen hat. |
TmxVersion | ARRAY[0..3] OF UDINT | Version des tmx-Treibers, der die Exception geworfen hat. |
InstructionAddr | UDINT | Relative Adresse im Speicher; Ort an dem die Exception aufgetreten ist. |
ReturnAddr | ARRAY[0..3] OF UDINT | Rücksprungadressen |
DumpCreated | BOOLEAN | TRUE, wenn ein Dump File zur Exception erstellt wurde. |
Mit der InstructionAddr ist es möglich, zu beurteilen, ob die Exception mit dem angegebenen ExceptionCode immer an der gleichen Stelle im Quellcode auftritt. Ist die InstructionAddr für wiederholende Exceptions gleich, tritt diese immer an der gleichen Stelle im Code auf. Über die ReturnAddr sehen Sie, woher die Aufrufe gekommen sind, die zur Stelle der Exception geführt haben. Sie können also beurteilen, ob der Aufruf, der zur Exception führt, immer denselben Aufrufweg nimmt. Wird der Code von außerhalb des Tmx-Treibers aufgerufen, steht in ReturnAddr eine 0.
Exception code | Bedeutung |
---|---|
0xC000008E | Divide by zero |
0xC000008F | Inexact result |
0xC0000090 | Invalid operation |
Nutzen Sie den TcCOM-Wrapper-FB, steht Ihnen die ExecutionInfo Struktur am Funktionsbaustein zur Verfügung. Beachten Sie, dass die Einträge entsprechend der TwinCAT Programmierkonventionen Präfixe entsprechend dem Datentyp tragen.
<< Einstellung für PLC-FB >>
Der PLC-FB beinhaltet als Properties immer nExceptionCount
und stActiveException
entsprechend obiger Definition. D.h. es muss keine Checkbox separat gesetzt werden, um diese Properties zu erhalten. Einziger, im Vergleich zum TcCOM, nicht vorhandener Parameter ist der Cycle Count, da dieser in der SPS bei bedarf sehr einfach selbst implementiert werden kann.
Ausführungsstopp eines TwinCAT-Objekts behandeln
LogAndHold und LogHoldAndDump
Im Falle einer Exception wird die Ausführung des Codes im betreffenden TcCOM-Objekt oder SPS-Funktionsbaustein (PLC-FB) durch Setzen des Parameters Execute auf FALSE gestoppt.
<< Einstellung für TcCOM >>
Der Paramater Execute kann aus dem XAE und per ADS gelesen bzw. geschrieben werden.
Im XAE können Sie auf dem TcCOM-Objekt unter Parameter (Init) dessen Online-Werte anzeigen lassen und verändern.


Im Blockdiagramm wird Ihnen der Parameter unter Module parameters angeboten.

Wenn Sie die Maus über den Namen Execute im Änderungsdialog führen, wird Ihnen, wie bei allen anderen Parametern auch, die ADS-Adresse des Parameters gezeigt. Damit können Sie den Parameter auch per ADS setzen.

Durch Rechtsklick auf den Namen Execute können Sie die ADS-Symbolinformationen auch in der Zwischenablage speichern. Auch dies gilt für alle anderen Parameter.

Nutzen Sie den TcCOM-Wrapper FB, können Sie den Parameter Execute durch Schreiben auf dem Property bExecute verändern.
<< Einstellung für PLC-FB >>
Der Parameter Execute ist am FB als Property bExecute
mit Lese- und Schreibrechten vorhanden. Nutzen Sie dieses Property, um die Ausführung des FB wieder zu starten.
LogAndCatch und LogCatchAndDump
Zusätzlich zum Parameter Execute wechselt, im Fall von LogAndCatch und LogCatchAndDump, auch der Online-Parameter Initialized nach FALSE. Das Modul muss neu initialisiert werden, bevor es wieder eine Berechnung durchführen kann. Dies ist notwendig, da interne Zustände, durch den Abbruch der Code-Ausführung an der Stelle der Exception, inkonsistent sein können.
<< Einstellung für TcCOM >>
Eine Reinitialisierung kann nur erfolgen, indem das TcCOM-Objekt in den Zustand „Init“ zurückgefahren und erneut nach OP gefahren wird. Zur Laufzeit können aber nur TcCOM-Objekte runtergefahren werden, welche keine Mappings haben, sonst würden aktive Mappings das Herunterfahren blockieren. Eine neue Initialisierung ist im Fall von aktiven Mappings am TcCOM nur möglich, indem die gesamte TwinCAT-Laufzeit neu gestartet wird. Es wird daher empfohlen den TcCOM-Wrapper-FB zu nutzen. Dieser kann genutzt werden, um das TcCOM aus des SPS aufzurufen und benötigt keine Mappings um auf dessen Eingänge und Ausgänge zuzugreifen. Entsprechend kann das TcCOM-Objekt auch während der Laufzeit neu initialisiert werden.
![]() | Property-Einstellungen für den TcCOM-Wrapper-FB Im Folgenden Beispiel-Code werden Properties, z.B. bExecute, gelesen. Erzeugen Sie den TcCOM-Wrapper-FB mit gesetzten TcCom Wrapper FB Properties und mit der Option “CyclicUdate“ für die Properties, damit untenstehender Code zum Wrapper passt. |
PROGRAM MAIN
VAR
stInitTemp : ST_FB_SimpleTempCtrl_TcCOM_InitStruct := (nOid := 16#01010010);
fbTempCtr : FB_SimpleTempCtrl_TcCOM_InitStruct(stInitTemp);
Inputs : ST_ExtU_SimpleTempCtrl_T;
Outputs : ST_ExtY_SimpleTempCtrl_T;
ExecutionOut : ST_ExecutionInfo2;
END_VAR
// check if TcCOM is in OP mode and all set
IF fbTempCtr.bExecute = TRUE AND fbTempCtr.bInitialized = TRUE AND fbTempCtr.nObjectState = TCOM_STATE.TCOM_STATE_OP THEN
// call the module
fbTempCtr(stSimpleTempCtrl_U := Inputs, stSimpleTempCtrl_Y => Outputs, stExecutionInfo => ExecutionOut);
// handle exceptions
IF ExecutionOut.ActException.ExceptionCode <> 0 THEN
// collect exception information
(* ...... *)
// reinit TcCOM
fbTempCtr.Reinit(stReInit := stInitTemp);
END_IF
END_IF
Beachten Sie, dass die ReInit-Methode synchron ausgeführt wird, d. h. je nach Zykluszeit und benötigter Zeit zum neu initialisieren, kann es zu Zyklusüberschreitungen kommen.
<< Einstellung für PLC-FB >>
Zur Prüfung, ob das hinterlegte Modul nicht (mehr) initialisiert ist, können Sie das Property bInitialized
am FB nutzen. Sie haben hier nur lesenden Zugriff. Eine Reinitialisierung ist derzeit nicht über eine Methode am FB möglich. Es muss die SPS-Laufzeit, alternativ die gesamte TwinCAT-Laufzeit, neu gestartet werden.
Dump-Files
Das Schreiben des Dump-Files kann einige Zyklen in Anspruch nehmen. Am besten sollte für das betreffende TcCOM-Objekt oder den PLC-FB eine separate Task verwendet werden, die keine wichtigen Tasks blockiert.
Dump-Files werden nur mit einer TwinCAT XAR Version >= 3.1.4024.22 geschrieben, ansonsten erhält man eine entsprechende Warnung.
Im Fall von LogAndDump wird die Ausführung des Codes nach Auftreten einer Exception zyklisch fortgeführt, es können entsprechend zyklisch Exceptions auftreten, die zu andauernden Zykluszeitüberschreitungen führen könnten. Daher wird der Online-Wert des Parameters UpdateExceptionHandling nach dem Schreiben des Dump-Files auf LogExceptions gesetzt, d. h. das Schreiben von Dump-Files wird deaktiviert, kann anschließend aber z. B. per ADS oder Eingriff über das XAE unter Parameter (Init) wieder eingeschaltet werden.
Das erstellte Dump-File wird auf dem Laufzeit-PC im Boot-Ordner abgelegt und kann von dort zur Analyse auf einen anderen PC kopiert werden. Bei Verwendung einer TwinCAT Version kleiner 3.1.4024.x können Sie die Dump-Files mit WinDbg öffnen und Ihre Analyse starten.