//***************************************************************************** // (C) Automotive Lighting Reutlingen GmbH // Tuebinger Strasse 123, 72762 Reutlingen, Germany // // Automotive Lighting Reutlingen GmbH owns all the rights to this work. // This work shall not be copied, reproduced, used, modified, transferred // or its information shall not be disclosed without the prior written // authorization of Automotive Lighting Reutlingen GmbH. //***************************************************************************** //----------------------------------------------------------------------------- /// \file SysMonRx.c /// /// \brief /// /// \descr /// //----------------------------------------------------------------------------- #include #include //#include "E2EPW_ctaaSysMon.h" //#include "E2E_Types.h" //============================================================================= // Start declaration or definitions of functions //============================================================================= #define ctaaSysMon_START_SEC_CODE #include "ctaaSysMon_MemMap.h" // -------------- Start function declarations or definitions. //-------------------------------------------------------------------------------------------------- /// \brief Private helper to initialize counter monitor /// \param pCntMon conter based monitor /// \param nLimitActivate error debouncing counter value /// \param nLimitDeActivate recovery debouncing counter value /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_initCounterMonitor(tSysMonCounterMonitor* const pCntMon, uint32 nLimitActivate, uint32 nLimitDeActivate) { pCntMon->cntActivate = nLimitActivate; //-- counter pCntMon->cntDeActivate = nLimitDeActivate; //-- counter pCntMon->isDebounced = FALSE; pCntMon->cnt = 0u; pCntMon->isActiveDtc = FALSE; } //-------------------------------------------------------------------------------------------------- /// \brief Private helper to initialize timer monitor /// \param pTimMon timer based monitor /// \param nToutActivateMsec errordebouncing timing value /// \param nToutDeActivateMsec recovery debouncing timing value /// \note Currently not in use. Originaly introduced because of unclear RTE interfaces as fallback /// solution. /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_initTimerMonitor(tSysMonTimerMonitor* const pTimMon, uint32 nToutActivateMsec, uint32 nToutDeActivateMsec) { pTimMon->toutActivate = nToutActivateMsec; //-- milliseconds pTimMon->toutDeActivate = nToutDeActivateMsec; //-- milliseconds pTimMon->isTimeout = FALSE; pTimMon->isActiveDtc = FALSE; } //-------------------------------------------------------------------------------------------------- /// \brief Private helper to initialize the quality of one signal /// \param pQuality quality of a signal /// \param nTcyclicMsec Cyclic time of the PDU /// \param nToutMsec Timeout value of PDU /// \note The timings are relevant fo cyclic based PDUs. /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_initSignalQuality(tSysMonSignalQuality* const pQuality, uint32 nTcyclicMsec, uint32 nToutMsec) { pQuality->state = eSysMonSigState_Init; //-- calculate values for counters for debouncing ----- uint32 nCntOn = SysMon_divAndRoundClosest(nToutMsec, nTcyclicMsec); uint32 nCntOff = nCntOn; SysMonRx_initCounterMonitor(&(pQuality->monitor), nCntOn, nCntOff); } //-------------------------------------------------------------------------------------------------- /// \brief Private helper to initialize the PDU quality /// \param pQuality quality of a PDU /// \param nTcyclicMsec Cyclic time of the PDU /// \param nToutMsec Timeout value of PDU /// \note The timings are relevant fo cyclic based PDUs. /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_initPduQuality(tSysMonPduQuality* const pQuality, uint32 nTcyclicMsec, uint32 nToutMsec) { //-- calculate values for counters for debouncing ----- uint32 nDTCon = SysMon_divAndRoundClosest(nToutMsec, nTcyclicMsec);//1;//SysMon_divAndRoundClosest(nToutMsec, nTcyclicMsec); The DTC is set after a timeout triged interrupt. It is not based on the cyclic PDUs periods. uint32 nDTCoff = SysMon_divAndRoundClosest(nToutMsec, nTcyclicMsec); //nDTCon; // Set the DTC to off after this specific number of successful PDUs received. uint32 nStateFail = nDTCon; uint32 nStatePass = nDTCoff; pQuality->state = eSysMonPduState_Init; SysMonRx_initCounterMonitor(&(pQuality->monitor.monitorAliveCounter.monitorFail), nStateFail, nStatePass); SysMonRx_initCounterMonitor(&(pQuality->monitor.monitorAliveCounter.monitorDTC), nDTCon, nDTCoff); SysMonRx_initCounterMonitor(&(pQuality->monitor.monitorCrc.monitorFail), nStateFail, nStatePass); SysMonRx_initCounterMonitor(&(pQuality->monitor.monitorCrc.monitorDTC), nDTCon, nDTCoff); SysMonRx_initCounterMonitor(&(pQuality->monitor.monitorRteTimeout.monitorFail), nStateFail, nStatePass); SysMonRx_initCounterMonitor(&(pQuality->monitor.monitorRteTimeout.monitorDTC), nDTCon, nDTCoff); SysMonRx_initTimerMonitor(&(pQuality->monitor.monitorSelfTimer), nToutMsec, nToutMsec); } //-- Signal Handler ----- //-------------------------------------------------------------------------------------------------- /// \brief Private helper to handle the quality of one signal when signal is valid /// \param pQuality quality of one signal /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_HandleSignalQualitySuccess(tSysMonSignalQuality* const pQuality) { //-- signal state becomes valid with first successfully received CAN PDU pQuality->state = eSysMonSigState_Valid; //-- Note: Even if signal is vaild, isDebounced might still be TRUE if (0U < pQuality->monitor.cnt) { pQuality->monitor.cnt -= 1U; } if (0U == pQuality->monitor.cnt) { pQuality->monitor.isDebounced = FALSE; //-- now DTC can be reset if this monitor is a DTC monitor } } //-------------------------------------------------------------------------------------------------- /// \brief Private helper to handle the quality of one signal when signal is invalid /// \param pQuality quality of one signal /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_HandleSignalQualityFail(tSysMonSignalQuality* const pQuality) { if (FALSE == pQuality->monitor.isDebounced) { if (pQuality->monitor.cnt < pQuality->monitor.cntActivate) { pQuality->monitor.cnt += 1U; } if (pQuality->monitor.cnt >= pQuality->monitor.cntActivate) { pQuality->monitor.isDebounced = TRUE; pQuality->state = eSysMonSigState_Invalid; pQuality->monitor.cnt = pQuality->monitor.cntDeActivate; } } else { if (pQuality->monitor.cnt < pQuality->monitor.cntDeActivate) { pQuality->monitor.cnt += 1U; } if (pQuality->monitor.cnt >= pQuality->monitor.cntActivate) { pQuality->state = eSysMonSigState_Invalid; } } if ((eSysMonSigState_Valid == pQuality->state) || (eSysMonSigState_Init == pQuality->state)) { pQuality->state = eSysMonSigState_PreInvalid; } } //-- Message Handler ----- //-------------------------------------------------------------------------------------------------- /// \brief Private helper to handle PDU quality when RTE read was succesfully /// \param pQuality PDU quality /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_HandlePduQualitySuccess(tSysMonPduQuality* const pQuality) { //pQuality->state = eSysMonPduState_Passed; SysMonRx_HandlePduQualityCounterMonitorSuccess(&(pQuality->monitor.monitorAliveCounter.monitorFail)); SysMonRx_HandlePduQualityCounterMonitorSuccess(&(pQuality->monitor.monitorAliveCounter.monitorDTC)); SysMonRx_HandlePduQualityCounterMonitorSuccess(&(pQuality->monitor.monitorCrc.monitorFail)); SysMonRx_HandlePduQualityCounterMonitorSuccess(&(pQuality->monitor.monitorCrc.monitorDTC)); SysMonRx_HandlePduQualityCounterMonitorSuccess(&(pQuality->monitor.monitorRteTimeout.monitorFail)); SysMonRx_HandlePduQualityCounterMonitorSuccess(&(pQuality->monitor.monitorRteTimeout.monitorDTC)); //todo timer SysMonRx_HandleMsgMgrTimerMonitorSuccess(&(pMsgMgr->monitor.monitorSelfTimer)); } //-------------------------------------------------------------------------------------------------- /// \brief Private helper to maintain debounce counter for various monitors when RTE read was successfully /// \param pCntMon one (of many) counter monitor of PDU handler /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_HandlePduQualityCounterMonitorSuccess(tSysMonCounterMonitor* const pCntMon) { if (0U < pCntMon->cnt) { pCntMon->cnt -= 1U; } if (0U == pCntMon->cnt) { pCntMon->isDebounced = FALSE; } } //-------------------------------------------------------------------------------------------------- /// \brief Private helper to maintain debounce counter for various monitors when RTE read failed /// \param pCntMon one (of many) counter monitor of PDU handler /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_HandlePduQualityCounterMonitorFail(tSysMonCounterMonitor* const pCntMon) { if (FALSE == pCntMon->isDebounced) { if (pCntMon->cnt < pCntMon->cntActivate) { pCntMon->cnt += 1U; } if (pCntMon->cnt >= pCntMon->cntActivate) { pCntMon->isDebounced = TRUE; pCntMon->cnt = pCntMon->cntDeActivate; } } else { if (pCntMon->cnt < pCntMon->cntDeActivate) { pCntMon->cnt += 1U; //-- safe } } } //-------------------------------------------------------------------------------------------------- /// \brief Private helper to maintain PDU state in case of E2E protected CAN PDU not read successfully /// \param pQuality quality of PDU /// \param eErrIndType interpreted error cause /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRx_HandlePduQualityFail(tSysMonPduQuality* const pQuality, SysMon_EnumErrorIndicationType eErrIndType) { switch (eErrIndType) { case eSysMonErrIndRteAliveCounter: SysMonRx_HandlePduQualityCounterMonitorFail(&(pQuality->monitor.monitorAliveCounter.monitorFail)); if (TRUE == pQuality->monitor.monitorAliveCounter.monitorFail.isDebounced) { pQuality->state = eSysMonPduState_Failed; } SysMonRx_HandlePduQualityCounterMonitorFail(&(pQuality->monitor.monitorAliveCounter.monitorDTC)); break; case eSysMonErrIndRteCrc: SysMonRx_HandlePduQualityCounterMonitorFail(&(pQuality->monitor.monitorCrc.monitorFail)); if (TRUE == pQuality->monitor.monitorCrc.monitorFail.isDebounced) { pQuality->state = eSysMonPduState_Failed; } SysMonRx_HandlePduQualityCounterMonitorFail(&(pQuality->monitor.monitorCrc.monitorDTC)); break; case eSysMonErrIndRteTimeout: SysMonRx_HandlePduQualityCounterMonitorFail(&(pQuality->monitor.monitorRteTimeout.monitorFail)); if (TRUE == pQuality->monitor.monitorRteTimeout.monitorFail.isDebounced) { pQuality->state = eSysMonPduState_Failed; } SysMonRx_HandlePduQualityCounterMonitorFail(&(pQuality->monitor.monitorRteTimeout.monitorDTC)); break; case eSysMonErrIndSelfTimeout: default: if (TRUE == pQuality->monitor.monitorSelfTimer.isTimeout) { pQuality->state = eSysMonPduState_Failed; } break; } if ((eSysMonPduState_Passed == pQuality->state) || (eSysMonPduState_Init == pQuality->state)) { pQuality->state = eSysMonPduState_PreFailed; } } //-------------------------------------------------------------------------------------------------- /// \brief Helper to encapsulate set and clear of a DTC /// \param pf funtion pointer to DTC handler /// \param pMon related monitor of PDU handler /// \param isPre variant of invoking DTC handler /// \return - //-------------------------------------------------------------------------------------------------- void SysMonRxHandleDTC_CounterMonitor(SYSMON_FUNC_PTR_DTC pf, tSysMonCounterMonitor* pMon, boolean isPre) { if ((NULL_PTR != pf) && (NULL_PTR != pMon)) //-- completely useless because both are NEVER EVER NULL. SysMon only works with static references. Pointerchecks are FORBIDDEN in AUTOSAR. { Dem_EventStatusType setEvent = 1U;//DEM_EVENT_STATUS_FAILED; Dem_EventStatusType clearEvent = 0U;// DEM_EVENT_STATUS_PASSED; if (TRUE == isPre) { setEvent = 3U;//DEM_EVENT_STATUS_PREFAILED; clearEvent = 2U;//DEM_EVENT_STATUS_PREPASSED; } if ((TRUE == pMon->isDebounced) && (FALSE == pMon->isActiveDtc)) { if (RTE_E_OK == (pf)(setEvent)) //-- set DTC { pMon->isActiveDtc = TRUE; } } else { if ((FALSE == pMon->isDebounced) && (TRUE == pMon->isActiveDtc)) { if (RTE_E_OK == (pf)(clearEvent)) //-- clear DTC { pMon->isActiveDtc = FALSE; } } } } } //-------------------------------------------------------------------------------------------------- /// \brief Helper to interpret E2E function return value /// \param E2E_ReadReturnVal /// \return SysMon error enum mapping RTE Read value to SUCCESS (eSysMonErrNone) or /// TIMEOUT error (eSysMonErrIndRteTimeout), CRC error (eSysMonErrIndRteCrc) or /// ALIVE COUNTER error (eSysMonErrIndRteAliveCounter) //-------------------------------------------------------------------------------------------------- SysMon_EnumErrorIndicationType SysMonRx_GetE2E_ErrorIndication(uint32 E2E_ReadReturnVal) { uint32 StatusByte0 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 0U) & ((uint32)0x000000FFU)); uint32 StatusByte1 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 8U) & ((uint32)0x000000FFU)); uint32 StatusByte2 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 16U) & ((uint32)0x000000FFU)); uint32 StatusByte3 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 24U) & ((uint32)0x000000FFU)); SysMon_EnumErrorIndicationType retVal = eSysMonErrIndRteTimeout; if ((((uint32)RTE_E_OK == StatusByte0) && ((uint32)RTE_E_OK == StatusByte1) && ((uint32)RTE_E_OK == StatusByte2)) && ((uint32)RTE_E_OK == StatusByte3) || ((uint32)RTE_E_OK == StatusByte3)) { retVal = eSysMonErrNone; //-- success } else { if ( ((uint32)RTE_E_MAX_AGE_EXCEEDED == StatusByte0) || ((uint32)RTE_E_UNCONNECTED == StatusByte0) || ((uint32)RTE_E_NEVER_RECEIVED == StatusByte0) || ((uint32)RTE_E_LOST_DATA == StatusByte0)) { retVal = eSysMonErrIndRteTimeout; //-- TIMEOUT } else if (((uint32)RTE_E_INVALID == StatusByte2) || ((uint32)RTE_E_INVALID == StatusByte2) || ((uint32)RTE_E_INVALID == StatusByte3) || ((uint32)RTE_E_INVALID == StatusByte3) || ((uint32)RTE_E_INVALID == StatusByte3) || ((uint32)RTE_E_INVALID == StatusByte3) || ((uint32)RTE_E_INVALID == StatusByte3)) { retVal = eSysMonErrIndRteAliveCounter; //-- ALIVE COUNTER } else if ((uint32)RTE_E_INVALID == StatusByte3) { retVal = eSysMonErrIndRteCrc; //-- CRC } } #ifdef UNIT_TEST extern val; retVal = change_value(val); //retVal = 0; #endif // UNIT_TEST return retVal; } //-------------------------------------------------------------------------------------------------- /// \brief Helper to interpret E2E function return value /// \param E2E_ReadReturnVal /// \return SysMon error enum mapping RTE Read value to SUCCESS (eSysMonErrNone) or /// TIMEOUT error (eSysMonErrIndRteTimeout), CRC error (eSysMonErrIndRteCrc) or /// ALIVE COUNTER error (eSysMonErrIndRteAliveCounter) //-------------------------------------------------------------------------------------------------- SysMon_EnumErrorIndicationType SysMonRx_GetE2E_internalErrorIndication(uint32 E2E_ReadReturnVal, uint8* maxCounter) { uint32 StatusByte0 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 0u) & ((uint32)0x000000FFU)); uint32 StatusByte1 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 8U) & ((uint32)0x000000FFU)); uint32 StatusByte2 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 16U) & ((uint32)0x000000FFU)); uint32 StatusByte3 = (uint32)((((uint32)(E2E_ReadReturnVal)) >> 24U) & ((uint32)0x000000FFU)); SysMon_EnumErrorIndicationType retVal = eSysMonErrIndRteTimeout; if (((uint32)RTE_E_OK == StatusByte0) && ((uint32)RTE_E_OK == StatusByte1) && ((uint32)RTE_E_OK == StatusByte2) && (((uint32)RTE_E_OK == StatusByte3) || ((uint32)RTE_E_OK == StatusByte3) || ((uint32)RTE_E_OK == StatusByte3))) { retVal = eSysMonErrNone; //-- success *maxCounter = 0u; } else { if (((uint32)RTE_E_INVALID == StatusByte1) || ((uint32)RTE_E_INVALID == StatusByte1) || ((uint32)RTE_E_INVALID == StatusByte1)) { retVal = eSysMonErrIndRteTimeout; //-- TIMEOUT } if ((uint32)RTE_E_INVALID == StatusByte3) { retVal = eSysMonErrIndRteAliveCounter; //-- ALIVE COUNTER } if ((uint32)RTE_E_INVALID == StatusByte3) //Three consecutive cycles are checked for same sequence counter in E2E_PH.c { if (*maxCounter < 2) { *maxCounter = *maxCounter + 1u; retVal = eSysMonErrNone; } else { //Do Nothing } if (*maxCounter == 2) { retVal = eSysMonErrIndRteAliveCounter; //-- ALIVE COUNTER ERROR FOR CONSECUTIVE 3 TIMES REPEATED DATA } else { //retVal = eSysMonErrNone; } } else { *maxCounter = 0u; //retVal = eSysMonErrNone; } if ((uint32)RTE_E_INVALID == StatusByte3) { retVal = eSysMonErrIndRteCrc; //-- CRC } } #ifdef UNIT_TEST extern val; retVal = change_value(val); //retVal = 0; #endif // UNIT_TEST return retVal; } // -------------- Stop function declarations or definitions. #define ctaaSysMon_STOP_SEC_CODE #include "ctaaSysMon_MemMap.h" //============================================================================= // End declaration or definitions of functions //=============================================================================