Supported platforms: CODESYS 3.5 SAFETYCODESYS 3.5 SP19 SAFETY

 

Reviewing Diagnostics

This section describes how to review generated code for safety project diagnostics.

 

This guide focuses mainly on safety related implementation.

 

 

S_Safety_Status (PRG)

 

This program contains conditions for safety related diagnostic conditions.

 

  1. Verify that the program checks the hardware specific diagnostic status OK flag

  2. Verify that the program checks the SRDO signature valid condition

  3. Verify that program checks the safety parameters valid condition

  4. Verify that the program checks the GFC status

 

Error codes are added to application log only when device description includes SafeErrorLog library. In SC52 device description 3.5.10.6 or later is required.

See also How to use application error log.

 

The following is an example implementation of S_Safety_Status program

 

SC52 Safety Control UnitSC52 Safety Control Unit

Code:

IF EPEC_SHWD.S_SC52_Diagnostic.S_o_DiagStatusOk AND (* System diagnostic ok*)

    i_Safe_InitDone AND     (* Init has been executed successfully *)

    i_Nonsafe_InitDone AND (*Non - safe init has been executed successfully *)

    S_i_SafetySignaturesValid AND (*SRDO safety signatures are valid *)

    S_i_SafetyParametersValid AND (*All safety parameters are valid *)

    G_CANOPEN_GFC_VALID <> G_CANopen_CAN1_VAR.GFC_Status AND

    (* No CANopen protocol errors *)

    NOT Init_CANopen_CAN1.o_Error

THEN

    S_o_SafeOperationEnable := TRUE;

ELSE

    // Add error on falling edge

    IF S_o_SafeOperationEnable THEN

        EPEC_SERRLOG.S_AddError_DWORD(i_ErrorCode := ApplicationErrors.SAFE_OPERATION_DISABLED,

  i_LibraryErrorCode := EPEC_SERRLOG.LibConstants.G_ErrorNA, i_Info1:=0, i_Info2:=0);

    END_IF

 

    S_o_SafeOperationEnable := FALSE;

 

    // Check for GFC activation

    EPEC_SERRLOG.S_AddError_DWORD(i_ErrorCode:=ApplicationErrors.GFC_STATUS,

    i_LibraryErrorCode:=BYTE_TO_DINT(G_CANopen_CAN1_VAR.GFC_Status),i_Info1:=0, i_Info2:=1);

 

    // Check HW diagnostic errors when diagnostic is enabled

    // Following code is product specific

    (*...*)

END_IF

 

 

 

SL84 Safety Control UnitSL84 Safety Control Unit

Code:

IF EPEC_SHWD.S_SL84_Diagnostic.S_o_DiagStatusOk AND (* System diagnostic ok*)

    i_Safe_InitDone AND     (* Init has been executed successfully *)

    i_Nonsafe_InitDone AND (*Non - safe init has been executed successfully *)

    S_i_SafetySignaturesValid AND (*SRDO safety signatures are valid *)

    S_i_SafetyParametersValid AND (*All safety parameters are valid *)

    G_CANOPEN_GFC_VALID <> G_CANopen_CAN1_VAR.GFC_Status AND

    (* No CANopen protocol errors *)

    NOT Init_CANopen_CAN1.o_Error

THEN

    S_o_SafeOperationEnable := TRUE;

 

   (*Output group 1 voltage status for output controls*)

   IF EPEC_SHWD.S_SL84_Diagnostic.S_o_SupplyVoltageGroup1 >= G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_LOW_LIMIT AND

      EPEC_SHWD.S_SL84_Diagnostic.S_o_SupplyVoltageGroup1 <= G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

   THEN

      G_StatusFlags_Safe.S_OutputGroup1VoltageOK:=TRUE;

   ELSE

      G_StatusFlags_Safe.S_OutputGroup1VoltageOK:=FALSE;

   END_IF

 

   (*Output group 2 voltage status for output controls*)

   IF EPEC_SHWD.S_SL84_Diagnostic.S_o_SupplyVoltageGroup2 >= G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_LOW_LIMIT AND

      EPEC_SHWD.S_SL84_Diagnostic.S_o_SupplyVoltageGroup2 <= G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

   THEN

      G_StatusFlags_Safe.S_OutputGroup2VoltageOK:=TRUE;

   ELSE

      G_StatusFlags_Safe.S_OutputGroup2VoltageOK:=FALSE;

   END_IF

 

   (*Output group 3 voltage status for output controls*)

   IF EPEC_SHWD.S_SL84_Diagnostic.S_o_SupplyVoltageGroup3 >= G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_LOW_LIMIT AND

      EPEC_SHWD.S_SL84_Diagnostic.S_o_SupplyVoltageGroup3 <= G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

   THEN

      G_StatusFlags_Safe.S_OutputGroup3VoltageOK:=TRUE;

   ELSE

      G_StatusFlags_Safe.S_OutputGroup3VoltageOK:=FALSE;

   END_IF

 

ELSE

    // Add error on falling edge

    IF S_o_SafeOperationEnable THEN

        EPEC_SERRLOG.S_AddError_DWORD(i_ErrorCode := ApplicationErrors.SAFE_OPERATION_DISABLED,

  i_LibraryErrorCode := EPEC_SERRLOG.LibConstants.G_ErrorNA, i_Info1:=0, i_Info2:=0);

    END_IF

 

    S_o_SafeOperationEnable := FALSE;

 

   G_StatusFlags_Safe.S_OutputGroup1VoltageOK:=FALSE;

   G_StatusFlags_Safe.S_OutputGroup2VoltageOK:=FALSE;

   G_StatusFlags_Safe.S_OutputGroup3VoltageOK:=FALSE;

 

    // Check for GFC activation

    EPEC_SERRLOG.S_AddError_DWORD(i_ErrorCode:=ApplicationErrors.GFC_STATUS,

    i_LibraryErrorCode:=BYTE_TO_DINT(G_CANopen_CAN1_VAR.GFC_Status),i_Info1:=0, i_Info2:=1);

 

    // Check HW diagnostic errors when diagnostic is enabled

    // Following code is product specific

    (*...*)

END_IF

 

 

 

 

 

 

SL8X1-01 Control UnitSL8X1-01 Control Unit

Code:

IF EPEC_HWDIAG.S_SL8X1_Diagnostic.S_o_DiagStatusOk AND (* System diagnostic ok*) 
    i_Safe_InitDone AND     (* Init has been executed successfully *) 
    i_Nonsafe_InitDone AND (*Non - safe init has been executed successfully *) 
    S_i_SafetySignaturesValid AND (*SRDO safety signatures are valid *) 
    S_i_SafetyParametersValid AND (*All safety parameters are valid *) 
    G_CANOPEN_GFC_VALID <> G_CANopen_CAN1_VAR.GFC_Status AND
    (* No CANopen protocol errors *)
     NOT Init_CANopen_CAN1.o_Error
THEN
    S_o_SafeOperationEnable := TRUE;    
ELSE 
    // Add error on falling edge
    IF S_o_SafeOperationEnable THEN
        EPEC_SERRLOG.S_AddError_DWORD(i_ErrorCode := ApplicationErrors.SAFE_OPERATION_DISABLED, i_LibraryErrorCode := EPEC_SERRLOG.LibConstants.G_ErrorNA, i_Info1:=0, i_Info2:=0);
    END_IF


    S_o_SafeOperationEnable := FALSE;
    
    // Check for CAN1 GFC activation
    EPEC_SERRLOG.S_AddError_DWORD(i_ErrorCode:=ApplicationErrors.GFC_STATUS, i_LibraryErrorCode:=BYTE_TO_DINT(G_CANopen_CAN1_VAR.GFC_Status), i_Info1:=0, i_Info2:=1);


    // Check HW diagnostic errors

    // Following code is product specific

    (*...*)

END_IF


 

 

Following are product specific hardware diagnostic errors which are added to application log (when available).

 

SC52 Safety Control UnitSC52 Safety Control Unit

Code:

// Check HW diagnostic errors when diagnostic is enabled

IF EPEC_SHWD.S_SC52_Diagnostic.S_o_Running AND NOT EPEC_SHWD.S_SC52_Diagnostic.S_o_DiagStatusOk THEN

EPEC_SERRLOG.S_AddError_DWORD(

i_ErrorCode := ApplicationErrors.HW_DIAGNOSTIC_FAULT,

i_LibraryErrorCode := EPEC_SERRLOG.LibConstants.G_ErrorNA,

i_Info1 := 0,

i_Info2 := 0);

// output group 1

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_OUT_PWR_GRP_1,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_OutputGroup1Control_EC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_OutputGroup1Control_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_OutputGroup1Control_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_OutputGroup1Control_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

// REF output

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_OUT_REF_1,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_RefControl_EC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_RefControl_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_RefControl_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_RefControl_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

// supply voltage

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_SUPPLY,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_SupplyVoltag_EC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_SupplyVoltag_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_SupplyVoltag_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_SupplyVoltag_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

// 5VAN

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_5VAN,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_5VAN_EC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_5VAN_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_5VAN_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_5VAN_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

// MCU temperature

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_MCU_TEMP,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_MCUTemperatureEC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_MCUTemperatureEC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_MCUTemperatureEC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_MCUTemperatureEC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

// SBC temperature

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_SBC_TEMP,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_SBCTemperatureEC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_SBCTemperatureEC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_SBCTemperatureEC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_SBCTemperatureEC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

// PCB temperature 1

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_PCB_TEMP_1,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh1_EC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh1_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh1_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh1_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

// PCB temperature 2

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_PCB_TEMP_2,

i_LibraryErrorCode := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh2_EC.EventID,

i_Info1 := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh2_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh2_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SC52_Diagnostic.o_PCBTemperatureCh2_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

 

END_IF

 

 

 

SL84 Safety Control UnitSL84 Safety Control Unit

Code:

// Check HW diagnostic errors when diagnostic is enabled

IF EPEC_SHWD.S_SL84_Diagnostic.S_o_Running AND NOT EPEC_SHWD.S_SL84_Diagnostic.S_o_DiagStatusOk THEN

 

EPEC_SERRLOG.S_AddError_DWORD(

i_ErrorCode := ApplicationErrors.HW_DIAGNOSTIC_FAULT,

i_LibraryErrorCode := EPEC_SERRLOG.LibConstants.G_ErrorNA,

i_Info1 := 0,

i_Info2 := 0);

 

// Supply voltage group 1

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_OUT_PWR_GRP_1,

i_LibraryErrorCode := EPEC_SHWD.S_SL84_Diagnostic.o_SupplyVoltageGroup1_EC.EventID,

i_Info1 := EPEC_SHWD.S_SL84_Diagnostic.o_SupplyVoltageGroup1_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SL84_Diagnostic.o_SupplyVoltageGroup1_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SL84_Diagnostic.o_SupplyVoltageGroup1_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

 

// REF output

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_OUT_REF_1,

i_LibraryErrorCode := EPEC_SHWD.S_SL84_Diagnostic.o_RefControl_EC.EventID,

i_Info1 := EPEC_SHWD.S_SL84_Diagnostic.o_RefControl_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SL84_Diagnostic.o_RefControl_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SL84_Diagnostic.o_RefControl_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

 

// MCU temperature

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_MCU_TEMP,

i_LibraryErrorCode := EPEC_SHWD.S_SL84_Diagnostic.o_MCUTemperatureEC.EventID,

i_Info1 := EPEC_SHWD.S_SL84_Diagnostic.o_MCUTemperatureEC.FunctionID,

i_Info2 := EPEC_SHWD.S_SL84_Diagnostic.o_MCUTemperatureEC.DeviceID,

i_Info3 := EPEC_SHWD.S_SL84_Diagnostic.o_MCUTemperatureEC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

 

// SBC temperature

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_SBC_TEMP,

i_LibraryErrorCode := EPEC_SHWD.S_SL84_Diagnostic.o_SBCTemperatureEC.EventID,

i_Info1 := EPEC_SHWD.S_SL84_Diagnostic.o_SBCTemperatureEC.FunctionID,

i_Info2 := EPEC_SHWD.S_SL84_Diagnostic.o_SBCTemperatureEC.DeviceID,

i_Info3 := EPEC_SHWD.S_SL84_Diagnostic.o_SBCTemperatureEC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

 

// PCB temperature

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.HW_DIAG_IN_PCB_TEMP_1,

i_LibraryErrorCode := EPEC_SHWD.S_SL84_Diagnostic.o_PCBTemperatureCh1_EC.EventID,

i_Info1 := EPEC_SHWD.S_SL84_Diagnostic.o_PCBTemperatureCh1_EC.FunctionID,

i_Info2 := EPEC_SHWD.S_SL84_Diagnostic.o_PCBTemperatureCh1_EC.DeviceID,

i_Info3 := EPEC_SHWD.S_SL84_Diagnostic.o_PCBTemperatureCh1_EC.ChannelID,

i_Info4 := 0,

i_Info5 := 0,

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

END_IF

 

 

 

 

SL8X1-01 Control UnitSL8X1-01 Control Unit

 

Code:

    IF EPEC_HWDIAG.S_SL8X1_Diagnostic.o_DiagEnableStates.OutputGroup1_Diagnostic_Enable AND NOT EPEC_HWDIAG.S_SL8X1_Diagnostic.S_o_DiagStatusOk THEN
        // Trigger error if S_o_DiagStatusOk is not OK after output group diagnostic is enabled
        EPEC_SERRLOG.S_AddError_DWORD(
            i_ErrorCode := ApplicationErrors.HW_DIAGNOSTIC_FAULT,
            i_LibraryErrorCode := EPEC_SERRLOG.LibConstants.G_ErrorNA,
            i_Info1 := 0,
            i_Info2 := 0);
    END_IF
    // output group 1
    EPEC_SERRLOG.S_AddError_BYTE(
        i_ErrorCode := ApplicationErrors.HW_DIAG_OUT_PWR_GRP_1,
        i_LibraryErrorCode := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_OutputGroup1Control_EC.EventID,
        i_Info1 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_OutputGroup1Control_EC.FunctionID,
        i_Info2 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_OutputGroup1Control_EC.DeviceID,
        i_Info3 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_OutputGroup1Control_EC.ChannelID,
        i_Info4 := 0,
        i_Info5 := 0,
        i_Info6 := 0,
        i_Info7 := 0,
        i_Info8 := 0);

    // REF A output
    EPEC_SERRLOG.S_AddError_BYTE(
        i_ErrorCode := ApplicationErrors.HW_DIAG_OUT_REF_1,
        i_LibraryErrorCode := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefAControl_EC.EventID,
        i_Info1 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefAControl_EC.FunctionID,
        i_Info2 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefAControl_EC.DeviceID,
        i_Info3 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefAControl_EC.ChannelID,
        i_Info4 := 0,
        i_Info5 := 0,
        i_Info6 := 0,
        i_Info7 := 0,
        i_Info8 := 0);

    // REF B output
    EPEC_SERRLOG.S_AddError_BYTE(
        i_ErrorCode := ApplicationErrors.HW_DIAG_OUT_REF_2,
        i_LibraryErrorCode := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefBControl_EC.EventID,
        i_Info1 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefBControl_EC.FunctionID,
        i_Info2 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefBControl_EC.DeviceID,
        i_Info3 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_RefBControl_EC.ChannelID,
        i_Info4 := 0,
        i_Info5 := 0,
        i_Info6 := 0,
        i_Info7 := 0,
        i_Info8 := 0);

    // supply voltage
    EPEC_SERRLOG.S_AddError_BYTE(
        i_ErrorCode := ApplicationErrors.HW_DIAG_IN_SUPPLY,
        i_LibraryErrorCode := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_SupplyVoltage_EC.EventID,
        i_Info1 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_SupplyVoltage_EC.FunctionID,
        i_Info2 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_SupplyVoltage_EC.DeviceID,
        i_Info3 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_SupplyVoltage_EC.ChannelID,
        i_Info4 := 0,
        i_Info5 := 0,
        i_Info6 := 0,
        i_Info7 := 0,
        i_Info8 := 0);

    // MCU temperature
    EPEC_SERRLOG.S_AddError_BYTE(
        i_ErrorCode := ApplicationErrors.HW_DIAG_IN_MCU_TEMP,
        i_LibraryErrorCode := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_MCUTemperatureEC.EventID,
        i_Info1 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_MCUTemperatureEC.FunctionID,
        i_Info2 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_MCUTemperatureEC.DeviceID,
        i_Info3 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_MCUTemperatureEC.ChannelID,
        i_Info4 := 0,
        i_Info5 := 0,
        i_Info6 := 0,
        i_Info7 := 0,
        i_Info8 := 0);

    // PCB temperature 1
    EPEC_SERRLOG.S_AddError_BYTE(
        i_ErrorCode := ApplicationErrors.HW_DIAG_IN_PCB_TEMP_1,
        i_LibraryErrorCode := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh1_EC.EventID,
        i_Info1 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh1_EC.FunctionID,
        i_Info2 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh1_EC.DeviceID,
        i_Info3 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh1_EC.ChannelID,
        i_Info4 := 0,
        i_Info5 := 0,
        i_Info6 := 0,
        i_Info7 := 0,
        i_Info8 := 0);

    // PCB temperature 2
    EPEC_SERRLOG.S_AddError_BYTE(
        i_ErrorCode := ApplicationErrors.HW_DIAG_IN_PCB_TEMP_2,
        i_LibraryErrorCode := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh2_EC.EventID,
        i_Info1 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh2_EC.FunctionID,
        i_Info2 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh2_EC.DeviceID,
        i_Info3 := EPEC_HWDIAG.S_SL8X1_Diagnostic.o_PCBTemperatureCh2_EC.ChannelID,
        i_Info4 := 0,
        i_Info5 := 0,
        i_Info6 := 0,
        i_Info7 := 0,
        i_Info8 := 0);

 

 

 

S_PLC_PRG

 

  1. Verify that the hardware specific diagnostic program's Init method is executed at the initialization phase

 

The following are product specific examples of HW diagnostic Init

 

SC52 Safety Control UnitSC52 Safety Control Unit

Code:

ELSIF NOT EPEC_SHWD.S_SC52_Diagnostic.S_o_InitReady THEN

EPEC_SHWD.S_SC52_Diagnostic.Init(

S_i_SupplyVoltageHighLimit := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT,

S_i_SupplyVoltageLowLimit := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_LOW_LIMIT,

S_i_SupplyVoltageDiagDelay := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_DELAY,  

S_i_5VRefControlTolerance := G_CONSTANTS.DIAG_5V_REF_TOLERANCE,

S_i_5VRefControlDiagDelay := G_CONSTANTS.DIAG_5V_REF_DELAY,

S_i_OutputGroup1HighVoltage := G_CONSTANTS.DIAG_OUTPUT_GROUP1_HIGH_LIMIT,

S_i_OutputGroup1LowVoltage:= G_CONSTANTS.DIAG_OUTPUT_GROUP1_LOW_LIMIT,

S_i_OutputGroup1DiagDelay:= G_CONSTANTS.DIAG_OUTPUT_GROUP1_DELAY,

S_i_5VANHighVoltage:= G_CONSTANTS.DIAG_5V_VAN_HIGH_LIMIT,

S_i_5VANLowVoltage:= G_CONSTANTS.DIAG_5V_VAN_LOW_LIMIT,

S_i_5VANDiagDelay:= G_CONSTANTS.DIAG_5V_VAN_DELAY,

S_i_TemperatureHighLimit:= G_CONSTANTS.DIAG_TEMP_HIGH_LIMIT,

S_i_TemperatureLowLimit:= G_CONSTANTS.DIAG_TEMP_LOW_LIMIT,

S_i_TemperatureDiagDelay:= G_CONSTANTS.DIAG_TEMP_DELAY);

 

 

 

SL84 Safety Control UnitSL84 Safety Control Unit

Code:

ELSIF NOT EPEC_SHWD.S_SL84_Diagnostic.S_o_InitReady THEN

EPEC_SHWD.S_SL84_Diagnostic.Init(

S_i_SupplyVoltageHighLimit := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT,

S_i_SupplyVoltageLowLimit := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_LOW_LIMIT,

S_i_SupplyVoltageDiagDelay := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_DELAY,  

S_i_RefControlDiagDelay := G_CONSTANTS.DIAG_5V_REF_DELAY,

S_i_TemperatureHighLimit:= G_CONSTANTS.DIAG_TEMP_HIGH_LIMIT,

S_i_TemperatureLowLimit:= G_CONSTANTS.DIAG_TEMP_LOW_LIMIT,

S_i_TemperatureDiagDelay:= G_CONSTANTS.DIAG_TEMP_DELAY);

 

 

 

 

SL8X1-01 Control UnitSL8X1-01 Control Unit

Code:

    ELSIF NOT EPEC_HWDIAG.S_SL8X1_Diagnostic.o_InitReady THEN
        EPEC_HWDIAG.S_SL8X1_Diagnostic.Init(
            S_i_SupplyVoltageHighLimit := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT,
            S_i_SupplyVoltageLowLimit := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_LOW_LIMIT,
            S_i_SupplyVoltageDiagDelay := G_CONSTANTS.DIAG_SUPPLY_VOLTAGE_DELAY,
            S_i_RefAInUse := TRUE,
            S_i_RefAType5V := TRUE,
            S_i_RefAControlTolerance := G_CONSTANTS.DIAG_REF_5V_TOLERANCE,
            S_i_RefAControlDiagDelay := G_CONSTANTS.DIAG_REF_5V_DELAY,
            S_i_RefAControlChangeDiagDelay := G_CONSTANTS.DIAG_REF_5V_CONTROL_CHANGE_DELAY,
            S_i_RefBInUse := TRUE,
            S_i_RefBType5V := FALSE,
            S_i_RefBControlTolerance := G_CONSTANTS.DIAG_REF_10V_TOLERANCE,
            S_i_RefBControlDiagDelay := G_CONSTANTS.DIAG_REF_10V_DELAY,
            S_i_RefBControlChangeDiagDelay := G_CONSTANTS.DIAG_REF_10V_CONTROL_CHANGE_DELAY,
            S_i_OutputGroup1HighVoltage := G_CONSTANTS.DIAG_OUTPUT_GROUP1_HIGH_LIMIT,
            S_i_OutputGroup1LowVoltage := G_CONSTANTS.DIAG_OUTPUT_GROUP1_LOW_LIMIT,
            S_i_OutputGroup1DiagDelay := G_CONSTANTS.DIAG_OUTPUT_GROUP1_DELAY,
            S_i_MCUTemperatureHighLimit := G_CONSTANTS.DIAG_MCU_TEMP_HIGH_LIMIT,
            S_i_MCUTemperatureLowLimit := G_CONSTANTS.DIAG_MCU_TEMP_LOW_LIMIT,
            S_i_MCUTemperatureDiagDelay := G_CONSTANTS.DIAG_MCU_TEMP_DELAY,
            S_i_PCB1TemperatureHighLimit := G_CONSTANTS.DIAG_PCB1_TEMP_HIGH_LIMIT,
            S_i_PCB1TemperatureLowLimit := G_CONSTANTS.DIAG_PCB1_TEMP_LOW_LIMIT,
            S_i_PCB1TemperatureDiagDelay := G_CONSTANTS.DIAG_PCB1_TEMP_DELAY,
            S_i_PCB2TemperatureHighLimit := G_CONSTANTS.DIAG_PCB2_TEMP_HIGH_LIMIT,
            S_i_PCB2TemperatureLowLimit := G_CONSTANTS.DIAG_PCB2_TEMP_LOW_LIMIT,
            S_i_PCB2TemperatureDiagDelay := G_CONSTANTS.DIAG_PCB2_TEMP_DELAY
        );


 

 

  1. Verify that the hardware specific diagnostic program is executed at the run phase

 

The following are product specific examples of HW diagnostic

 

SC52 Safety Control UnitSC52 Safety Control Unit

Code:

ELSIF PLC_PRG.o_Initdone THEN

(* Safe actions to execute before safe main program *)

S_Inputs(i_Initialize:=FALSE);

(*...*)

EPEC_SHWD.S_SC52_Diagnostic(

      i_5VRefChannel1:= S_Inputs.o_AI_REF_5V_MAIN_Diagnostic,

i_5VRefChannel2:=S_Inputs.o_AI_REF_5V_RED_Diagnostic,

i_SupplyVoltageInPin := S_Inputs.o_AI_SUPPLY_PIN_VOLTAGE_Diagnostic,

i_SupplyBeforeSafetySwitch1:= S_Inputs.o_AI_POWER1_SUPPLY_Diagnostic,

i_SupplyAfterSafetySwitch1 := S_Inputs.o_AI_POWER1_OUTPUT_Diagnostic,

i_5VANChannel1:=S_Inputs.o_AI_5V_VAN_MAIN_Diagnostic,

i_5VANChannel2:=S_Inputs.o_AI_5V_VAN_RED_Diagnostic,

i_MCUTemperature:=S_Inputs.o_TEMP_MCU_Diagnostic,

i_SBCTemperature:=S_Inputs.o_TEMP_SBC_Diagnostic,

i_PCBTemperatureChannel1:=S_Inputs.o_TEMP_PCB_MAIN_Diagnostic,

i_PCBTemperatureChannel2:=S_Inputs.o_TEMP_PCB_RED_Diagnostic,

i_Negative5V:=S_Inputs.o_AI_5V_NEG_Diagnostic);

 

 

 

SL84 Safety Control UnitSL84 Safety Control Unit

Code:

ELSIF PLC_PRG.o_Initdone THEN

(* Safe actions to execute before safe main program *)

S_Inputs(i_Initialize:=FALSE);

(*...*)

EPEC_SHWD.S_SL84_Diagnostic(

      i_RefChannel1 := S_Inputs.o_AI_5V_REF_Diagnostic,

i_SupplyVoltageGroup1 := S_Inputs.o_AI_POWER1_SUPPLY_Diagnostic,

i_SupplyVoltageGroup2 := S_Inputs.o_AI_POWER2_SUPPLY_Diagnostic,

i_SupplyVoltageGroup3 := S_Inputs.o_AI_POWER3_SUPPLY_Diagnostic,

i_MCUTemperature := S_Inputs.o_TEMP_MCU_Diagnostic,

i_SBCTemperature := S_Inputs.o_AI_SBC_TEMP_Diagnostic,

i_PCBTemperatureChannel1 := S_Inputs.o_AI_PCB_TEMP_Diagnostic);

 

 

 

 

SL8X1-01 Control unitSL8X1-01 Control unit

Code:

ELSIF PLC_PRG.o_Initdone THEN

(* Safe actions to execute before safe main program *)

S_Inputs(i_Initialize:=FALSE);

(*...*)

EPEC_HWDIAG.S_SL8X1_Diagnostic(
    i_SupplyVoltageInPin := S_Inputs.o_AI_VIN_V_Diagnostic,
    i_SupplyBeforeSafetySwitch1:= S_Inputs.o_AI_VIN_V_Diagnostic,
    i_SupplyAfterSafetySwitch1:= S_Inputs.o_AI_VOUT_SAFE_Diagnostic,
    i_RefAChannel1:= S_Inputs.o_AI_5V_REF_OUTPUT_MAIN_Diagnostic,
    i_RefAChannel2:= S_Inputs.o_AI_5V_REF_OUTPUT_RED_Diagnostic,
    i_RefBChannel1:= S_Inputs.o_AI_10V_REF_OUTPUT_MAIN_Diagnostic,
    i_RefBChannel2:= S_Inputs.o_AI_10V_REF_OUTPUT_RED_Diagnostic,
    i_MCUTemperature:= S_Inputs.o_AI_MCU_C_Diagnostic,
    i_PCBTemperatureChannel1:= S_Inputs.o_AI_PCB_1_V_Diagnostic,
    i_PCBTemperatureChannel2:= S_Inputs.o_AI_PCB_2_V_Diagnostic,
    i_CableDetectionSavedNodeId := TO_BYTE(G_SystemInfo.WireHarnessId[28]), // use stored offset as saved value
    i_CableDetectionDetectedNodeId := TO_BYTE(G_SystemInfo.WireHarnessId[27]) // use calculated offset as detected value
);


 

  1. Verify that the S_Safety_Status program is executed at the run phase.

 

Safety related application shall go to safe state when S_SafeOperationEnable is FALSE.

 

The following is an example of SC52 Safety Control Unit when SRDO messages and safety parameters are both used.

SRDO signature and safety parameter CRC are considered valid if they are not used.

Code:

EPEC_SHWD.S_SC52_Diagnostic(...);

 

S_Safety_Status(i_Safe_InitDone:= o_InitDone,

i_Nonsafe_InitDone:= PLC_PRG.o_InitDone,

S_i_SafetySignaturesValid:= S_ValidateConfigurations.o_SRDOSignaturesValid,

S_i_SafetyParametersValid:= S_ValidateConfigurations.o_ParametersValid,

S_o_SafeOperationEnable => G_StatusFlags_Safe.S_SafeOperationEnable);

 

G_CONSTANTS (GVL)

 

The limits used in hardware diagnostic initialization are defined in the G_CONSTANTS global variable list.

In MultiTool 6.3 or later, or MultiTool Creator it is possible to adjust some of the limits in MultiTool Creator's diagnostic tab. In previous versions, the constant values are hardcoded.

 

  1. Verify that the generated constant values are within range.

 

SC52 Safety Control UnitSC52 Safety Control Unit

The following constants are generated for the SC52 Safety Control Unit.

 

Constant

Unit

Default value

Min

Max

DIAG_TEMP_HIGH_LIMIT

°C

105

DIAG_TEMP_LOW_LIMIT

105

DIAG_TEMP_LOW_LIMIT

°C

-35

-35

DIAG_TEMP_HIGH_LIMIT

DIAG_TEMP_DELAY

ms

50

0

100

DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

mV

34000

DIAG_SUPPLY_VOLTAGE_LOW_LIMIT

34000

DIAG_SUPPLY_VOLTAGE_LOW_LIMIT

mV

9000

9000

DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

DIAG_SUPPLY_VOLTAGE_DELAY

ms

95

0

100

DIAG_OUTPUT_GROUP1_HIGH_LIMIT

mV

34000

DIAG_OUTPUT_GROUP1_LOW_LIMIT

34000

DIAG_OUTPUT_GROUP1_LOW_LIMIT

mV

9000

9000

 DIAG_OUTPUT_GROUP1_HIGH_LIMIT

DIAG_OUTPUT_GROUP1_DELAY

ms

95

0

100

DIAG_5V_VAN_HIGH_LIMIT

mV

5250

Not adjustable

Not adjustable

DIAG_5V_VAN_LOW_LIMIT

mV

4750

Not adjustable

Not adjustable

DIAG_5V_VAN_DELAY

ms

50

Not adjustable

Not adjustable

DIAG_5V_REF_DELAY

ms

50

0

100

DIAG_5V_REF_TOLERANCE

100

0

1000

 

 

SL84 Safety Control UnitSL84 Safety Control Unit

The following constants are generated for the SL84 Safety Control Unit.

 

Constant

Unit

Default value

Min

Max

DIAG_TEMP_HIGH_LIMIT

°C

105

DIAG_TEMP_LOW_LIMIT

105

DIAG_TEMP_LOW_LIMIT

°C

-35

-35

DIAG_TEMP_HIGH_LIMIT

DIAG_TEMP_DELAY

ms

50

0

100

DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

mV

34000

DIAG_SUPPLY_VOLTAGE_LOW_LIMIT

34000

DIAG_SUPPLY_VOLTAGE_LOW_LIMIT

mV

9000

9000

DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

DIAG_SUPPLY_VOLTAGE_DELAY

ms

95

0

100

DIAG_5V_REF_DELAY

ms

50

0

100

 

 

 

SL8X1-01 Control UnitSL8X1-01 Control Unit

The following constants are generated for the SL8X1-01 Control Unit.


Constant

Unit

Default value

Min

Max

DIAG_MCU_TEMP_HIGH_LIMIT

°C

125

DIAG_MCU_TEMP_LOW_LIMIT

125

DIAG_MCU_TEMP_LOW_LIMIT

°C

-40

-40

DIAG_MCU_TEMP_HIGH_LIMIT

DIAG_MCU_TEMP_DELAY

ms

50

0

100

DIAG_PCB1_TEMP_HIGH_LIMIT

°C

125

DIAG_PCB1_TEMP_LOW_LIMIT

125

DIAG_PCB1_TEMP_LOW_LIMIT

°C

-45

-45

DIAG_PCB1_TEMP_HIGH_LIMIT

DIAG_PCB1_TEMP_DELAY

ms

100

0

10000

DIAG_PCB2_TEMP_HIGH_LIMIT

°C

105

DIAG_PCB2_TEMP_LOW_LIMIT

105

DIAG_PCB2_TEMP_LOW_LIMIT

°C

-40

-40

DIAG_PCB2_TEMP_HIGH_LIMIT

DIAG_PCB2_TEMP_DELAY

ms

100

0

10000

DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

mV

32000

DIAG_SUPPLY_VOLTAGE_LOW_LIMIT

33000

DIAG_SUPPLY_VOLTAGE_LOW_LIMIT

mV

4500

0

DIAG_SUPPLY_VOLTAGE_HIGH_LIMIT

DIAG_SUPPLY_VOLTAGE_DELAY

ms

450

0

450

DIAG_OUTPUT_GROUP1_HIGH_LIMIT

mV

37000

DIAG_OUTPUT_GROUP1_LOW_LIMIT

37000

DIAG_OUTPUT_GROUP1_LOW_LIMIT

mV

4500

0

DIAG_OUTPUT_GROUP1_HIGH_LIMIT

DIAG_OUTPUT_GROUP1_DELAY

ms

100

0

100

DIAG_REF_5V_DELAY

ms

60

0

80

DIAG_REF_5V_CONTROL_CHANGE_DELAY

ms

500

0

3000

DIAG_REF_10V_DELAY

ms

60

0

80

DIAG_REF_10V_CONTROL_CHANGE_DELAY

ms

500

0

3000

DIAG_REF_5V_TOLERANCE

15

Not adjustable

Not adjustable

DIAG_REF_10V_TOLERANCE

30

Not adjustable

Not adjustable



 

See also

 

Source file topic100555.htm

Last updated 24-Apr-2025