//--------------------------------------------------------------------------- // // Function: EplNmtkProcess // // Description: main process function // -> process NMT-State-Maschine und read NMT-Events from Queue // // // // Parameters: EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instance pointer // pEvent_p = Epl-Event with NMT-event to process // // // Returns: tEplKernel = Errorcode // // // State: // //--------------------------------------------------------------------------- EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent * pEvent_p) { tEplKernel Ret; tEplNmtState OldNmtState; tEplNmtEvent NmtEvent; tEplEvent Event; tEplEventNmtStateChange NmtStateChange; // check for all API function if instance is valid EPL_MCO_CHECK_INSTANCE_STATE(); Ret = kEplSuccessful; switch (pEvent_p->m_EventType) { case kEplEventTypeNmtEvent: { NmtEvent = *((tEplNmtEvent *) pEvent_p->m_pArg); break; } case kEplEventTypeTimer: { NmtEvent = (tEplNmtEvent) ((tEplTimerEventArg *) pEvent_p-> m_pArg)->m_ulArg; break; } default: { Ret = kEplNmtInvalidEvent; goto Exit; } } // save NMT-State // needed for later comparison to // inform hgher layer about state change OldNmtState = EPL_MCO_GLB_VAR(m_NmtState); // NMT-State-Maschine switch (EPL_MCO_GLB_VAR(m_NmtState)) { //----------------------------------------------------------- // general part of the statemaschine // first init of the hardware case kEplNmtGsOff: { // leave this state only if higher layer says so if (NmtEvent == kEplNmtEventSwReset) { // new state kEplNmtGsInitialising EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; } break; } // first init of the hardware case kEplNmtGsInitialising: { // leave this state only if higher layer says so // check events switch (NmtEvent) { // 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // new state kEplNmtGsResetApplication case kEplNmtEventEnterResetApp: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } default: { break; } } break; } // init of the manufacturer-specific profile area and the // standardised device profile area case kEplNmtGsResetApplication: { // check events switch (NmtEvent) { // 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // leave this state only if higher layer // say so case kEplNmtEventEnterResetCom: { // new state kEplNmtGsResetCommunication EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } default: { break; } } break; } // init of the communication profile area case kEplNmtGsResetCommunication: { // check events switch (NmtEvent) { // 2006/07/31 d.k.: react also on NMT reset commands in ResetComm state // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // leave this state only if higher layer // say so case kEplNmtEventEnterResetConfig: { // new state kEplNmtGsResetCommunication EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } default: { break; } } break; } // build the configuration with infos from OD case kEplNmtGsResetConfiguration: { // reset flags EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE; EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE; EPL_MCO_GLB_VAR(m_fFrozen) = FALSE; // check events switch (NmtEvent) { // 2006/07/31 d.k.: react also on NMT reset commands in ResetConf state // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication case kEplNmtEventResetCom: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // leave this state only if higher layer says so case kEplNmtEventEnterCsNotActive: { // Node should be CN EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsNotActive; break; } case kEplNmtEventEnterMsNotActive: { // Node should be CN #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) // no MN functionality // TODO: -create error E_NMT_BA1_NO_MN_SUPPORT EPL_MCO_GLB_VAR(m_fFrozen) = TRUE; #else EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsNotActive; #endif break; } default: { break; } } break; } //----------------------------------------------------------- // CN part of the statemaschine // node liste for EPL-Frames and check timeout case kEplNmtCsNotActive: { // check events switch (NmtEvent) { // 2006/07/31 d.k.: react also on NMT reset commands in NotActive state // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; // Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; // Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; // Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); break; } // NMT Command Reset Configuration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; // Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); break; } // see if SoA or SoC received // k.t. 20.07.2006: only SoA forces change of state // see EPL V2 DS 1.0.0 p.267 // case kEplNmtEventDllCeSoc: case kEplNmtEventDllCeSoa: { // new state PRE_OPERATIONAL1 EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; // Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); break; } // timeout for SoA and Soc case kEplNmtEventTimerBasicEthernet: { // new state BASIC_ETHERNET EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsBasicEthernet; break; } default: { break; } } // end of switch(NmtEvent) break; } // node processes only async frames case kEplNmtCsPreOperational1: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command Reset Configuration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // NMT Command StopNode case kEplNmtEventStopNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped; break; } // check if SoC received case kEplNmtEventDllCeSoc: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational2; break; } default: { break; } } // end of switch(NmtEvent) break; } // node processes isochronous and asynchronous frames case kEplNmtCsPreOperational2: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command Reset Configuration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // NMT Command StopNode case kEplNmtEventStopNode: { // reset flags EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE; EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE; EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped; break; } // error occured case kEplNmtEventNmtCycleError: { // reset flags EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE; EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE; EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } // check if application is ready to operate case kEplNmtEventEnterReadyToOperate: { // check if command NMTEnableReadyToOperate from MN was received if (EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) == TRUE) { // reset flags EPL_MCO_GLB_VAR (m_fEnableReadyToOperate) = FALSE; EPL_MCO_GLB_VAR (m_fAppReadyToOperate) = FALSE; // change state EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsReadyToOperate; } else { // set Flag EPL_MCO_GLB_VAR (m_fAppReadyToOperate) = TRUE; } break; } // NMT Commando EnableReadyToOperate case kEplNmtEventEnableReadyToOperate: { // check if application is ready if (EPL_MCO_GLB_VAR(m_fAppReadyToOperate) == TRUE) { // reset flags EPL_MCO_GLB_VAR (m_fEnableReadyToOperate) = FALSE; EPL_MCO_GLB_VAR (m_fAppReadyToOperate) = FALSE; // change state EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsReadyToOperate; } else { // set Flag EPL_MCO_GLB_VAR (m_fEnableReadyToOperate) = TRUE; } break; } default: { break; } } // end of switch(NmtEvent) break; } // node should be configured und application is ready case kEplNmtCsReadyToOperate: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // NMT Command StopNode case kEplNmtEventStopNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped; break; } // error occured case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } // NMT Command StartNode case kEplNmtEventStartNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsOperational; break; } default: { break; } } // end of switch(NmtEvent) break; } // normal work state case kEplNmtCsOperational: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // NMT Command StopNode case kEplNmtEventStopNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped; break; } // NMT Command EnterPreOperational2 case kEplNmtEventEnterPreOperational2: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational2; break; } // error occured case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } default: { break; } } // end of switch(NmtEvent) break; } // node stopped by MN // -> only process asynchronous frames case kEplNmtCsStopped: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // NMT Command EnterPreOperational2 case kEplNmtEventEnterPreOperational2: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational2; break; } // error occured case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } default: { break; } } // end of switch(NmtEvent) break; } // no epl cycle // -> normal ethernet communication case kEplNmtCsBasicEthernet: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // error occured // d.k.: how does this error occur? on CRC errors /* case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } */ case kEplNmtEventDllCeSoc: case kEplNmtEventDllCePreq: case kEplNmtEventDllCePres: case kEplNmtEventDllCeSoa: { // Epl-Frame on net -> stop any communication EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } default: { break; } } // end of switch(NmtEvent) break; } //----------------------------------------------------------- // MN part of the statemaschine // MN listen to network // -> if no EPL traffic go to next state case kEplNmtMsNotActive: { #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) // no MN functionality // TODO: -create error E_NMT_BA1_NO_MN_SUPPORT EPL_MCO_GLB_VAR(m_fFrozen) = TRUE; #else // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // EPL frames received case kEplNmtEventDllCeSoc: case kEplNmtEventDllCeSoa: { // other MN in network // $$$ d.k.: generate error history entry EPL_MCO_GLB_VAR(m_fFrozen) = TRUE; break; } // timeout event case kEplNmtEventTimerBasicEthernet: { if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) { // new state BasicEthernet EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsBasicEthernet; } break; } // timeout event case kEplNmtEventTimerMsPreOp1: { if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) { // new state PreOp1 EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1; EPL_MCO_GLB_VAR (m_fTimerMsPreOp2) = FALSE; EPL_MCO_GLB_VAR (m_fAllMandatoryCNIdent) = FALSE; } break; } default: { break; } } // end of switch(NmtEvent) #endif // ((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) break; } #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) // MN process reduces epl cycle case kEplNmtMsPreOperational1: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // EPL frames received case kEplNmtEventDllCeSoc: case kEplNmtEventDllCeSoa: { // other MN in network // $$$ d.k.: generate error history entry EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // error occured // d.k. MSPreOp1->CSPreOp1: nonsense -> keep state /* case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } */ case kEplNmtEventAllMandatoryCNIdent: { // all mandatory CN identified if (EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) != FALSE) { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational2; } else { EPL_MCO_GLB_VAR (m_fAllMandatoryCNIdent) = TRUE; } break; } case kEplNmtEventTimerMsPreOp2: { // residence time for PreOp1 is elapsed if (EPL_MCO_GLB_VAR (m_fAllMandatoryCNIdent) != FALSE) { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational2; } else { EPL_MCO_GLB_VAR (m_fTimerMsPreOp2) = TRUE; } break; } default: { break; } } // end of switch(NmtEvent) break; } // MN process full epl cycle case kEplNmtMsPreOperational2: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // EPL frames received case kEplNmtEventDllCeSoc: case kEplNmtEventDllCeSoa: { // other MN in network // $$$ d.k.: generate error history entry EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // error occured case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1; break; } case kEplNmtEventEnterReadyToOperate: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsReadyToOperate; break; } default: { break; } } // end of switch(NmtEvent) break; } // all madatory nodes ready to operate // -> MN process full epl cycle case kEplNmtMsReadyToOperate: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // EPL frames received case kEplNmtEventDllCeSoc: case kEplNmtEventDllCeSoa: { // other MN in network // $$$ d.k.: generate error history entry EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // error occured case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1; break; } case kEplNmtEventEnterMsOperational: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsOperational; break; } default: { break; } } // end of switch(NmtEvent) break; } // normal eplcycle processing case kEplNmtMsOperational: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // EPL frames received case kEplNmtEventDllCeSoc: case kEplNmtEventDllCeSoa: { // other MN in network // $$$ d.k.: generate error history entry EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // error occured case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1; break; } default: { break; } } // end of switch(NmtEvent) break; } // normal ethernet traffic case kEplNmtMsBasicEthernet: { // check events switch (NmtEvent) { // NMT Command SwitchOff case kEplNmtEventCriticalError: case kEplNmtEventSwitchOff: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; break; } // NMT Command SwReset case kEplNmtEventSwReset: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; break; } // NMT Command ResetNode case kEplNmtEventResetNode: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; break; } // NMT Command ResetCommunication // or internal Communication error case kEplNmtEventResetCom: case kEplNmtEventInternComError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // NMT Command ResetConfiguration case kEplNmtEventResetConfig: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration; break; } // EPL frames received case kEplNmtEventDllCeSoc: case kEplNmtEventDllCeSoa: { // other MN in network // $$$ d.k.: generate error history entry EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication; break; } // error occured // d.k. BE->PreOp1 on cycle error? No /* case kEplNmtEventNmtCycleError: { EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; break; } */ default: { break; } } // end of switch(NmtEvent) break; } #endif //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) default: { //DEBUG_EPL_DBGLVL_NMTK_TRACE0(EPL_DBGLVL_NMT ,"Error in EplNmtProcess: Unknown NMT-State"); //EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; Ret = kEplNmtInvalidState; goto Exit; } } // end of switch(NmtEvent) // inform higher layer about State-Change if needed if (OldNmtState != EPL_MCO_GLB_VAR(m_NmtState)) { EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent, OldNmtState, EPL_MCO_GLB_VAR(m_NmtState)); // d.k.: memorize NMT state before posting any events NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState); // inform DLL if ((OldNmtState > kEplNmtGsResetConfiguration) && (EPL_MCO_GLB_VAR(m_NmtState) <= kEplNmtGsResetConfiguration)) { // send DLL DEINIT Event.m_EventSink = kEplEventSinkDllk; Event.m_EventType = kEplEventTypeDllkDestroy; EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); Event.m_pArg = &OldNmtState; Event.m_uiSize = sizeof(OldNmtState); // d.k.: directly call DLLk process function, because // 1. execution of process function is still synchonized and serialized, // 2. it is the same as without event queues (i.e. well tested), // 3. DLLk will get those necessary events even if event queue is full, // 4. event queue is very inefficient #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplDllkProcess(&Event); #else Ret = EplEventkPost(&Event); #endif } else if ((OldNmtState <= kEplNmtGsResetConfiguration) && (EPL_MCO_GLB_VAR(m_NmtState) > kEplNmtGsResetConfiguration)) { // send DLL INIT Event.m_EventSink = kEplEventSinkDllk; Event.m_EventType = kEplEventTypeDllkCreate; EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); Event.m_pArg = &NmtStateChange.m_NewNmtState; Event.m_uiSize = sizeof(NmtStateChange.m_NewNmtState); // d.k.: directly call DLLk process function, because // 1. execution of process function is still synchonized and serialized, // 2. it is the same as without event queues (i.e. well tested), // 3. DLLk will get those necessary events even if event queue is full // 4. event queue is very inefficient #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplDllkProcess(&Event); #else Ret = EplEventkPost(&Event); #endif } else if ((EPL_MCO_GLB_VAR(m_NmtState) == kEplNmtCsBasicEthernet) || (EPL_MCO_GLB_VAR(m_NmtState) == kEplNmtMsBasicEthernet)) { tEplDllAsyncReqPriority AsyncReqPriority; // send DLL Fill Async Tx Buffer, because state BasicEthernet was entered Event.m_EventSink = kEplEventSinkDllk; Event.m_EventType = kEplEventTypeDllkFillTx; EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); AsyncReqPriority = kEplDllAsyncReqPrioGeneric; Event.m_pArg = &AsyncReqPriority; Event.m_uiSize = sizeof(AsyncReqPriority); // d.k.: directly call DLLk process function, because // 1. execution of process function is still synchonized and serialized, // 2. it is the same as without event queues (i.e. well tested), // 3. DLLk will get those necessary events even if event queue is full // 4. event queue is very inefficient #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplDllkProcess(&Event); #else Ret = EplEventkPost(&Event); #endif } // inform higher layer about state change NmtStateChange.m_NmtEvent = NmtEvent; Event.m_EventSink = kEplEventSinkNmtu; Event.m_EventType = kEplEventTypeNmtStateChange; EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); Event.m_pArg = &NmtStateChange; Event.m_uiSize = sizeof(NmtStateChange); Ret = EplEventkPost(&Event); EPL_DBGLVL_NMTK_TRACE2 ("EplNmtkProcess(NMT-Event = 0x%04X): New NMT-State = 0x%03X\n", NmtEvent, NmtStateChange.m_NewNmtState); } Exit: return Ret; }
tEplKernel PUBLIC EplEventkProcess(tEplEvent* pEvent_p) { tEplKernel Ret; tEplEventSource EventSource; Ret = kEplSuccessful; #if (EPL_USE_SHAREDBUFF != FALSE) \ && (EPL_EVENT_USE_KERNEL_QUEUE != FALSE) // error handling if event queue is full if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0) { // UserToKernel event queue has run out of space -> kEplNmtEventInternComError #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) tEplEvent Event; tEplNmtEvent NmtEvent; #endif // directly call NMTk process function, because event queue is full #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) NmtEvent = kEplNmtEventInternComError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_NetTime.m_dwNanoSec = 0; Event.m_NetTime.m_dwSec = 0; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof(NmtEvent); Ret = EplNmtkProcess(&Event); #endif // NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION) // now, it is safe to reset the counter and empty the event queue ShbCirResetBuffer (EplEventkInstance_g.m_pShbUserToKernelInstance, 1000, NULL); EplEventkInstance_g.m_uiUserToKernelFullCount = 0; TGT_DBG_SIGNAL_TRACE_POINT(22); // also discard the current event (it doesn't matter if we lose another event) goto Exit; } #endif // check m_EventSink switch(pEvent_p->m_EventSink) { // NMT-Kernel-Modul case kEplEventSinkNmtk: { #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) Ret = EplNmtkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceNmtk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif BENCHMARK_MOD_27_RESET(0); #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent) && (*((tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllCeSoa)) { BENCHMARK_MOD_27_SET(0); #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) // forward SoA event to DLLk module for cycle preprocessing Ret = EplDllkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceDllk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif BENCHMARK_MOD_27_RESET(0); } #endif break; } // events for Dllk module case kEplEventSinkDllk: { #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplDllkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceDllk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif break; } // events for DllkCal module case kEplEventSinkDllkCal: { #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplDllkCalProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceDllk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif break; } #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) // events for PDO CAL module case kEplEventSinkPdokCal: { Ret = EplPdokCalProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourcePdok; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } break; } #endif #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) // events for Error handler module case kEplEventSinkErrk: { // only call error handler if DLL is present Ret = EplErrorHandlerkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceErrk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } break; } #endif // unknown sink default: { Ret = kEplEventUnknownSink; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(pEvent_p->m_EventSink), &pEvent_p->m_EventSink); } } // end of switch(pEvent_p->m_EventSink) #if (EPL_USE_SHAREDBUFF != FALSE) \ && (EPL_EVENT_USE_KERNEL_QUEUE != FALSE) Exit: #endif return Ret; }
tEplKernel EplEventkProcess(tEplEvent *pEvent_p) { tEplKernel Ret; tEplEventSource EventSource; Ret = kEplSuccessful; // error handling if event queue is full if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0) { // UserToKernel event queue has run out of space -> kEplNmtEventInternComError #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) tEplEvent Event; tEplNmtEvent NmtEvent; #endif #ifndef EPL_NO_FIFO tShbError ShbError; #endif // directly call NMTk process function, because event queue is full #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) NmtEvent = kEplNmtEventInternComError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_NetTime.m_dwNanoSec = 0; Event.m_NetTime.m_dwSec = 0; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof(NmtEvent); Ret = EplNmtkProcess(&Event); #endif // NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION) // now, it is safe to reset the counter and empty the event queue #ifndef EPL_NO_FIFO ShbError = ShbCirResetBuffer(EplEventkInstance_g. m_pShbUserToKernelInstance, 1000, NULL); #endif EplEventkInstance_g.m_uiUserToKernelFullCount = 0; TGT_DBG_SIGNAL_TRACE_POINT(22); // also discard the current event (it doesn't matter if we lose another event) goto Exit; } // check m_EventSink switch (pEvent_p->m_EventSink) { case kEplEventSinkSync: { if (EplEventkInstance_g.m_pfnCbSync != NULL) { Ret = EplEventkInstance_g.m_pfnCbSync(); if (Ret == kEplSuccessful) { #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) // mark TPDOs as valid Ret = EplPdokCalSetTpdosValid(TRUE); #endif } else if ((Ret != kEplReject) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceSyncCb; // Error event for API layer EplEventkPostError (kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } } break; } // NMT-Kernel-Modul case kEplEventSinkNmtk: { #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) Ret = EplNmtkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceNmtk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent) && ((*((tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllCeSoa) #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) || (*((tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent) #endif )) { // forward SoA event to error handler Ret = EplErrorHandlerkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceErrk; // Error event for API layer EplEventkPostError (kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) // forward SoA event to PDO module pEvent_p->m_EventType = kEplEventTypePdoSoa; Ret = EplPdokProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourcePdok; // Error event for API layer EplEventkPostError (kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif } break; #endif } // events for Dllk module case kEplEventSinkDllk: { #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplDllkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceDllk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif break; } // events for DllkCal module case kEplEventSinkDllkCal: { #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplDllkCalProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceDllk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif break; } // case kEplEventSinkPdok: { // PDO-Module #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) Ret = EplPdokProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourcePdok; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } #endif break; } // events for Error handler module case kEplEventSinkErrk: { // only call error handler if DLL is present #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) Ret = EplErrorHandlerkProcess(pEvent_p); if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { EventSource = kEplEventSourceErrk; // Error event for API layer EplEventkPostError(kEplEventSourceEventk, Ret, sizeof(EventSource), &EventSource); } break; #endif } // unknown sink default: { Ret = kEplEventUnknownSink; } } // end of switch(pEvent_p->m_EventSink) Exit: return Ret; }