Esempio n. 1
0
INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay (void FAR* pAddr_p, tTimeOfDay FAR* pTimeOfDay_p)
{

    AmiSetDwordToLe (((BYTE FAR*) pAddr_p),     pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
    AmiSetWordToLe  (((BYTE FAR*) pAddr_p) + 4, pTimeOfDay_p->m_wDays);

}
static tEplKernel EplPdokPdoEncode(tEplFrame* pFrame_p, unsigned int uiFrameSize_p, BOOL fReadyFlag_p)
{
    tEplKernel          Ret = kEplSuccessful;
    BYTE                bFlag1;
    unsigned int        uiNodeId;
    tEplMsgType         MsgType;
    tEplPdoChannel*     pPdoChannel;
    unsigned int        uiChannelId;
    tEplPdoMappObject*  pMappObject;
    unsigned int        uiMappObjectCount;

    // set TPDO invalid, so that only fully processed TPDOs are sent as valid
    bFlag1 = AmiGetByteFromLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1);
    AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1, (bFlag1 & ~EPL_FRAME_FLAG1_RD));

    // retrieve EPL message type
    MsgType = AmiGetByteFromLe(&pFrame_p->m_le_bMessageType);
    if (MsgType == kEplMsgTypePres)
    {   // TPDO is PRes frame
        uiNodeId = EPL_PDO_PRES_NODE_ID;  // 0x00
    }
    else
    {   // TPDO is PReq frame
        // retrieve node ID
        uiNodeId = AmiGetByteFromLe(&pFrame_p->m_le_bDstNodeId);
    }

    // search for appropriate valid TPDO
    for (uiChannelId = 0, pPdoChannel = &EplPdokInstance_g.m_pTxPdoChannel[0];
            uiChannelId < EplPdokInstance_g.m_Allocation.m_uiTxPdoChannelCount;
            uiChannelId++, pPdoChannel++)
    {
        if (pPdoChannel->m_uiNodeId != uiNodeId)
        {
            continue;
        }

        // valid TPDO found

        if ((unsigned int)(pPdoChannel->m_wPdoSize + 24) > uiFrameSize_p)
        {   // TPDO is too short
            // $$$ raise PDO error, set Ret
            break;
        }

        // set PDO version in frame
        AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bPdoVersion, pPdoChannel->m_bMappingVersion);

        // call data copy callback function right before TPDO access
        if ((EplPdokInstance_g.m_pfnCbTpdoPreCopy != NULL) && (pPdoChannel->m_uiMappObjectCount != 0))
        {
            EplPdokInstance_g.m_pfnCbTpdoPreCopy((BYTE) uiChannelId);
        }

        // process mapping
        for (uiMappObjectCount = pPdoChannel->m_uiMappObjectCount, pMappObject = EplPdokInstance_g.m_paTxObject[uiChannelId];
                uiMappObjectCount > 0;
                uiMappObjectCount--, pMappObject++)
        {

            BENCHMARK_MOD_08_TOGGLE(7);
            // copy object from process/OD variable to TPDO
            Ret = EplPdokCopyVarToPdo(&pFrame_p->m_Data.m_Pres.m_le_abPayload[0], pMappObject);
            if (Ret != kEplSuccessful)
            {   // other fatal error occurred
                goto Exit;
            }

        }

        // set PDO size in frame
        AmiSetWordToLe(&pFrame_p->m_Data.m_Pres.m_le_wSize, pPdoChannel->m_wPdoSize);

        if (fReadyFlag_p != FALSE)
        {
            // set TPDO valid
            AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1, (bFlag1 | EPL_FRAME_FLAG1_RD));
        }

        // processing finished successfully
        goto Exit;
    }

    // set PDO size in frame to zero, because no TPDO mapped
    AmiSetWordToLe(&pFrame_p->m_Data.m_Pres.m_le_wSize, 0);

    if (fReadyFlag_p != FALSE)
    {
        // set TPDO valid even if TPDO size is 0
        AmiSetByteToLe(&pFrame_p->m_Data.m_Pres.m_le_bFlag1, (bFlag1 | EPL_FRAME_FLAG1_RD));
    }

Exit:
    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;

}