Exception handling

When processing the C++ code autogenerated from MATLAB® or Simulink® in TwinCAT, floating point exceptions can occur at runtime, for example if an unexpected value is passed into a function during programming. The handling of such exceptions is described below.

What is a floating point exception?

A floating point exception occurs when an arithmetically not exactly executable operation is instructed in the floating point unit of the CPU. IEEE 754 defines these cases: inexact, underflow, overflow, divide-by-zero, invalid-operation. If one of these cases occurs, a status flag is set, which indicates that the arithmetic operation cannot be executed exactly. It is further defined that each arithmetic operation must return a result – one that in the majority of cases leads to the possibility of ignoring the exception.

For example, a division by zero results in +inf or -inf. If a value is divided by inf in the further code, this results in zero, so that no consequential problems are to be expected. However, if inf is multiplied or other arithmetic operations are performed with inf, these are invalid operations, whose result is represented as a Not-a-Number (NaN).

How does the TwinCAT Runtime react in case of exceptions?

Exception handling 1:

TwinCAT C++ Debugger not active

The following explanations only apply if the C++ debugger is not activated on the TwinCAT runtime system. When the C++ debugger is enabled, exceptions are caught by the debugger and can be handled, see Debugging.

Standard behavior

Default setting in TwinCAT is that at divide-by-zero and invalid-operation the execution of the program is stopped and TwinCAT issues an error message.

Task setting: Floating Point Exceptions

This default setting can be changed on the level of each TwinCAT task. If the checkbox "Floating Point Exception" is unchecked, an exception does not lead to a TwinCAT stop and no error message is issued. This setting is then valid for all objects that are called by this task. As a consequence, care must be taken in the application that NaN and inf values are handled accordingly in the program code.

Check for NaN and Inf

If, for example, a NaN is passed on via mapping to a TwinCAT object that has activated floating point exceptions, an arithmetic operation with NaN naturally leads to an exception in this object and subsequently to a TwinCAT stop. Therefore, NaN or inf must be checked directly after mapping. In the PLC, corresponding functions are available in the Tc2_Utilities library, e.g. LrealIsNaN.

Try-Catch statement

Another way to handle exceptions is to embed them in a try-catch statement. In the PLC the instructions __TRY, __CATCH, __FINALLY, __ENDTRY are available for this purpose. If floating point exceptions are enabled on the calling task and an exception occurs within the Try-Catch, it is caught in the Catch branch and can be handled. Accordingly, no variables are set to inf or NaN in this approach. However, it is also important to note that the code in the Try branch is run through only up to the point of the exception and then a jump is made to the Catch branch. In the application code, it should be noted that internal states in the Try branch may not be consistent.

Dump Files

From TwinCAT 3.1.4024.22 (XAR), dump files can be created at runtime in case of exceptions in the TcCOM object.

Specification of the behavior in case of exceptions on object level

In addition to the possibility of influencing the behavior in the event of exceptions at task level, the behavior can also be specified at the level of a TwinCAT object, i.e. the generated TcCOM or the generated PLC function block.

On the object level, a wealth of possibilities can be realized with the TwinCAT Target for Simulink®. Basically, however, all the options presented below are based on the above principles.

Optional ExecutionInfo Output

If exceptions are handled at object level, it makes sense to make corresponding information about occurred exceptions accessible at the object output. This output can be used to query whether an exception has occurred, what kind of exception it was, whether a dump file has been written, etc.

For the TcCOM object you can activate an additional output "ExecutionInfo":

exportConfig.ClassExportCfg{nModuleCount}.TcCom.ExecutionInfoOutput = true;
Exception handling 2:

ExecutionInfo Output for PLC-FB

Currently the ExecutionInfo is only available for the TcCOM object. If you want to call the code from the PLC, use the TcCOM-Wrapper-FB.

The ExecutionInfo output is a structure with the following entries:

ExcecutionInfo structure

Entry

Data type

Meaning

CycleCount

ULINT

Current cycle count (independent of an exception)

ExceptionCount

ULINT

Number of exceptions that have occurred so far

ActException

TcMgSdk.ExceptionInfo

More detailed explanation of the current exception (only first exception in the current cycle)

TcMgSdk.ExceptionInfo

ExceptionCode

DINT

Code of the exception, cf. Microsoft Help

TmxName

STRING(127)

Name of the tmx driver that threw the exception.

TmxVersion

ARRAY[0..3] OF UDINT

Version of the tmx driver that threw the exception.

InstructionAddr

UDINT

Relative address in memory; location where the exception occurred.

ReturnAddr

ARRAY[0..3] OF UDINT

Return addresses

DumpCreated

BOOLEAN

TRUE if a dump file was created for the exception.

With the InstructionAddr it is possible to judge if the exception with the given ExceptionCode always occurs at the same place in the source code. If the InstructionAddr is the same for repeating exceptions, it always occurs at the same point in the code. Via ReturnAddr you can see where the calls came from that led to the location of the exception. So you can judge if the call that leads to the exception always takes the same call path. If the code is called from outside the Tmx driver, there is a 0 in the ReturnAddr.

Definition of the object behavior in case of occurring exceptions

The behavior of a TcCOM object in case of exceptions can be set separately for the initialization phase and for the update phase under the properties of the class TwinCAT.ModuleGenerator.ProjectExportConfig:

exportConfig.ClassExportCfg{ nModuleCount }.TcCom.UpdateExceptionHandling = 'CallerExceptions';
exportConfig.ClassExportCfg{ nModuleCount }.TcCom.InitExceptionHandling = 'CallerExceptions';

Options are: CallerExceptions, ThrowExceptions, SuppressExceptions, LogExceptions, LogAndHold, LogAndCatch, LogAndDump, LogHoldAndDump, LogCatchAndDump.

If you are working with an already compiled TcCOM in TwinCAT, you can also change the settings on the object instance afterwards. To do this, use the tab Parameters (Init) and select Show hidden Parameters.

Exception handling 3:

The settings for the PLC-FB FB_<ModelName> in the PLC library are independent of the settings for the TcCOM object.

exportConfig.ClassExportCfg{nModuleCount}.PlcFb.UpdateExceptionHandling

exportConfig.ClassExportCfg{nModuleCount}.PlcFb.InitExceptionHandling

Note that the other PLC function block (FB_<ModelName>_TcCOM) is a wrapper for a TcCOM object and therefore the exception settings from the TcCOM section are valid when it is used.

A total of 9 different settings are available.

A total of 9 different settings are available.

Handle execution stop of a TwinCAT object

LogAndHold and LogHoldAndDump

In the event of an exception, execution of the code in the TcCOM object concerned is stopped by setting the Execute parameter to FALSE. The parameter can be read or written from the XAE and via ADS.

In the XAE, you can display and change the online values of the TcCOM object under Parameters (Init).

Exception handling 4:
Exception handling 5:

In the block diagram the parameter is offered to you under Module parameters.

Exception handling 6:

If you move the mouse over the Execute name in the change dialog, you will be shown the ADS address of the parameter, as with all other parameters. This allows you to set the parameter also by ADS.

Exception handling 7:

By right-clicking on the name Execute you can also save the ADS symbol information to the clipboard. This also applies to all other parameters.

Exception handling 8:

LogAndCatch and LogCatchAndDump

In addition to the parameter Execute, the online parameter Initialized also changes to FALSE in the case of LogAndCatch and LogCatchAndDump. The module must be reinitialized before the module can perform a calculation again. This is necessary because internal states can no longer be consistent. Reinitialization can only be performed by returning the TcCOM object to the "Init" state and moving it to OP again.

At runtime, only TcCOM objects that have no mappings can be shut down, otherwise active mappings would block the shutdown. A new initialization is only possible by restarting the entire TwinCAT Runtime.

A more flexible alternative is to use the TcCOM-Wrapper-FB in the PLC. This can be used to call the TcCOM from the PLC and does not require any mappings to access its inputs and outputs. Accordingly, the TcCOM object can also be reinitialized during runtime.

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

Note that the ReInit method is executed synchronously, i.e. depending on the cycle time and the time required to reinitialize, cycle overruns may occur.

Dump files

Writing the dump file may take a few cycles. It is best to use a separate task for the TcCOM object or the PLC-FB in question that does not block any important tasks.

Dump files are only written with a TwinCAT XAR version >= 3.1.4024.22, otherwise you get a corresponding warning.

In the case of LogAndDump the execution of the code is continued cyclically after the occurrence of an exception, accordingly exceptions can occur cyclically which could lead to persistent cycle timeouts. Therefore, the online value of the parameter UpdateExceptionHandling is set to LogExceptions after the dump file has been written, i.e. the writing of dump files is deactivated, but can subsequently be switched on again, e.g. by ADS or intervention via the XAE under parameter (Init).

The created dump file is stored on the runtime PC in the boot folder and can be copied from there to another PC for analysis. If you use a TwinCAT version lower than 3.1.4024.x you can open the dump files with WinDbg and start your analysis.