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

EC_T_DWORD esResetLinkDownGenerationAtSlavePorts(EC_T_DWORD dwInstanceId, EC_T_WORD wCfgFixedAddress)

Reset link lost event generation.

Parameters
  • dwInstanceId – [in] Simulator Instance ID

  • wCfgFixedAddress – [in] Slave’s station address. 0: all slaves

Returns

EC_E_NOERROR or error code

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);