6.8. Error simulation functions
6.8.1. esSetErrorAtSlavePort
-
EC_T_DWORD esSetErrorAtSlavePort(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_BYTE byPort, EC_T_BOOL bOutgoing)
Trigger loss of sent or received EtherCAT frames at slave port (“single shot”)
- Remark
See ESC registers RX Error Counter (0x0300:0x0307), Forwarded RX Error Counter (0x0308:0x030B), ECAT Processing Unit Error Counter (0x030C)
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address. 0: all slaves
byPort – [in] ESC port. 0, 1, 2, 3: port A, port B, port C, port D
bOutgoing – [in] Direction. EC_FALSE: Receive Frame, EC_TRUE: Send Frame
- Returns
EC_E_NOERROR or error code
6.8.2. esSetErrorGenerationAtSlavePort
-
EC_T_DWORD esSetErrorGenerationAtSlavePort(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_BYTE byPort, EC_T_BOOL bOutgoing, EC_T_DWORD dwLikelihoodPpm, EC_T_DWORD dwFixedGoodFramesCnt, EC_T_DWORD dwFixedErroneousFramesCnt)
Simulate the loss of sent EtherCAT frames at the port of a simulated slave at either random, periodic or random periodic intervalls.
Random frame loss simulation: For each frame the dwLikelihoodPpm parameter determines whether the frame will be discarded.
Periodic frame loss simulation: After dwFixedErroneousFramesCnt discarded frames, dwFixedGoodFramesCnt frames will be processed.
Random periodic frame loss simulation: The dwLikelihoodPpm parameter determines whether a periodic frame loss sequence is triggered.
- Remark
See ESC registers RX Error Counter (0x0300:0x0307), Forwarded RX Error Counter (0x0308:0x030B), ECAT Processing Unit Error Counter (0x030C)
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave station address. 0: All slaves
byPort – [in] ESC port. 0, 1, 2, 3: port A, port B, port C, port D
bOutgoing – [in] Direction. EC_FALSE: Receive Frame, EC_TRUE: Send Frame
dwLikelihoodPpm – [in] Likelihood (ppm) according to frame loss simulation mode (Random / Random Periodic). Set to 0 in case of Periodic frame loss simulation.
dwFixedGoodFramesCnt – [in] Number of processed frames according to frame loss simulation mode (Periodic / Random Periodic). Set to 0 in case of Random frame loss simulation.
dwFixedErroneousFramesCnt – [in] Number of discarded frames according to frame loss simulation mode (Periodic / Random Periodic). Set to 0 in case of Random frame loss simulation.
- Returns
EC_E_NOERROR or error code
6.8.3. esResetErrorGenerationAtSlavePorts
-
EC_T_DWORD esResetErrorGenerationAtSlavePorts(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress)
Reset physical layer error generation destroying frames at slave port.
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address. 0: all slaves
- Returns
EC_E_NOERROR or error code
6.8.4. esSetLinkDownAtSlavePort
-
EC_T_DWORD esSetLinkDownAtSlavePort(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_BYTE byPort, EC_T_BOOL bDown, EC_T_DWORD dwLinkDownTimeMs)
Trigger link lost event.
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address. 0: all slaves
byPort – [in] ESC port. 0, 1, 2, 3: port A, port B, port C, port D
bDown – [in] Connect or disconnect cable. EC_TRUE: disconnect
dwLinkDownTimeMs – [in] Link down duration in ms
- Returns
EC_E_NOERROR or error code
6.8.5. esSetLinkDownGenerationAtSlavePort
-
EC_T_DWORD esSetLinkDownGenerationAtSlavePort(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_BYTE byPort, EC_T_DWORD dwLikelihoodPpm, EC_T_DWORD dwFixedLinkDownTimeMs, EC_T_DWORD dwFixedLinkUpTimeMs)
Generate link lost events randomly or at fixed intervals.
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address. 0: all slaves
byPort – [in] ESC port. 0, 1, 2, 3: port A, port B, port C, port D
dwLikelihoodPpm – [in] Random simulation: link down likelihood (ppm) within OnTimer
dwFixedLinkDownTimeMs – [in] on link down simulation: fixed link down duration in ms (at least)
dwFixedLinkUpTimeMs – [in] after link down was simulated: fixed link up duration in ms (at least)
- Returns
EC_E_NOERROR or error code
6.8.6. esResetLinkDownGenerationAtSlavePorts
6.8.7. esLogFrameEnableAtSlavePort
-
EC_T_DWORD esLogFrameEnableAtSlavePort(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_BYTE byPort, EC_T_PFLOGFRAME_CB pvLogFrameCallBack, EC_T_VOID *pvContext)
Register EtherCAT network traffic logging function at given slave port.
Note
The simulator introduces frame errors if the callback function modifies the Ethernet frame type at byte offset 12.
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address. 0: all slaves
byPort – [in] ESC port. 0, 1, 2, 3: port A, port B, port C, port D
pvLogFrameCallBack – [in] Pointer to frame logging callback function
pvContext – [in] Pointer to context passed as first parameters to callback function
- Returns
EC_E_NOERROR or error code
6.8.8. esLogFrameDisableAtSlavePort
-
EC_T_DWORD esLogFrameDisableAtSlavePort(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_BYTE byPort)
Unregister EtherCAT network traffic logging function from given slave port.
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address. 0: all slaves
byPort – [in] ESC port. 0, 1, 2, 3: port A, port B, port C, port D
- Returns
EC_E_NOERROR or error code
6.8.9. esSendSlaveCoeEmergency
-
EC_T_DWORD esSendSlaveCoeEmergency(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_WORD wCode, EC_T_BYTE *pbyData, EC_T_DWORD dwDataLen)
Send CoE emergency (queued)
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address
wCode – [in] Emergency code
pbyData – [in] Emergency data
dwDataLen – [in] Length of emergency data in byte
- Returns
EC_E_NOERROR or error code
CoE Emergency Example
The following code demonstrates how to send a CoE Emergency from a local buffer to the Master.
/* send CoE Emergency */
EC_T_BYTE abyEmergencyData[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
dwRes = esSendSlaveCoeEmergency(dwSimulatorId, wSlaveAddress, 0x1234 /* code */, abyEmergencyData, 6 /* data length */);
if (dwRes != EC_E_NOERROR)
{
EcLogMsg(EC_LOG_LEVEL_ERROR, (pEcLogContext, EC_LOG_LEVEL_ERROR, "esSendSlaveCoeEmergency failed: %s (0x%lx))\n", esGetText(dwSimulatorId, dwRes), dwRes));
goto Exit;
}
6.8.10. esSetSimSlaveState
-
EC_T_DWORD esSetSimSlaveState(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress, EC_T_WORD wDeviceState, EC_T_WORD wDeviceStatusCode)
Simulate AL Status Error for slave without device emulation or acknowledge delayed EtherCAT state change.
- Parameters
dwInstanceId – [in] Simulator Instance ID
wCfgFixedAddress – [in] Slave’s station address
wDeviceState – [in] Device state (DEVICE_STATE_…)
wDeviceStatusCode – [in] Device status code (DEVICE_STATUSCODE_…)
- Returns
EC_E_NOERROR or error code
Simulate AL Status Error Example
The following code demonstrates how to simulate AL Status Errors for slaves without device emulation:
/* start and immediately stop AL Status Error simulation (single shot) */
dwRes = esSetSimSlaveState(dwSimulatorId, wSlaveAddr,
DEVICE_STATE_PREOP, DEVICE_STATUSCODE_ERROR);
if (dwRes != EC_E_NOERROR)
{
goto Exit;
}
dwRes = esSetSimSlaveState(dwSimulatorId, wSlaveAddr,
0, DEVICE_STATUSCODE_NOERROR);
if (dwRes != EC_E_NOERROR)
{
goto Exit;
}
Simulate AL Status Delay Example
The following code demonstrates how to simulate the EtherCAT state transition being delayed for some cycles by the slave application.
APPL_StartMailboxHandlerCallback_DelayALStatus()
starts the EtherCAT state transition delay and
APPL_ApplicationCallback_DelayALStatus()
stops the EtherCAT state transition delay:
/* AL Status delay timer */
static CEcTimer S_oAlStatusDelayTimer;
/* EC_PF_SSC_APPL_START_MAILBOX_HANDLER */
static EC_T_WORD EC_FNCALL APPL_StartMailboxHandlerCallback_DelayALStatus(
EC_T_VOID* pvContext,
EC_T_DWORD /* dwSimulatorId */,
EC_T_WORD /* wCfgFixedAddress */)
{
T_EC_DEMO_APP_CONTEXT* pAppContext = (T_EC_DEMO_APP_CONTEXT*)pvContext;
if (!S_oAlStatusDelayTimer.IsStarted())
{
EC_T_DWORD dwBusCycleTimeUsec = pAppContext->AppParms.dwBusCycleTimeUsec;
/* simulate slave state delay (e.g 3 cycles) */
S_oAlStatusDelayTimer.Start(EC_AT_LEAST(3 * dwBusCycleTimeUsec / 1000, 1));
}
/* return NOERROR_INWORK to delay the EtherCAT state transition */
return 0xFF; /* NOERROR_INWORK, see also esSetSimSlaveState(..., 0, DEVICE_STATUSCODE_NOERROR) */
}
/* EC_PF_SSC_APPL_APPLICATION */
static EC_T_VOID EC_FNCALL APPL_ApplicationCallback_DelayALStatus(
EC_T_VOID* /* pvContext */,
EC_T_DWORD dwInstanceId,
EC_T_WORD wCfgFixedAddress)
{
/* application ready */
if (S_oAlStatusDelayTimer.IsElapsed())
{
/* signal delayed EtherCAT state transition complete (see also NOERROR_INWORK) */
esSetSimSlaveState(dwInstanceId, wCfgFixedAddress, 0, DEVICE_STATUSCODE_NOERROR);
S_oAlStatusDelayTimer.Stop();
}
}
S_oAlStatusDelayTimer simulates the delay until the slave application is ready.
Note
If the delay is too long, the transition to PREOP will fail in EcSimulatorSilDemo due to InitCmd timeouts from the ENI file and checks within the SSC:
The callbacks must be registered using esSetSlaveSscApplication()
, e.g. in myAppPrepare()
of EcSimulatorHilDemo / EcSimulatorSilDemo:
struct _EC_T_SLAVE_SSC_APPL_DESC oSlaveAppDesc;
OsMemset(&oSlaveAppDesc, 0, sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC));
oSlaveAppDesc.dwSignature = SIMULATOR_SIGNATURE;
oSlaveAppDesc.dwSize = sizeof(struct _EC_T_SLAVE_SSC_APPL_DESC);
oSlaveAppDesc.szName = (EC_T_CHAR*)"mySlaveAppl";
oSlaveAppDesc.pvContext = pAppContext;
/* register callback APPL_Application, called after frame processing*/
oSlaveAppDesc.pfnApplication = APPL_ApplicationCallback_DelayALStatus;
/* register callback for master state transition request INIT to higher */
oSlaveAppDesc.pfnStartMailboxHandler = APPL_StartMailboxHandlerCallback_DelayALStatus;
/* register SlaveSscApplication callbacks (Master INIT) */
dwRes = esSetSlaveSscApplication(dwSimulatorId, wSlaveAddress, &oSlaveAppDesc);
if (dwRes != EC_E_NOERROR)
{
goto Exit;
}
dwRes = emSetMasterState(0, ETHERCAT_STATE_CHANGE_TIMEOUT, eEcatState_PREOP);