//------------------------------------------------------------------------------ static tOplkError cbCnLossOfSync(void) { tOplkError ret = kErrorOk; tNmtState nmtState; UINT32 arg; TGT_DLLK_DECLARE_FLAGS; TGT_DLLK_ENTER_CRITICAL_SECTION(); nmtState = dllkInstance_g.nmtState; if (nmtState <= kNmtGsResetConfiguration) goto Exit; ret = dllkstatemachine_changeState(kNmtEventDllCeFrameTimeout, nmtState); if (ret != kErrorOk) goto Exit; Exit: if (ret != kErrorOk) { BENCHMARK_MOD_02_TOGGLE(7); arg = dllkInstance_g.dllState | (kNmtEventDllCeFrameTimeout << 8); // Error event for API layer ret = eventk_postError(kEventSourceDllk, ret, sizeof(arg), &arg); } TGT_DLLK_LEAVE_CRITICAL_SECTION(); return ret; }
//------------------------------------------------------------------------------ static tOplkError handleCnLossPreq(tEvent* pEvent_p) { tOplkError ret; tEventDllError* pErrorHandlerEvent = (tEventDllError*)pEvent_p->pEventArg; UINT32 threshold, thresholdCnt, cumulativeCnt; // check if loss of PReq event occurred if ((pErrorHandlerEvent->dllErrorEvents & DLL_ERR_CN_LOSS_PREQ) == 0) return kErrorOk; errhndkcal_getCnLossPreqError(&cumulativeCnt, &thresholdCnt, &threshold); cumulativeCnt++; // According to spec threshold counting is disabled by setting threshold to 0 if (threshold > 0) { thresholdCnt += 8; if (thresholdCnt >= threshold) { ret = generateHistoryEntry(E_DLL_LOSS_PREQ_TH, pEvent_p->netTime); if (ret != kErrorOk) { errhndkcal_setCnLossPreqCounters(cumulativeCnt, thresholdCnt); return ret; } BENCHMARK_MOD_02_TOGGLE(7); postNmtEvent(kNmtEventNmtCycleError); } } errhndkcal_setCnLossPreqCounters(cumulativeCnt, thresholdCnt); return kErrorOk; }
//------------------------------------------------------------------------------ static tOplkError cbCnPresFallbackTimeout(void) { tOplkError ret = kErrorOk; tNmtState nmtState; UINT32 arg; TGT_DLLK_DECLARE_FLAGS; TGT_DLLK_ENTER_CRITICAL_SECTION(); nmtState = dllkInstance_g.nmtState; if (nmtState <= kNmtGsResetConfiguration) goto Exit; ret = dllkframe_presChainingDisable(); Exit: if (ret != kErrorOk) { BENCHMARK_MOD_02_TOGGLE(7); arg = dllkInstance_g.dllState | (kNmtEventDllCeFrameTimeout << 8); // Error event for API layer ret = eventk_postError(kEventSourceDllk, ret, sizeof(arg), &arg); } TGT_DLLK_LEAVE_CRITICAL_SECTION(); return ret; }
//------------------------------------------------------------------------------ static tOplkError handleInvalidFormat(tEvent* pEvent_p) { tOplkError ret; tEventDllError* pErrorHandlerEvent = (tEventDllError*)pEvent_p->pEventArg; // check if invalid format error occurred (only direct reaction) if ((pErrorHandlerEvent->dllErrorEvents & DLL_ERR_INVALID_FORMAT) == 0) return kErrorOk; ret = generateHistoryEntryNodeId(E_DLL_INVALID_FORMAT, pEvent_p->netTime, pErrorHandlerEvent->nodeId); if (ret != kErrorOk) return ret; BENCHMARK_MOD_02_TOGGLE(7); #ifdef CONFIG_INCLUDE_NMT_MN if (NMT_IF_ACTIVE_MN(pErrorHandlerEvent->nmtState)) { // MN is active if (pErrorHandlerEvent->nodeId != 0) { tDllNodeOpParam NodeOpParam; NodeOpParam.opNodeType = kDllNodeOpTypeIsochronous; NodeOpParam.nodeId = pErrorHandlerEvent->nodeId; // remove node from isochronous phase dllk_deleteNode(&NodeOpParam); // inform NmtMnu module about state change, which shall send // NMT command ResetNode to this CN postHeartbeatEvent(pErrorHandlerEvent->nodeId, kNmtCsNotActive, E_DLL_INVALID_FORMAT); } // $$$ and else should lead to InternComError } else { postNmtEvent(kNmtEventInternComError); } #else // CN is active postNmtEvent(kNmtEventInternComError); #endif return kErrorOk; }
//------------------------------------------------------------------------------ tOplkError dllk_cbTimerSwitchOver(tTimerEventArg* pEventArg_p) { tOplkError ret = kErrorOk; tNmtState nmtState; UINT32 arg; tNmtEvent nmtEvent; tEvent event; TGT_DLLK_DECLARE_FLAGS; TGT_DLLK_ENTER_CRITICAL_SECTION(); #if CONFIG_TIMER_USE_HIGHRES != FALSE if (pEventArg_p->timerHdl != dllkInstance_g.timerHdlSwitchOver) { // zombie callback - just exit goto Exit; } #endif nmtState = dllkInstance_g.nmtState; if (!NMT_IF_ACTIVE_CN(nmtState)) goto Exit; ret = edrv_sendTxBuffer(&dllkInstance_g.pTxBuffer[DLLK_TXFRAME_AMNI]); if (ret != kErrorOk) goto Exit; // increment relativeTime for missing SoC dllkInstance_g.relativeTime += dllkInstance_g.dllConfigParam.cycleLen; nmtEvent = kNmtEventDllReSwitchOverTimeout; event.eventSink = kEventSinkNmtk; event.eventType = kEventTypeNmtEvent; event.eventArgSize = sizeof(nmtEvent); event.pEventArg = &nmtEvent; ret = eventk_postEvent(&event); Exit: if (ret != kErrorOk) { BENCHMARK_MOD_02_TOGGLE(7); arg = dllkInstance_g.dllState | (kNmtEventDllReSwitchOverTimeout << 8); // Error event for API layer ret = eventk_postError(kEventSourceDllk, ret, sizeof(arg), &arg); } TGT_DLLK_LEAVE_CRITICAL_SECTION(); return ret; }
//------------------------------------------------------------------------------ static tOplkError cbMnSyncHandler(void) { tOplkError ret = kErrorOk; tNmtState nmtState; BYTE* pbCnNodeId; UINT32 arg; TGT_DLLK_DECLARE_FLAGS; TGT_DLLK_ENTER_CRITICAL_SECTION(); nmtState = dllkInstance_g.nmtState; if (nmtState <= kNmtGsResetConfiguration) goto Exit; // do cycle finish which has to be done inside the callback function triggered by interrupt pbCnNodeId = &dllkInstance_g.aCnNodeIdList[dllkInstance_g.curTxBufferOffsetCycle][dllkInstance_g.curNodeIndex]; while (*pbCnNodeId != C_ADR_INVALID) { // issue error for each CN in list which was not processed yet, i.e. PRes received ret = dllknode_issueLossOfPres(*pbCnNodeId); if (ret != kErrorOk) goto Exit; pbCnNodeId++; } dllkInstance_g.fSyncProcessed = FALSE; dllkInstance_g.fPrcSlotFinished = FALSE; // switch to next cycle dllkInstance_g.curTxBufferOffsetCycle ^= 1; dllkInstance_g.curNodeIndex = 0; ret = dllk_postEvent(kEventTypeDllkCycleFinish); Exit: if (ret != kErrorOk) { BENCHMARK_MOD_02_TOGGLE(7); arg = dllkInstance_g.dllState | (kNmtEventDllMeSocTrig << 8); // Error event for API layer ret = eventk_postError(kEventSourceDllk, ret, sizeof(arg), &arg); } TGT_DLLK_LEAVE_CRITICAL_SECTION(); return ret; }
//--------------------------------------------------------------------------- // // Function: EplErrorHandlerkProcess // // Description: processes error events from DLL // // Parameters: pEvent_p = pointer to event-structure from buffer // // Returns: tEpKernel = errorcode // // State: // //--------------------------------------------------------------------------- tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent* pEvent_p) { tEplKernel Ret; unsigned long ulDllErrorEvents; tEplEvent Event; tEplNmtEvent NmtEvent; Ret = kEplSuccessful; // check m_EventType switch(pEvent_p->m_EventType) { case kEplEventTypeDllError: { tEplErrorHandlerkEvent* pErrHandlerEvent = (tEplErrorHandlerkEvent*)pEvent_p->m_pArg; tEplErrHistoryEntry HistoryEntry = {0}; ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents; HistoryEntry.m_wEntryType = EPL_ERR_ENTRYTYPE_MODE_OCCURRED | EPL_ERR_ENTRYTYPE_PROF_EPL | EPL_ERR_ENTRYTYPE_HISTORY; // check the several error events if ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0) { // loss of SoC event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_LOSS_SOC_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_LOSS_SOC_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0) { // loss of PReq event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_LOSS_PREQ_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_LOSS_PREQ_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } } } if ((EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt > 0) && ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0)) { // PReq correctly received // decrement threshold counter by 1 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt--; } if ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0) { // CRC error event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_CRC_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_CRC_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_CRC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0) { // invalid format error occured (only direct reaction) // generate error history entry E_DLL_INVALID_FORMAT HistoryEntry.m_wErrorCode = EPL_E_DLL_INVALID_FORMAT; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetByteToLe(&HistoryEntry.m_abAddInfo[0], (BYTE) pErrHandlerEvent->m_uiNodeId); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } BENCHMARK_MOD_02_TOGGLE(7); #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive) { // MN is active if (pErrHandlerEvent->m_uiNodeId != 0) { tEplHeartbeatEvent HeartbeatEvent; tEplDllNodeOpParam NodeOpParam; NodeOpParam.m_OpNodeType = kEplDllNodeOpTypeIsochronous; NodeOpParam.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; // remove node from isochronous phase Ret = EplDllkDeleteNode(&NodeOpParam); // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; HeartbeatEvent.m_NmtState = kEplNmtCsNotActive; HeartbeatEvent.m_wErrorCode = EPL_E_DLL_INVALID_FORMAT; Event.m_EventSink = kEplEventSinkNmtMnu; Event.m_EventType = kEplEventTypeHeartbeat; Event.m_uiSize = sizeof (HeartbeatEvent); Event.m_pArg = &HeartbeatEvent; Ret = EplEventkPost(&Event); } // $$$ and else should lead to InternComError } else #endif { // CN is active // post event to NMT state machine NmtEvent = kEplNmtEventInternComError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } } #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0) { // CRC error event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_CRC_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_CRC_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CRC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0) { // cycle time exceeded event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold) { // threshold is reached // generate error history entry E_DLL_CYCLE_EXCEED_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_CYCLE_EXCEED_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetWordToLe(&HistoryEntry.m_abAddInfo[0], (WORD) pErrHandlerEvent->m_EplError); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } else { // generate error history entry E_DLL_CYCLE_EXCEED HistoryEntry.m_wErrorCode = EPL_E_DLL_CYCLE_EXCEED; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetWordToLe(&HistoryEntry.m_abAddInfo[0], (WORD) pErrHandlerEvent->m_EplError); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CYCTIMEEXCEED; } } if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0) { // CN loss PRes event occured unsigned int uiNodeId; uiNodeId = pErrHandlerEvent->m_uiNodeId - 1; if (uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt)) { if (EplErrorHandlerkInstance_g.m_abMnCnLossPresEvent[uiNodeId] == EPL_ERRORHANDLERK_CN_LOSS_PRES_EVENT_NONE) { // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt[uiNodeId]++; if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId] > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] += 8; if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] >= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId]) { // threshold is reached tEplHeartbeatEvent HeartbeatEvent; tEplDllNodeOpParam NodeOpParam; EplErrorHandlerkInstance_g.m_abMnCnLossPresEvent[uiNodeId] = EPL_ERRORHANDLERK_CN_LOSS_PRES_EVENT_THR; NodeOpParam.m_OpNodeType = kEplDllNodeOpTypeIsochronous; NodeOpParam.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; // generate error history entry E_DLL_LOSS_PRES_TH HistoryEntry.m_wErrorCode = EPL_E_DLL_LOSS_PRES_TH; HistoryEntry.m_TimeStamp = pEvent_p->m_NetTime; AmiSetByteToLe(&HistoryEntry.m_abAddInfo[0], (BYTE) pErrHandlerEvent->m_uiNodeId); Ret = EplErrorHandlerkPostHistoryEntry(&HistoryEntry); if (Ret != kEplSuccessful) { goto Exit; } // remove node from isochronous phase Ret = EplDllkDeleteNode(&NodeOpParam); // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; HeartbeatEvent.m_NmtState = kEplNmtCsNotActive; HeartbeatEvent.m_wErrorCode = EPL_E_DLL_LOSS_PRES_TH; Event.m_EventSink = kEplEventSinkNmtMnu; Event.m_EventType = kEplEventTypeHeartbeat; Event.m_uiSize = sizeof (HeartbeatEvent); Event.m_pArg = &HeartbeatEvent; Ret = EplEventkPost(&Event); } else { EplErrorHandlerkInstance_g.m_abMnCnLossPresEvent[uiNodeId] = EPL_ERRORHANDLERK_CN_LOSS_PRES_EVENT_OCC; } } } } } #endif break; } // unknown type default: { Ret = kEplInvalidEvent; break; } } // end of switch(pEvent_p->m_EventType) Exit: return Ret; }
//------------------------------------------------------------------------------ tOplkError dllk_cbCyclicError(tOplkError errorCode_p, tEdrvTxBuffer* pTxBuffer_p) { tOplkError ret = kErrorOk; tNmtState nmtState; UINT handle = 0; UINT32 arg; tEventDllError dllEvent; TGT_DLLK_DECLARE_FLAGS; UNUSED_PARAMETER(pTxBuffer_p); TGT_DLLK_ENTER_CRITICAL_SECTION(); nmtState = dllkInstance_g.nmtState; if (!NMT_IF_MN(nmtState)) { #if defined(CONFIG_INCLUDE_NMT_RMN) if (errorCode_p == kErrorEdrvCurTxListEmpty) { switch (dllkInstance_g.nmtEventGoToStandby) { case kNmtEventGoToStandby: hrestimer_modifyTimer(&dllkInstance_g.timerHdlSwitchOver, (dllkInstance_g.dllConfigParam.switchOverTimeMn - dllkInstance_g.dllConfigParam.cycleLen) * 1000ULL, dllk_cbTimerSwitchOver, 0L, FALSE); dllkInstance_g.nmtEventGoToStandby = kNmtEventNoEvent; break; case kNmtEventGoToStandbyDelayed: hrestimer_modifyTimer(&dllkInstance_g.timerHdlSwitchOver, (dllkInstance_g.dllConfigParam.delayedSwitchOverTimeMn - dllkInstance_g.dllConfigParam.cycleLen) * 1000ULL, dllk_cbTimerSwitchOver, 0L, FALSE); dllkInstance_g.nmtEventGoToStandby = kNmtEventNoEvent; break; default: break; } } #endif // ignore errors if not MN goto Exit; } if (pTxBuffer_p != NULL) { handle = (UINT)(pTxBuffer_p - dllkInstance_g.pTxBuffer); } BENCHMARK_MOD_02_TOGGLE(7); switch (errorCode_p) { case kErrorEdrvCurTxListEmpty: case kErrorEdrvTxListNotFinishedYet: case kErrorEdrvNoFreeTxDesc: dllEvent.dllErrorEvents = DLL_ERR_MN_CYCTIMEEXCEED; dllEvent.nodeId = handle; dllEvent.nmtState = nmtState; dllEvent.oplkError = errorCode_p; ret = errhndk_postError(&dllEvent); break; default: arg = dllkInstance_g.dllState | (handle << 16); // Error event for API layer ret = eventk_postError(kEventSourceDllk, errorCode_p, sizeof(arg), &arg); break; } Exit: TGT_DLLK_LEAVE_CRITICAL_SECTION(); return ret; }
//--------------------------------------------------------------------------- // // Function: EplErrorHandlerkProcess // // Description: processes error events from DLL // // // // Parameters: pEvent_p = pointer to event-structur from buffer // // // Returns: tEpKernel = errorcode // // // State: // //--------------------------------------------------------------------------- tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent* pEvent_p) { tEplKernel Ret; unsigned long ulDllErrorEvents; tEplEvent Event; tEplNmtEvent NmtEvent; Ret = kEplSuccessful; // check m_EventType switch(pEvent_p->m_EventType) { case kEplEventTypeDllError: { tEplErrorHandlerkEvent* pErrHandlerEvent = (tEplErrorHandlerkEvent*)pEvent_p->m_pArg; ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents; // check the several error events if ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0) { // loss of SoC event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold) { // threshold is reached // $$$ d.k.: generate error history entry E_DLL_LOSS_SOC_TH BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0) { // loss of PReq event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold) { // threshold is reached // $$$ d.k.: generate error history entry E_DLL_LOSS_PREQ_TH BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } } } if ((EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt > 0) && ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0)) { // PReq correctly received // decrement threshold counter by 1 EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt--; } if ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0) { // CRC error event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold) { // threshold is reached // $$$ d.k.: generate error history entry E_DLL_CRC_TH BENCHMARK_MOD_02_TOGGLE(7); // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_CRC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0) { // invalid format error occured (only direct reaction) // $$$ d.k.: generate error history entry E_DLL_INVALID_FORMAT BENCHMARK_MOD_02_TOGGLE(7); #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive) { // MN is active if (pErrHandlerEvent->m_uiNodeId != 0) { tEplHeartbeatEvent HeartbeatEvent; tEplDllNodeOpParam NodeOpParam; NodeOpParam.m_OpNodeType = kEplDllNodeOpTypeIsochronous; NodeOpParam.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; // remove node from isochronous phase Ret = EplDllkDeleteNode(&NodeOpParam); // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; HeartbeatEvent.m_NmtState = kEplNmtCsNotActive; HeartbeatEvent.m_wErrorCode = EPL_E_DLL_INVALID_FORMAT; Event.m_EventSink = kEplEventSinkNmtMnu; Event.m_EventType = kEplEventTypeHeartbeat; Event.m_uiSize = sizeof (HeartbeatEvent); Event.m_pArg = &HeartbeatEvent; Ret = EplEventkPost(&Event); } // $$$ and else should lead to InternComError } else #endif { // CN is active // post event to NMT state machine NmtEvent = kEplNmtEventInternComError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } } #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0) { // CRC error event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold) { // threshold is reached // $$$ d.k.: generate error history entry E_DLL_CRC_TH // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CRC; } } if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0) { // cycle time exceeded event occured // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwCumulativeCnt++; if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt += 8; if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold) { // threshold is reached // $$$ d.k.: generate error history entry E_DLL_CYCLE_EXCEED_TH // post event to NMT state machine NmtEvent = kEplNmtEventNmtCycleError; Event.m_EventSink = kEplEventSinkNmtk; Event.m_EventType = kEplEventTypeNmtEvent; Event.m_pArg = &NmtEvent; Event.m_uiSize = sizeof (NmtEvent); Ret = EplEventkPost(&Event); } // $$$ d.k.: else generate error history entry E_DLL_CYCLE_EXCEED EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CYCTIMEEXCEED; } } if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0) { // CN loss PRes event occured unsigned int uiNodeId; uiNodeId = pErrHandlerEvent->m_uiNodeId - 1; if (uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt)) { // increment cumulative counter by 1 EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt[uiNodeId]++; if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId] > 0) { // increment threshold counter by 8 EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] += 8; if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] >= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId]) { // threshold is reached tEplHeartbeatEvent HeartbeatEvent; tEplDllNodeOpParam NodeOpParam; NodeOpParam.m_OpNodeType = kEplDllNodeOpTypeIsochronous; NodeOpParam.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; // $$$ d.k.: generate error history entry E_DLL_LOSS_PRES_TH // remove node from isochronous phase Ret = EplDllkDeleteNode(&NodeOpParam); // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId; HeartbeatEvent.m_NmtState = kEplNmtCsNotActive; HeartbeatEvent.m_wErrorCode = EPL_E_DLL_LOSS_PRES_TH; Event.m_EventSink = kEplEventSinkNmtMnu; Event.m_EventType = kEplEventTypeHeartbeat; Event.m_uiSize = sizeof (HeartbeatEvent); Event.m_pArg = &HeartbeatEvent; Ret = EplEventkPost(&Event); } EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] = TRUE; } } } #endif break; } // NMT event case kEplEventTypeNmtEvent: { if ((*(tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllCeSoa) { // SoA event of CN -> decrement threshold counters if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) == 0) { // decrement loss of SoC threshold counter, because it didn't occur last cycle if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt > 0) { EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt--; } } if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) == 0) { // decrement CRC threshold counter, because it didn't occur last cycle if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt > 0) { EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt--; } } } #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) else if ((*(tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent) { // SoA event of MN -> decrement threshold counters tEplDllkNodeInfo* pIntNodeInfo; unsigned int uiNodeId; Ret = EplDllkGetFirstNodeInfo(&pIntNodeInfo); if (Ret != kEplSuccessful) { break; } // iterate through node info structure list while (pIntNodeInfo != NULL) { uiNodeId = pIntNodeInfo->m_uiNodeId - 1; if (uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt)) { if (EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] == FALSE) { if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] > 0) { EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId]--; } } else { EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] = FALSE; } } pIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo; } if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) == 0) { // decrement CRC threshold counter, because it didn't occur last cycle if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt > 0) { EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt--; } } if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) == 0) { // decrement cycle exceed threshold counter, because it didn't occur last cycle if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt > 0) { EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt--; } } } #endif // reset error events EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0L; break; } // unknown type default: { Ret = kEplInvalidEvent; break; } } // end of switch(pEvent_p->m_EventType) return Ret; }