Supported platforms: CODESYS 3.5, CODESYS 3.5 SAFETY
These function blocks validate diverse SRDO message data to single safe type variable. Outdated or mismatching data is diagnosed.
The plain and binary-inverted input data are compared to match.
The timestamp input values are the CAN message reception time µs-values from firmware.
If the given Safety Cycle Time or Safety-Related Validation Time has passed, or the input data mismatch, the data is considered invalid.
Each supported variable type has a function block.
Function |
Data type of i_PlainMsgData and i_InvertMsgData |
Data type of S_o_Output |
S_ValidateSRDO_BYTE |
BYTE |
SAFEBYTE |
S_ValidateSRDO_WORD |
WORD |
SAFEWORD |
S_ValidateSRDO_DWORD |
DWORD |
SAFEDWORD |
S_ValidateSRDO_SINT |
SINT |
SAFESINT |
S_ValidateSRDO_INT |
INT |
SAFEINT |
S_ValidateSRDO_DINT |
DINT |
SAFEDINT |
S_ValidateSRDO_USINT |
USINT |
SAFEUSINT |
S_ValidateSRDO_UINT |
UINT |
SAFEUINT |
S_ValidateSRDO_UDINT |
UDINT |
SAFEUDINT |
Init method is used to initialize the necessary static calculation parameters for the function block instance.
The method shall be called at least once before the actual function block can be called, i.e. at the application initialization phase.
The method checks the validity of input parameters. However, none of the function block outputs are affected by the initialization.
|
A parameter error is diagnosed if: • Init method is not called before the main FB call OR • S_i_SRVTime = 0 OR • i_pEventCode = 0 OR • i_pTrigger = 0 OR • i_pInterlock = 0 OR • i_SRDOIndex out of range OR • i_VarIndex out of range
|
SRDO uses EventCode’s DeviceID as SRDO number and ChannelID as mapped variable index. The values are given as input parameters at initialization. Thus variable validation can use the same EventCode instance for SRDO as safety signature validation.
Parameter |
Type |
Unit |
Range |
Description |
S_i_SCTime |
SAFEUINT |
ms |
- |
Safeguard cycle time of the SRDO. |
S_i_SRVTime |
SAFEUSINT |
ms |
>0 |
SR validation time of the SRDO. |
i_SRDOIndex |
BYTE |
- |
1..64 |
SRDO index number to be added to EventCode as DeviceID. |
i_VarIndex |
BYTE |
- |
1..8 |
Index number of mapped variable in SRDO. To be added to EventCode as ChannelID. |
i_pEventCode |
POINTER TO EventCode |
- |
≠0 |
Pointer to application variable which is type EventCode. |
i_pTrigger |
POINTER TO BOOL |
- |
≠0 |
Pointer to boolean variable that triggers the validation procedure. |
i_pInterlock |
POINTER TO BOOL |
- |
≠0 |
SRDO interlock from CANopen |
TRUE: All initialization parameters ok. |
FALSE: Error in initialization parameter(s). |
CANopen library SRDO reception sets a global trigger status TRUE when inverted message is received.
When enabled (i.e. the system is operational), the function block waits for the trigger status to be TRUE (i_pTrigger) to start the validation procedure.
Validated i_PlainMsgData value is copied to S_o_Output if:
• The control is enabled, i.e. i_Enable is TRUE, AND
• New data is available, i.e. trigger is TRUE, AND
• No fault (including initialization) has been diagnosed
Successful reception of an SRDO variable is signaled by o_Status.OutputValid.
A safe application runs safe and non-safe tasks. Due to lower priority, the non-safe task may be interrupted at any time by the safe task.
If an interrupt occurs while the application is handling diverse non-safe SRDO data, the validation will fail.
The non-safe CANopenSRDO protocol handler keeps the global lock status TRUE (given in i_pInterlock parameter) while handling received message data. The validation function blocks use global lock status to disable safety cycle and SR validation timeout diagnostic.
The output S_o_Output is set to 0 and o_Status.SCTimeOut is set TRUE if:
• i_Enable is TRUE, and pointed trigger status has not been set for given safeguard cycle time S_i_SCTime OR
• Time between current and previous received message time i_InvertMsgTime is greater than given safeguard cycle time S_i_SCTime
The output S_o_Output is set to 0 and o_Status.SRVTimeOut is set TRUE if:
• i_InvertMsgTime - i_PlainMsgTime > S_i_SRVTime (time between messages in pair too long) OR
• i_InvertMsgTime - i_PlainMsgTime < 0 (messages received in inconsistent order)
The output S_o_Output is set to 0 and o_Status.DataMismatch is set TRUE if:
• Any i_InvertMsgData bit = i_PlainMsgData bit
All function block statuses, including errors are reset on rising edge of i_Enable.
|
SRDO protocol is supported in CANopen library version 4.0.0.0 or newer. |
|
SRDO message's refresh time (tx interval) shall be greater than 2x safety task's cycle time for SRDO to work properly with interlock functionality. |
Input variable name |
Data type |
Unit |
Range |
Description |
i_Enable |
BOOL |
- |
- |
Enable POU operation |
i_PlainMsgData |
<type> |
- |
- |
Plain SRDO message data |
i_PlainMsgTime |
UDINT |
µs |
- |
Plain SRDO message time |
i_InvertMsgData |
<type> |
- |
- |
Invert SRDO message data |
i_InvertMsgTime |
UDINT |
µs |
- |
Invert SRDO message time |
Output variable name |
Data type |
Range |
Description |
S_o_Output |
<type> |
- |
Validated variable value |
o_Status |
- |
Status of output value |
See Diagnostic Interface library description of error status and event code functionality.
Conditions |
S_o_Output value |
o_Status. OutputValid |
o_Status error status |
Event code FunctionID |
Event code EventID |
i_Enable TRUE AND init parameter error AND i_pEventCode valid |
0 |
FALSE |
ParameterError |
VALIDATE_SRDO |
PARAMETER_ERROR |
i_Enable TRUE AND init parameter error AND |
0 |
FALSE |
ParameterError |
- |
- |
i_Enable rises AND init parameters ok AND data not validated |
0 |
FALSE |
- |
NO_FUNC |
NO_ERROR |
i_Enable TRUE AND parameters ok AND data validated AND plain data match inverted data |
the last validated plain message data |
TRUE |
- |
NO_FUNC |
NO_ERROR |
i_Enable TRUE AND parameters ok AND plain data mismatch inverted data |
0 |
FALSE |
ValueMismatch |
VALIDATE_SRDO |
DATA_MISMATCH |
i_Enable TRUE AND parameters ok AND plain data match inverted data AND i_pInterlock^ TRUE AND |
the last validated plain message data |
TRUE |
- |
NO_FUNC |
NO_ERROR |
i_Enable TRUE AND parameters ok AND plain data match inverted data AND i_pInterlock^ FALSE AND |
0 |
FALSE |
SRVTimeout |
VALIDATE_SRDO |
SRV_TIMEOUT |
i_Enable TRUE AND parameters ok AND plain data match inverted data AND i_pInterlock^ TRUE AND |
the last validated plain message data |
TRUE |
- |
NO_FUNC |
NO_ERROR |
i_Enable TRUE AND parameters ok AND plain data match inverted data AND i_pInterlock^ FALSE AND |
0 |
FALSE |
SCTimeout |
VALIDATE_SRDO |
SC_TIMEOUT |
i_Enable TRUE AND parameters ok AND plain data match inverted data AND |
0 |
FALSE |
SCTimeout |
VALIDATE_SRDO |
SC_TIMEOUT |
|
SRDO related POUs are automatically generated to code template when MultiTool is used.
|
Definitions: |
|
(*NOTE! This object is created by Epec MultiTool Creator*)
/// SRDO variables /// Plain SRDO variables rdw1 AT %MD4: DWORD := DWORD#16#0; rdw2 AT %MD5: DWORD := DWORD#16#0; /// Inverted SRDO variables rdw1_i AT %MD6: DWORD := DWORD#16#0; rdw2_i AT %MD7: DWORD := DWORD#16#0; /// Plain SRDO variable timestamps rdw1_TIME: UDINT := UDINT#0; rdw2_TIME: UDINT := UDINT#0; /// Inverted SRDO variable timestamps rdw1_i_TIME: UDINT := UDINT#0; rdw2_i_TIME: UDINT := UDINT#0;
/// SRDO variable mappings SRDO2Mappings: ARRAY [1..G_CANOPEN_NUMBER_OF_LAST_SRDO_MAP*2] OF DWORD := [ DWORD#16#5FD60320, (* rdw1 *) DWORD#16#5FD50320, (* rdw1_i *) DWORD#16#5FD60420, (* rdw2 *) DWORD#16#5FD50420, (* rdw2_i *) 12(DWORD#16#0)]; (* 16 - 4 = 12 *)
/// CANopen common Device: EPEC_CANopen.Device; Protocols: ARRAY[1..6] OF EPEC_CANopen.ProtocolEntry; ProtocolAdded: ARRAY[1..6] OF BOOL := [6(0)];
/// SRDO SRDO: EPEC_CANopen.SRDOData; (* Protocol data *) SRDOS: ARRAY[1..2] OF EPEC_CANopen.CANopenSRDO; (* SRDO instances *) SRDO_Handler: EPEC_CANopen.CANopenSRDOHandler; (* Protocol handler *) SRDO_Error: EPEC_CANopen.Errors := EPEC_CANopen.Errors.NotInitialized; SRDO_Triggers: ARRAY[1..2] OF BOOL; SRDO_Signatures: ARRAY[1..2] OF WORD; SRDO_EventCodes: ARRAY[1..2] OF EPEC_DITF.EventCode; SRDO_Interlock: ARRAY[1..2] OF BOOL;
|
Init:
(*NOTE! This object is created by Epec MultiTool Creator*)
|
|
(*Define SRDO protocol*) Protocols[6].Protocol:=EPEC_CANopen.ProtocolType.SRDO; Protocols[6].pData:=ADR(SRDO); Protocols[6].itfProtocol:=SRDO_Handler; Protocols[6].pError:=ADR(SRDO_Error); ProtocolAdded[6] := CANopenDeviceAddProtocol( (* Add to protocol stack *) i_pDevice:=ADR(Device), i_pProtocol:=ADR(Protocols[6]) ); IF ProtocolAdded[6] THEN SRDO_Handler.Init( i_pDevice := ADR(.Device) ); ELSE SRDO_Error := EPEC_CANopen.Errors.ProtocolDataMissing; END_IF
(* Init SRDOs *) SRDOS[2].i_pTimings[1]:= ADR(rdw1_TIME); (*rdw1 *) SRDOS[2].i_pTimings[2]:= ADR(rdw1_i_TIME); (*rdw1_i *) SRDOS[2].i_pTimings[3]:= ADR(rdw2_TIME); (*rdw2 *) SRDOS[2].i_pTimings[4]:= ADR(rdw2_i_TIME); (*rdw2_i *) SRDOS[2].Init( i_pDevice := ADR(Device), i_SRDONumber := 2, i_SRDOType := EPEC_CANopen.SRDOType.ReceiveSRDO, i_SCTime := UINT#50, (* RSRDO Safeguard Cycle Time (ms) *) i_SRVTime := USINT#20, (* Validation time (rx) (ms) *) i_COB_ID1 := DWORD#16#103, (* Plain message COB-ID *) i_COB_ID2 := DWORD#16#104, (* Inverted message COB-ID *) i_Mapping := G_CANopen_CAN1_Mappings.SRDO2Mappings, (* Plain + Inverted data mappings *) i_Mappings := 4, (* Plain + Inverted data mappings *) i_pTriggerValidation := ADR(SRDO_Triggers[2]), (* Trigger status *) i_pInterlock := ADR(SRDO_Interlock[2]), o_Error => SRDO_Error );
|
Code: |
|
(*NOTE! This object is created by Epec MultiTool Creator*)
// Update protocol data G_CANopen_CAN1.SRDO_Handler.Update( i_Enable := TRUE, (*Enable condition is set by MultiTool Creator code template*) o_Error => SRDO_Error ); |
|
|
Definitions: |
(*NOTE! This object is created by Epec MultiTool Creator*)
PROGRAM S_Validate_SRDOs_CAN1 VAR_INPUT i_Enable: BOOL := FALSE; i_Initialize:BOOL:=TRUE; END_VAR VAR_OUTPUT /// Safe variables received over SRDO S_o_rdw1: SAFEDWORD := DWORD#0; S_o_rdw2: SAFEDWORD := DWORD#0; /// SRDO validation FB statuses o_SRDO_2_Valid: BOOL;
END_VAR VAR /// SRDO validation FB instances S_Validate_rdw1: EPEC_SRDO.S_ValidateSRDO_DWORD; S_Validate_rdw2: EPEC_SRDO.S_ValidateSRDO_DWORD;
Status_rdw1: EPEC_SRDO.Status; Status_rdw2: EPEC_SRDO.Status;
END_VAR
|
Init: |
(*NOTE! This object is created by Epec MultiTool Creator*)
// SRDO 1 data rxSRDO_Ok := S_Validate_rw1.Init( S_i_SCTime := SRDOS[2].i_SCTime, (* Safeguard cycle time *) S_i_SRVTime := SRDOS[2].i_SRVTime, (* SR Validation time *) i_SRDOIndex := BYTE#2, (* SRDO number -> EventCode.DeviceID *) i_VarIndex := BYTE#1, (* variable number -> EventCode.ChannelID *) i_pEventCode := ADR(SRDO_EventCodes[2]), (* Event code pointer for FB *) i_pTrigger := ADR(SRDO_Triggers[2]), (* Trigger status *) i_pInterlock := ADR(SRDO_Interlock[2]) ); rxSRDO_Ok := rxSRDO_Ok AND S_Validate_rw2.Init( S_i_SCTime := SRDOS[2].i_SCTime, (* Safeguard cycle time *) S_i_SRVTime := SRDOS[2].i_SRVTime, (* SR Validation time *) i_SRDOIndex := BYTE#2, (* SRDO number -> EventCode.DeviceID *) i_VarIndex := BYTE#2, (* variable number -> EventCode.ChannelID *) i_pEventCode := ADR(SRDO_EventCodes[2]), (* Event code pointer for FB *) i_pTrigger := ADR(SRDO_Triggers[2]), (* Trigger status *) i_pInterlock := ADR(SRDO_Interlock[2]) );
|
|
Application must reset SRDO message trigger after validation. |
Code: |
(*NOTE! This object is created by Epec MultiTool Creator*)
// SRDO 1 data (* Validate RX SRDO data *) S_Validate_rdw1( i_Enable := i_Enable, i_PlainMsgData := rdw1, i_InvertMsgData := rdw1_i, i_PlainMsgTime := rdw1_TIME, i_InvertMsgTime := rdw1_i_TIME, o_Status => Status_rdw1, S_o_Output => S_o_rdw1 ); S_Validate_rdw2( i_Enable := i_Enable, i_PlainMsgData := rdw2, i_InvertMsgData := rdw2_i, i_PlainMsgTime := rdw2_TIME, i_InvertMsgTime := rdw2_i_TIME, o_Status => Status_rdw2, S_o_Output => S_o_rdw2 );
SRDO_Triggers[2]:=FALSE; // reset SRDO message trigger
o_SRDO_2_Valid := Status_rdw1.OutputValid AND Status_rdw2.OutputValid;
|