# Error simulation functions ## esSetErrorAtSlavePort ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetErrorAtSlavePort([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byPort, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bOutgoing) Trigger loss of sent or received EtherCAT frames at slave port (“single shot”). \_ * **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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esSetErrorGenerationAtSlavePort ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetErrorGenerationAtSlavePort([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byPort, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bOutgoing, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwLikelihoodPpm, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwFixedGoodFramesCnt, [EC_T_DWORD](api.html.md#_CPPv410EC_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. \_ * **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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esResetErrorGenerationAtSlavePorts ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esResetErrorGenerationAtSlavePorts([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esSetLinkDownAtSlavePort ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetLinkDownAtSlavePort([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byPort, [EC_T_BOOL](api.html.md#_CPPv49EC_T_BOOL) bDown, [EC_T_DWORD](api.html.md#_CPPv410EC_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 [ms] or EC_WAITINFINITE * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esSetLinkDownGenerationAtSlavePort ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetLinkDownGenerationAtSlavePort([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) byPort, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwLikelihoodPpm, [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwFixedLinkDownTimeMs, [EC_T_DWORD](api.html.md#_CPPv410EC_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 [ms] (at least) * **dwFixedLinkUpTimeMs** – [in] After link down was simulated: fixed link up duration [ms] (at least) * **Returns:** [EC_E_NOERROR](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esResetLinkDownGenerationAtSlavePorts ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esResetLinkDownGenerationAtSlavePorts([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esLogFrameEnableAtSlavePort ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esLogFrameEnableAtSlavePort([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_BYTE](api.html.md#_CPPv49EC_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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esLogFrameDisableAtSlavePort ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esLogFrameDisableAtSlavePort([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_BYTE](api.html.md#_CPPv49EC_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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ## esSendSlaveCoeEmergency ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSendSlaveCoeEmergency([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCode, [EC_T_BYTE](api.html.md#_CPPv49EC_T_BYTE) \*pbyData, [EC_T_DWORD](api.html.md#_CPPv410EC_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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ### **CoE Emergency Example** The following code demonstrates how to send a CoE Emergency from a local buffer to the MainDevice. ```cpp /* 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; } ``` ## esSetSimSlaveState ### [EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) esSetSimSlaveState([EC_T_DWORD](api.html.md#_CPPv410EC_T_DWORD) dwInstanceId, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wCfgFixedAddress, [EC_T_WORD](api.html.md#_CPPv49EC_T_WORD) wDeviceState, [EC_T_WORD](api.html.md#_CPPv49EC_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](error-codes_generic.html.md#d3/d2f/group___e_c___e_r_r_o_r___c_o_d_e_s___g_e_n_e_r_i_c_1ga8c8419c32e88e73d940a4501fe427116) or error code ### **Simulate AL Status Error Example** The following code demonstrates how to simulate AL Status Errors for SubDevices without network adapter emulation: ```cpp /* 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 SubDevice application. `APPL_StartMailboxHandlerCallback_DelayALStatus()` starts the EtherCAT® state transition delay and `APPL_ApplicationCallback_DelayALStatus()` stops the EtherCAT® state transition delay: ```cpp /* 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 dwBusCycleTimeMsec = pAppContext->AppParms.dwBusCycleTimeNsec / 1000000; /* simulate slave state delay (e.g 3 cycles) */ S_oAlStatusDelayTimer.Start(EC_AT_LEAST(3 * dwBusCycleTimeMsec, 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 SubDevice 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()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC), e.g. in `myAppPrepare()` of EcSimulatorHilDemo / EcSimulatorSilDemo: ```cpp 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; } ``` ```cpp dwRes = emSetMasterState(0, ETHERCAT_STATE_CHANGE_TIMEOUT, eEcatState_PREOP); ``` #### SEE ALSO - [`esSetSlaveSscApplication()`](api_general.html.md#_CPPv424esSetSlaveSscApplication10EC_T_DWORD9EC_T_WORDP24EC_T_SLAVE_SSC_APPL_DESC): [`EC_T_SLAVE_SSC_APPL_DESC::pfnAckErrorInd`](api_general.html.md#_CPPv4N24EC_T_SLAVE_SSC_APPL_DESC14pfnAckErrorIndE)